diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000000..d7cffbcfb68 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,60 @@ +FROM tgstation/byond:513.1533 as base + +FROM base as rust_g + +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + git \ + ca-certificates + +WORKDIR /rust_g + +RUN apt-get install -y --no-install-recommends \ + libssl-dev \ + pkg-config \ + curl \ + gcc-multilib \ + && curl https://sh.rustup.rs -sSf | sh -s -- -y --default-host i686-unknown-linux-gnu \ + && git init \ + && git remote add origin https://github.com/tgstation/rust-g + +COPY _build_dependencies.sh . + +RUN /bin/bash -c "source _build_dependencies.sh \ + && git fetch --depth 1 origin \$RUST_G_VERSION" \ + && git checkout FETCH_HEAD \ + && ~/.cargo/bin/cargo build --release + +FROM base as dm_base + +WORKDIR /vorestation + +FROM dm_base as build + +COPY . . + +RUN DreamMaker -max_errors 0 vorestation.dme + +FROM dm_base + +EXPOSE 2303 + +RUN apt-get update \ + && apt-get install -y --no-install-recommends software-properties-common \ + && add-apt-repository ppa:ubuntu-toolchain-r/test \ + && apt-get update \ + && apt-get upgrade -y \ + && apt-get dist-upgrade -y \ + && apt-get install -y --no-install-recommends \ + libmariadb2 \ + mariadb-client \ + libssl1.0.0 \ + && rm -rf /var/lib/apt/lists/* \ + && mkdir -p /root/.byond/bin + +COPY --from=rust_g /rust_g/target/release/librust_g.so /root/.byond/bin/rust_g +COPY --from=build /vorestation/ ./ + +#VOLUME [ "/vorestation/config", "/vorestation/data" ] + +ENTRYPOINT [ "DreamDaemon", "vorestation.dmb", "-port", "2303", "-trusted", "-close", "-verbose" ] diff --git a/code/__defines/_lists.dm b/code/__defines/_lists.dm index 016d1a89d4f..247e9dfeb0e 100644 --- a/code/__defines/_lists.dm +++ b/code/__defines/_lists.dm @@ -32,6 +32,12 @@ // Reads the length of L, returning 0 if null #define LAZYLEN(L) length(L) +#define LAZYADDASSOC(L, K, V) if(!L) { L = list(); } L[K] += V; +///This is used to add onto lazy assoc list when the value you're adding is a /list/. This one has extra safety over lazyaddassoc because the value could be null (and thus cant be used to += objects) +#define LAZYADDASSOCLIST(L, K, V) if(!L) { L = list(); } L[K] += list(V); +#define LAZYREMOVEASSOC(L, K, V) if(L) { if(L[K]) { L[K] -= V; if(!length(L[K])) L -= K; } if(!length(L)) L = null; } +#define LAZYACCESSASSOC(L, I, K) L ? L[I] ? L[I][K] ? L[I][K] : null : null : null + // Null-safe L.Cut() #define LAZYCLEARLIST(L) if(L) L.Cut() diff --git a/code/__defines/belly_modes_vr.dm b/code/__defines/belly_modes_vr.dm index d497391d3fc..c716615a7f2 100644 --- a/code/__defines/belly_modes_vr.dm +++ b/code/__defines/belly_modes_vr.dm @@ -20,6 +20,7 @@ #define DM_FLAG_LEAVEREMAINS 0x4 #define DM_FLAG_THICKBELLY 0x8 #define DM_FLAG_AFFECTWORN 0x10 +#define DM_FLAG_JAMSENSORS 0x20 //Item related modes #define IM_HOLD "Hold" diff --git a/code/__defines/chemistry.dm b/code/__defines/chemistry.dm index 0976ed5ea36..f1de2ddd45e 100644 --- a/code/__defines/chemistry.dm +++ b/code/__defines/chemistry.dm @@ -49,3 +49,11 @@ var/list/tachycardics = list("coffee", "inaprovaline", "hyperzine", "nitroglyce var/list/bradycardics = list("neurotoxin", "cryoxadone", "clonexadone", "space_drugs", "stoxin") // Decrease heart rate. var/list/heartstopper = list("potassium_chlorophoride", "zombie_powder") // This stops the heart. var/list/cheartstopper = list("potassium_chloride") // This stops the heart when overdose is met. -- c = conditional + +#define MAX_PILL_SPRITE 24 //max icon state of the pill sprites +#define MAX_BOTTLE_SPRITE 4 //max icon state of the pill sprites +#define MAX_MULTI_AMOUNT 20 // Max number of pills/patches that can be made at once +#define MAX_UNITS_PER_PILL 60 // Max amount of units in a pill +#define MAX_UNITS_PER_PATCH 60 // Max amount of units in a patch +#define MAX_UNITS_PER_BOTTLE 60 // Max amount of units in a bottle (it's volume) +#define MAX_CUSTOM_NAME_LEN 64 // Max length of a custom pill/condiment/whatever \ No newline at end of file diff --git a/code/__defines/crafting.dm b/code/__defines/crafting.dm new file mode 100644 index 00000000000..583c5abe467 --- /dev/null +++ b/code/__defines/crafting.dm @@ -0,0 +1,27 @@ +//tablecrafting defines +#define CAT_NONE "" +#define CAT_WEAPONRY "Weaponry" +#define CAT_WEAPON "Weapons" +#define CAT_AMMO "Ammunition" +#define CAT_ROBOT "Robots" +#define CAT_MISC "Misc" +#define CAT_PRIMAL "Tribal" +#define CAT_CLOTHING "Clothing" +#define CAT_FOOD "Foods" +#define CAT_BREAD "Breads" +#define CAT_BURGER "Burgers" +#define CAT_CAKE "Cakes" +#define CAT_EGG "Egg-Based Food" +#define CAT_MEAT "Meats" +#define CAT_MISCFOOD "Misc. Food" +#define CAT_MEXICAN "Mexican Food" +#define CAT_PASTRY "Pastries" +#define CAT_PIE "Pies" +#define CAT_PIZZA "Pizzas" +#define CAT_SALAD "Salads" +#define CAT_SANDWICH "Sandwiches" +#define CAT_SOUP "Soups" +#define CAT_SPAGHETTI "Spaghettis" +#define CAT_ICE "Frozen" +#define CAT_DRINK "Drinks" +#define CAT_CHEMISTRY "Chemistry" \ No newline at end of file diff --git a/code/__defines/dcs/signals.dm b/code/__defines/dcs/signals.dm index 017c92c9222..c6edaa80e4a 100644 --- a/code/__defines/dcs/signals.dm +++ b/code/__defines/dcs/signals.dm @@ -97,6 +97,10 @@ #define COMSIG_ATOM_FIRE_ACT "atom_fire_act" ///from base of atom/bullet_act(): (/obj/projectile, def_zone) #define COMSIG_ATOM_BULLET_ACT "atom_bullet_act" +///from base of atom/CheckParts(): (list/parts_list, datum/crafting_recipe/R) +#define COMSIG_ATOM_CHECKPARTS "atom_checkparts" +///from base of atom/CheckParts(): (atom/movable/new_craft) - The atom has just been used in a crafting recipe and has been moved inside new_craft. +#define COMSIG_ATOM_USED_IN_CRAFT "atom_used_in_craft" ///from base of atom/blob_act(): (/obj/structure/blob) #define COMSIG_ATOM_BLOB_ACT "atom_blob_act" ///from base of atom/acid_act(): (acidpwr, acid_volume) @@ -732,3 +736,5 @@ ///SSalarm signals #define COMSIG_TRIGGERED_ALARM "ssalarm_triggered" #define COMSIG_CANCELLED_ALARM "ssalarm_cancelled" + +#define COMSIG_REAGENTS_CRAFTING_PING "reagents_crafting_ping" \ No newline at end of file diff --git a/code/__defines/materials.dm b/code/__defines/materials.dm new file mode 100644 index 00000000000..499c974b475 --- /dev/null +++ b/code/__defines/materials.dm @@ -0,0 +1,63 @@ +#define DEFAULT_TABLE_MATERIAL "plastic" +#define DEFAULT_WALL_MATERIAL "steel" + +#define MAT_IRON "iron" +#define MAT_MARBLE "marble" +#define MAT_STEEL "steel" +#define MAT_PLASTIC "plastic" +#define MAT_GLASS "glass" +#define MAT_SILVER "silver" +#define MAT_GOLD "gold" +#define MAT_URANIUM "uranium" +#define MAT_TITANIUM "titanium" +#define MAT_PHORON "phoron" +#define MAT_DIAMOND "diamond" +#define MAT_SNOW "snow" +#define MAT_SNOWBRICK "packed snow" +#define MAT_WOOD "wood" +#define MAT_LOG "log" +#define MAT_SIFWOOD "alien wood" +#define MAT_SIFLOG "alien log" +#define MAT_STEELHULL "steel hull" +#define MAT_PLASTEEL "plasteel" +#define MAT_PLASTEELHULL "plasteel hull" +#define MAT_DURASTEEL "durasteel" +#define MAT_DURASTEELHULL "durasteel hull" +#define MAT_TITANIUMHULL "titanium hull" +#define MAT_VERDANTIUM "verdantium" +#define MAT_MORPHIUM "morphium" +#define MAT_MORPHIUMHULL "morphium hull" +#define MAT_VALHOLLIDE "valhollide" +#define MAT_LEAD "lead" +#define MAT_SUPERMATTER "supermatter" +#define MAT_METALHYDROGEN "mhydrogen" +#define MAT_OSMIUM "osmium" +#define MAT_GRAPHITE "graphite" +#define MAT_LEATHER "leather" +#define MAT_CHITIN "chitin" +#define MAT_CLOTH "cloth" +#define MAT_SYNCLOTH "syncloth" +#define MAT_COPPER "copper" +#define MAT_QUARTZ "quartz" +#define MAT_TIN "tin" +#define MAT_VOPAL "void opal" +#define MAT_ALUMINIUM "aluminium" +#define MAT_BRONZE "bronze" +#define MAT_PAINITE "painite" +#define MAT_BOROSILICATE "borosilicate glass" +#define MAT_SANDSTONE "sandstone" + +#define SHARD_SHARD "shard" +#define SHARD_SHRAPNEL "shrapnel" +#define SHARD_STONE_PIECE "piece" +#define SHARD_SPLINTER "splinters" +#define SHARD_NONE "" + +#define MATERIAL_UNMELTABLE 0x1 +#define MATERIAL_BRITTLE 0x2 +#define MATERIAL_PADDING 0x4 + +#define DEFAULT_TABLE_MATERIAL "plastic" +#define DEFAULT_WALL_MATERIAL "steel" + +#define TABLE_BRITTLE_MATERIAL_MULTIPLIER 4 // Amount table damage is multiplied by if it is made of a brittle material (e.g. glass) diff --git a/code/__defines/misc.dm b/code/__defines/misc.dm index 0a14535c66a..bb0387ab4ee 100644 --- a/code/__defines/misc.dm +++ b/code/__defines/misc.dm @@ -77,7 +77,7 @@ #define DO_AUTOPILOT 5 // Setting this much higher than 1024 could allow spammers to DOS the server easily. -#define MAX_MESSAGE_LEN 2048 //VOREStation Edit - I'm not sure about "easily". It can be a little longer. +#define MAX_MESSAGE_LEN 4096 //VOREStation Edit - I'm not sure about "easily". It can be a little longer. #define MAX_PAPER_MESSAGE_LEN 6144 #define MAX_BOOK_MESSAGE_LEN 24576 #define MAX_RECORD_LENGTH 24576 @@ -121,65 +121,6 @@ #define WALL_CAN_OPEN 1 #define WALL_OPENING 2 -#define DEFAULT_TABLE_MATERIAL "plastic" -#define DEFAULT_WALL_MATERIAL "steel" - -#define MAT_IRON "iron" -#define MAT_MARBLE "marble" -#define MAT_STEEL "steel" -#define MAT_PLASTIC "plastic" -#define MAT_GLASS "glass" -#define MAT_SILVER "silver" -#define MAT_GOLD "gold" -#define MAT_URANIUM "uranium" //Did it -#define MAT_TITANIUM "titanium" -#define MAT_PHORON "phoron" -#define MAT_DIAMOND "diamond" -#define MAT_SNOW "snow" -#define MAT_WOOD "wood" -#define MAT_LOG "log" -#define MAT_SIFWOOD "alien wood" -#define MAT_SIFLOG "alien log" -#define MAT_STEELHULL "steel hull" -#define MAT_PLASTEEL "plasteel" -#define MAT_PLASTEELHULL "plasteel hull" -#define MAT_DURASTEEL "durasteel" -#define MAT_DURASTEELHULL "durasteel hull" -#define MAT_TITANIUMHULL "titanium hull" -#define MAT_VERDANTIUM "verdantium" -#define MAT_MORPHIUM "morphium" -#define MAT_MORPHIUMHULL "morphium hull" -#define MAT_VALHOLLIDE "valhollide" -#define MAT_LEAD "lead" -#define MAT_SUPERMATTER "supermatter" -#define MAT_METALHYDROGEN "mhydrogen" -#define MAT_OSMIUM "osmium" -#define MAT_GRAPHITE "graphite" -#define MAT_LEATHER "leather" -#define MAT_CHITIN "chitin" -#define MAT_CLOTH "cloth" -#define MAT_SYNCLOTH "syncloth" -#define MAT_COPPER "copper" -#define MAT_QUARTZ "quartz" -#define MAT_TIN "tin" -#define MAT_VOPAL "void opal" -#define MAT_ALUMINIUM "aluminium" -#define MAT_BRONZE "bronze" -#define MAT_PAINITE "painite" -#define MAT_BOROSILICATE "borosilicate glass" - -#define SHARD_SHARD "shard" -#define SHARD_SHRAPNEL "shrapnel" -#define SHARD_STONE_PIECE "piece" -#define SHARD_SPLINTER "splinters" -#define SHARD_NONE "" - -#define MATERIAL_UNMELTABLE 0x1 -#define MATERIAL_BRITTLE 0x2 -#define MATERIAL_PADDING 0x4 - -#define TABLE_BRITTLE_MATERIAL_MULTIPLIER 4 // Amount table damage is multiplied by if it is made of a brittle material (e.g. glass) - #define BOMBCAP_DVSTN_RADIUS (max_explosion_range/4) #define BOMBCAP_HEAVY_RADIUS (max_explosion_range/2) #define BOMBCAP_LIGHT_RADIUS max_explosion_range @@ -504,3 +445,7 @@ GLOBAL_LIST_INIT(all_volume_channels, list( #define APPEARANCECHANGER_CHANGED_EYES "Eye Color" #define GET_DECL(D) (ispath(D, /decl) ? (decls_repository.fetched_decls[D] || decls_repository.get_decl(D)) : null) + +#define LOADOUT_WHITELIST_OFF 0 +#define LOADOUT_WHITELIST_LAX 1 +#define LOADOUT_WHITELIST_STRICT 2 \ No newline at end of file diff --git a/code/__defines/mobs.dm b/code/__defines/mobs.dm index 1e2b2e63f30..114979e96be 100644 --- a/code/__defines/mobs.dm +++ b/code/__defines/mobs.dm @@ -272,6 +272,10 @@ #define TASTE_DULL 0.5 //anything below 30% #define TASTE_NUMB 0.1 //anything below 150% +//Used by emotes +#define VISIBLE_MESSAGE 1 +#define AUDIBLE_MESSAGE 2 + // If they're in an FBP, what braintype. #define FBP_NONE "" #define FBP_CYBORG "Cyborg" @@ -433,6 +437,8 @@ #define EXAMINE_SKIPLEGS 0x0080 #define EXAMINE_SKIPFEET 0x0100 -#define MAX_NUTRITION 5000 //VOREStation Edit +#define MAX_NUTRITION 6000 //VOREStation Edit #define FAKE_INVIS_ALPHA_THRESHOLD 127 // If something's alpha var is at or below this number, certain things will pretend it is invisible. + +#define DEATHGASP_NO_MESSAGE "no message" diff --git a/code/__defines/tools.dm b/code/__defines/tools.dm new file mode 100644 index 00000000000..d7b5e1cdba6 --- /dev/null +++ b/code/__defines/tools.dm @@ -0,0 +1,21 @@ +// Tool types, if you add new ones please add them to /obj/item/debug/omnitool in code/game/objects/items/debug_items.dm +#define TOOL_CROWBAR "crowbar" +#define TOOL_MULTITOOL "multitool" +#define TOOL_SCREWDRIVER "screwdriver" +#define TOOL_WIRECUTTER "wirecutter" +#define TOOL_WRENCH "wrench" +#define TOOL_WELDER "welder" +#define TOOL_CABLE_COIL "cablecoil" +#define TOOL_ANALYZER "analyzer" +#define TOOL_MINING "mining" +#define TOOL_SHOVEL "shovel" +#define TOOL_RETRACTOR "retractor" +#define TOOL_HEMOSTAT "hemostat" +#define TOOL_CAUTERY "cautery" +#define TOOL_DRILL "drill" +#define TOOL_SCALPEL "scalpel" +#define TOOL_SAW "saw" +#define TOOL_BONESET "bonesetter" +#define TOOL_KNIFE "knife" +#define TOOL_BLOODFILTER "bloodfilter" +#define TOOL_ROLLINGPIN "rollingpin" \ No newline at end of file diff --git a/code/_global_vars/lists/misc.dm b/code/_global_vars/lists/misc.dm index 742708face2..ee320056bec 100644 --- a/code/_global_vars/lists/misc.dm +++ b/code/_global_vars/lists/misc.dm @@ -8,4 +8,5 @@ GLOBAL_LIST_EMPTY(wire_color_directory) // This is an associative list with the GLOBAL_LIST_EMPTY(tagger_locations) GLOBAL_LIST_INIT(char_directory_tags, list("Pred", "Prey", "Switch", "Non-Vore", "Unset")) -GLOBAL_LIST_INIT(char_directory_erptags, list("Top", "Bottom", "Switch", "No ERP", "Unset")) \ No newline at end of file +GLOBAL_LIST_INIT(char_directory_erptags, list("Top", "Bottom", "Switch", "No ERP", "Unset")) +GLOBAL_LIST_EMPTY(crafting_recipes) //list of all table craft recipes diff --git a/code/_helpers/_lists.dm b/code/_helpers/_lists.dm index 124f69f45e3..abe05b5141f 100644 --- a/code/_helpers/_lists.dm +++ b/code/_helpers/_lists.dm @@ -416,13 +416,9 @@ This actually tests if they have the same entries and values. - -//Mergesort: any value in a list -/proc/sortList(var/list/L) - if(L.len < 2) - return L - var/middle = L.len / 2 + 1 // Copy is first,second-1 - return mergeLists(sortList(L.Copy(0,middle)), sortList(L.Copy(middle))) //second parameter null = to end of list +//any value in a list +/proc/sortList(list/L, cmp=/proc/cmp_text_asc) + return sortTim(L.Copy(), cmp) //Mergsorge: uses sortList() but uses the var's name specifically. This should probably be using mergeAtom() instead /proc/sortNames(var/list/L) diff --git a/code/_helpers/global_lists.dm b/code/_helpers/global_lists.dm index 1c0d5f23932..868f69fde82 100644 --- a/code/_helpers/global_lists.dm +++ b/code/_helpers/global_lists.dm @@ -242,6 +242,7 @@ GLOBAL_LIST_EMPTY(mannequins) var/datum/digest_mode/DM = new T GLOB.digest_modes[DM.id] = DM // VOREStation Add End + init_crafting_recipes(GLOB.crafting_recipes) /* // Custom species traits @@ -278,8 +279,13 @@ GLOBAL_LIST_EMPTY(mannequins) return 1 // Hooks must return 1 - return 1 - +/// Inits the crafting recipe list, sorting crafting recipe requirements in the process. +/proc/init_crafting_recipes(list/crafting_recipes) + for(var/path in subtypesof(/datum/crafting_recipe)) + var/datum/crafting_recipe/recipe = new path() + recipe.reqs = sortList(recipe.reqs, /proc/cmp_crafting_req_priority) + crafting_recipes += recipe + return crafting_recipes /* // Uncomment to debug chemical reaction list. /client/verb/debug_chemical_list() diff --git a/code/_helpers/global_lists_vr.dm b/code/_helpers/global_lists_vr.dm index 057c96e2044..6c1fd9d261e 100644 --- a/code/_helpers/global_lists_vr.dm +++ b/code/_helpers/global_lists_vr.dm @@ -485,7 +485,7 @@ var/global/list/remainless_species = list(SPECIES_PROMETHEAN, hair_accesories_list[path] = instance // Custom species traits - paths = typesof(/datum/trait) - /datum/trait + paths = typesof(/datum/trait) - /datum/trait - /datum/trait/negative - /datum/trait/neutral - /datum/trait/positive for(var/path in paths) var/datum/trait/instance = new path() if(!instance.name) diff --git a/code/_helpers/sorts/comparators.dm b/code/_helpers/sorts/comparators.dm index 704042531a2..c192d19008c 100644 --- a/code/_helpers/sorts/comparators.dm +++ b/code/_helpers/sorts/comparators.dm @@ -64,4 +64,23 @@ return b_score - a_score /proc/cmp_typepaths_asc(A, B) - return sorttext("[B]","[A]") \ No newline at end of file + return sorttext("[B]","[A]") + +/** + * Sorts crafting recipe requirements before the crafting recipe is inserted into GLOB.crafting_recipes + * + * Prioritises [/datum/reagent] to ensure reagent requirements are always processed first when crafting. + * This prevents any reagent_containers from being consumed before the reagents they contain, which can + * lead to runtimes and item duplication when it happens. + */ +/proc/cmp_crafting_req_priority(A, B) + var/lhs + var/rhs + + lhs = ispath(A, /datum/reagent) ? 0 : 1 + rhs = ispath(B, /datum/reagent) ? 0 : 1 + + return lhs - rhs + +/proc/cmp_text_asc(a,b) + return sorttext(b,a) diff --git a/code/_helpers/string_lists.dm b/code/_helpers/string_lists.dm new file mode 100644 index 00000000000..6e2dc2c3180 --- /dev/null +++ b/code/_helpers/string_lists.dm @@ -0,0 +1,14 @@ +GLOBAL_LIST_EMPTY(string_lists) + +/** + * Caches lists with non-numeric stringify-able values (text or typepath). + */ +/proc/string_list(list/values) + var/string_id = values.Join("-") + + . = GLOB.string_lists[string_id] + + if(.) + return + + return GLOB.string_lists[string_id] = values \ No newline at end of file diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index 0cdda2e9939..076a0d740c2 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -18,6 +18,7 @@ /atom/Click(var/location, var/control, var/params) // This is their reaction to being clicked on (standard proc) if(src) + SEND_SIGNAL(src, COMSIG_CLICK, location, control, params, usr) usr.ClickOn(src, params) /atom/DblClick(var/location, var/control, var/params) diff --git a/code/_onclick/hud/_defines.dm b/code/_onclick/hud/_defines.dm index 247d1d3f8bf..df78fd5df8f 100644 --- a/code/_onclick/hud/_defines.dm +++ b/code/_onclick/hud/_defines.dm @@ -187,3 +187,5 @@ #define ui_mech_airtoggle "WEST+1:-7, SOUTH+8" #define ui_mech_deco1_f "WEST+2:-7, SOUTH+8" #define ui_mech_deco2_f "WEST+2:-7, SOUTH+9" + +#define ui_crafting "EAST-4:22,SOUTH:5" \ No newline at end of file diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index 5e5f044ac24..d53c44e0f3e 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -246,6 +246,7 @@ add_overlay(selecting_appearance) /obj/screen/Click(location, control, params) + ..() // why the FUCK was this not called before if(!usr) return 1 switch(name) if("toggle") diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index 67d14623cf6..1f82939221a 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -284,7 +284,10 @@ var/list/gamemode_cache = list() var/static/disable_cid_warn_popup = FALSE // whether or not to use the nightshift subsystem to perform lighting changes - var/static/enable_night_shifts = FALSE + var/static/enable_night_shifts = FALSE + + // How strictly the loadout enforces object species whitelists + var/loadout_whitelist = LOADOUT_WHITELIST_LAX var/static/vgs_access_identifier = null // VOREStation Edit - VGS var/static/vgs_server_port = null // VOREStation Edit - VGS diff --git a/code/controllers/subsystems/chemistry.dm b/code/controllers/subsystems/chemistry.dm new file mode 100644 index 00000000000..148e9755421 --- /dev/null +++ b/code/controllers/subsystems/chemistry.dm @@ -0,0 +1,58 @@ +SUBSYSTEM_DEF(chemistry) + name = "Chemistry" + wait = 20 + flags = SS_NO_FIRE + init_order = INIT_ORDER_CHEMISTRY + + var/list/chemical_reactions = list() + var/list/instant_reactions_by_reagent = list() + var/list/distilled_reactions_by_reagent = list() +// var/list/fusion_reactions_by_reagent = list() // TODO: Fusion reactions as chemical reactions + var/list/chemical_reagents = list() + +/datum/controller/subsystem/chemistry/Recover() + log_debug("[name] subsystem Recover().") + chemical_reactions = SSchemistry.chemical_reactions + chemical_reagents = SSchemistry.chemical_reagents + +/datum/controller/subsystem/chemistry/Initialize() + initialize_chemical_reagents() + initialize_chemical_reactions() + ..() + +/datum/controller/subsystem/chemistry/stat_entry() + ..("C: [chemical_reagents.len] | R: [chemical_reactions.len]") + +//Chemical Reactions - Initialises all /decl/chemical_reaction into a list +// It is filtered into multiple lists within a list. +// For example: +// chemical_reactions_by_reagent["phoron"] is a list of all reactions relating to phoron +// Note that entries in the list are NOT duplicated. So if a reaction pertains to +// more than one chemical it will still only appear in only one of the sublists. +/datum/controller/subsystem/chemistry/proc/initialize_chemical_reactions() + var/list/paths = decls_repository.get_decls_of_subtype(/decl/chemical_reaction) + + for(var/path in paths) + var/decl/chemical_reaction/D = paths[path] + chemical_reactions += D + if(D.required_reagents && D.required_reagents.len) + var/reagent_id = D.required_reagents[1] + + var/list/add_to = instant_reactions_by_reagent // Default to instant reactions list, if something's gone wrong +// if(istype(D, /decl/chemical_reaction/fusion)) // TODO: fusion reactions as chemical reactions +// add_to = fusion_reactions_by_reagent + if(istype(D, /decl/chemical_reaction/distilling)) + add_to = distilled_reactions_by_reagent + + LAZYINITLIST(add_to[reagent_id]) + add_to[reagent_id] += D + +//Chemical Reagents - Initialises all /datum/reagent into a list indexed by reagent id +/datum/controller/subsystem/chemistry/proc/initialize_chemical_reagents() + var/paths = subtypesof(/datum/reagent) + chemical_reagents = list() + for(var/path in paths) + var/datum/reagent/D = new path() + if(!D.name) + continue + chemical_reagents[D.id] = D diff --git a/code/controllers/subsystems/processing/chemistry.dm b/code/controllers/subsystems/processing/chemistry.dm deleted file mode 100644 index b4641ba7e00..00000000000 --- a/code/controllers/subsystems/processing/chemistry.dm +++ /dev/null @@ -1,54 +0,0 @@ -PROCESSING_SUBSYSTEM_DEF(chemistry) - name = "Chemistry" - wait = 20 - flags = SS_BACKGROUND|SS_POST_FIRE_TIMING - init_order = INIT_ORDER_CHEMISTRY - var/list/chemical_reactions = list() - var/list/chemical_reactions_by_reagent = list() - var/list/chemical_reagents = list() - -/datum/controller/subsystem/processing/chemistry/Recover() - log_debug("[name] subsystem Recover().") - if(SSchemistry.current_thing) - log_debug("current_thing was: (\ref[SSchemistry.current_thing])[SSchemistry.current_thing]([SSchemistry.current_thing.type]) - currentrun: [SSchemistry.currentrun.len] vs total: [SSchemistry.processing.len]") - var/list/old_processing = SSchemistry.processing.Copy() - for(var/datum/D in old_processing) - if(CHECK_BITFIELD(D.datum_flags, DF_ISPROCESSING)) - processing |= D - - chemical_reactions = SSchemistry.chemical_reactions - chemical_reagents = SSchemistry.chemical_reagents - -/datum/controller/subsystem/processing/chemistry/Initialize() - initialize_chemical_reactions() - initialize_chemical_reagents() - ..() - -//Chemical Reactions - Initialises all /datum/chemical_reaction into a list -// It is filtered into multiple lists within a list. -// For example: -// chemical_reaction_list["phoron"] is a list of all reactions relating to phoron -// Note that entries in the list are NOT duplicated. So if a reaction pertains to -// more than one chemical it will still only appear in only one of the sublists. -/datum/controller/subsystem/processing/chemistry/proc/initialize_chemical_reactions() - var/paths = typesof(/datum/chemical_reaction) - /datum/chemical_reaction - chemical_reactions = list() - chemical_reactions_by_reagent = list() - - for(var/path in paths) - var/datum/chemical_reaction/D = new path - chemical_reactions += D - if(D.required_reagents && D.required_reagents.len) - var/reagent_id = D.required_reagents[1] - LAZYINITLIST(chemical_reactions_by_reagent[reagent_id]) - chemical_reactions_by_reagent[reagent_id] += D - -//Chemical Reagents - Initialises all /datum/reagent into a list indexed by reagent id -/datum/controller/subsystem/processing/chemistry/proc/initialize_chemical_reagents() - var/paths = typesof(/datum/reagent) - /datum/reagent - chemical_reagents = list() - for(var/path in paths) - var/datum/reagent/D = new path() - if(!D.name) - continue - chemical_reagents[D.id] = D diff --git a/code/controllers/subsystems/ticker.dm b/code/controllers/subsystems/ticker.dm index d499f03d4d6..47f35a27a82 100644 --- a/code/controllers/subsystems/ticker.dm +++ b/code/controllers/subsystems/ticker.dm @@ -462,15 +462,15 @@ var/global/datum/controller/subsystem/ticker/ticker for (var/mob/living/silicon/ai/aiPlayer in mob_list) if (aiPlayer.stat != 2) - to_world("[aiPlayer.name] (Played by: [aiPlayer.key])'s laws at the end of the round were:") + to_world("[aiPlayer.name]'s laws at the end of the round were:") // VOREStation edit else - to_world("[aiPlayer.name] (Played by: [aiPlayer.key])'s laws when it was deactivated were:") + to_world("[aiPlayer.name]'s laws when it was deactivated were:") // VOREStation edit aiPlayer.show_laws(1) if (aiPlayer.connected_robots.len) var/robolist = "The AI's loyal minions were: " for(var/mob/living/silicon/robot/robo in aiPlayer.connected_robots) - robolist += "[robo.name][robo.stat?" (Deactivated) (Played by: [robo.key]), ":" (Played by: [robo.key]), "]" + robolist += "[robo.name][robo.stat?" (Deactivated), ":", "]" // VOREStation edit to_world("[robolist]") var/dronecount = 0 @@ -488,9 +488,9 @@ var/global/datum/controller/subsystem/ticker/ticker if (!robo.connected_ai) if (robo.stat != 2) - to_world("[robo.name] (Played by: [robo.key]) survived as an AI-less stationbound synthetic! Its laws were:") + to_world("[robo.name] survived as an AI-less stationbound synthetic! Its laws were:") // VOREStation edit else - to_world("[robo.name] (Played by: [robo.key]) was unable to survive the rigors of being a stationbound synthetic without an AI. Its laws were:") + to_world("[robo.name] was unable to survive the rigors of being a stationbound synthetic without an AI. Its laws were:") // VOREStation edit if(robo) //How the hell do we lose robo between here and the world messages directly above this? robo.laws.show_laws(world) diff --git a/code/datums/components/crafting/crafting.dm b/code/datums/components/crafting/crafting.dm new file mode 100644 index 00000000000..4ff5dadb7c0 --- /dev/null +++ b/code/datums/components/crafting/crafting.dm @@ -0,0 +1,507 @@ +/datum/component/personal_crafting/Initialize() + if(ismob(parent)) + RegisterSignal(parent, COMSIG_MOB_CLIENT_LOGIN, .proc/create_mob_button) + +/datum/component/personal_crafting/proc/create_mob_button(mob/user, client/CL) + // SIGNAL_HANDLER + + var/datum/hud/H = user.hud_used + var/obj/screen/craft/C = new() + C.icon = H.ui_style + H.other += C + CL.screen += C + RegisterSignal(C, COMSIG_CLICK, .proc/component_ui_interact) + +/datum/component/personal_crafting + var/busy + var/viewing_category = 1 //typical powergamer starting on the Weapons tab + var/viewing_subcategory = 1 + var/list/categories = list( + CAT_WEAPONRY = list( + CAT_WEAPON, + CAT_AMMO, + ), + CAT_ROBOT = CAT_NONE, + CAT_MISC = CAT_NONE, + CAT_PRIMAL = CAT_NONE, + CAT_FOOD = list( + CAT_BREAD, + CAT_BURGER, + CAT_CAKE, + CAT_EGG, + CAT_ICE, + CAT_MEAT, + CAT_MISCFOOD, + CAT_PASTRY, + CAT_PIE, + CAT_PIZZA, + CAT_SALAD, + CAT_SANDWICH, + CAT_SOUP, + CAT_SPAGHETTI, + ), + CAT_DRINK = CAT_NONE, + CAT_CLOTHING = CAT_NONE, + ) + + var/cur_category = CAT_NONE + var/cur_subcategory = CAT_NONE + var/datum/action/innate/crafting/button + var/display_craftable_only = FALSE + var/display_compact = TRUE + +/* This is what procs do: + get_environment - gets a list of things accessable for crafting by user + get_surroundings - takes a list of things and makes a list of key-types to values-amounts of said type in the list + check_contents - takes a recipe and a key-type list and checks if said recipe can be done with available stuff + check_tools - takes recipe, a key-type list, and a user and checks if there are enough tools to do the stuff, checks bugs one level deep + construct_item - takes a recipe and a user, call all the checking procs, calls do_after, checks all the things again, calls del_reqs, creates result, calls CheckParts of said result with argument being list returned by deel_reqs + del_reqs - takes recipe and a user, loops over the recipes reqs var and tries to find everything in the list make by get_environment and delete it/add to parts list, then returns the said list +*/ + +/** + * Check that the contents of the recipe meet the requirements. + * + * user: The /mob that initated the crafting. + * R: The /datum/crafting_recipe being attempted. + * contents: List of items to search for R's reqs. + */ +/datum/component/personal_crafting/proc/check_contents(atom/a, datum/crafting_recipe/R, list/contents) + var/list/item_instances = contents["instances"] + var/list/machines = contents["machinery"] + contents = contents["other"] + + + var/list/requirements_list = list() + + // Process all requirements + for(var/requirement_path in R.reqs) + // Check we have the appropriate amount available in the contents list + var/needed_amount = R.reqs[requirement_path] + for(var/content_item_path in contents) + // Right path and not blacklisted + if(!ispath(content_item_path, requirement_path) || R.blacklist.Find(content_item_path)) + continue + + needed_amount -= contents[content_item_path] + if(needed_amount <= 0) + break + + if(needed_amount > 0) + return FALSE + + // Store the instances of what we will use for R.check_requirements() for requirement_path + var/list/instances_list = list() + for(var/instance_path in item_instances) + if(ispath(instance_path, requirement_path)) + instances_list += item_instances[instance_path] + + requirements_list[requirement_path] = instances_list + + for(var/requirement_path in R.chem_catalysts) + if(contents[requirement_path] < R.chem_catalysts[requirement_path]) + return FALSE + + for(var/machinery_path in R.machinery) + if(!machines[machinery_path])//We don't care for volume with machines, just if one is there or not + return FALSE + + return R.check_requirements(a, requirements_list) + +/datum/component/personal_crafting/proc/get_environment(atom/a, list/blacklist = null, radius_range = 1) + . = list() + + if(!isturf(a.loc)) + return + + for(var/atom/movable/AM in range(radius_range, a)) + if(/*(AM.flags_1 & HOLOGRAM_1) ||*/ (blacklist && (AM.type in blacklist))) + continue + . += AM + + +/datum/component/personal_crafting/proc/get_surroundings(atom/a, list/blacklist=null) + . = list() + .["tool_qualities"] = list() + .["other"] = list() + .["instances"] = list() + .["machinery"] = list() + for(var/obj/object in get_environment(a, blacklist)) + if(isitem(object)) + var/obj/item/item = object + LAZYADDASSOCLIST(.["instances"], item.type, item) + if(istype(item, /obj/item/stack)) + var/obj/item/stack/stack = item + .["other"][item.type] += stack.amount + else if(item.tool_qualities) + .["tool_qualities"] |= item.tool_qualities + .["other"][item.type] += 1 + else + if(istype(item, /obj/item/weapon/reagent_containers)) + var/obj/item/weapon/reagent_containers/container = item + // if(container.is_drainable()) + if(container.is_open_container()) // this isn't exactly the same + for(var/datum/reagent/reagent in container.reagents.reagent_list) + .["other"][reagent.type] += reagent.volume + .["other"][item.type] += 1 + else if (istype(object, /obj/machinery)) + LAZYADDASSOCLIST(.["machinery"], object.type, object) + + + +/// Returns a boolean on whether the tool requirements of the input recipe are satisfied by the input source and surroundings. +/datum/component/personal_crafting/proc/check_tools(atom/source, datum/crafting_recipe/recipe, list/surroundings) + if(!length(recipe.tool_behaviors) && !length(recipe.tool_paths)) + return TRUE + var/list/available_tools = list() + var/list/present_qualities = list() + + for(var/obj/item/contained_item in source.contents) + // if(contained_item.GetComponent(/datum/component/storage)) + if(istype(contained_item, /obj/item/weapon/storage)) // cursed + for(var/obj/item/subcontained_item in contained_item.contents) + available_tools[subcontained_item.type] = TRUE + for(var/behavior in subcontained_item.tool_qualities) + present_qualities[behavior] = TRUE + available_tools[contained_item.type] = TRUE + for(var/behavior in contained_item.tool_qualities) + present_qualities[behavior] = TRUE + + for(var/quality in surroundings["tool_behaviour"]) + present_qualities[quality] = TRUE + + for(var/path in surroundings["other"]) + available_tools[path] = TRUE + + for(var/required_quality in recipe.tool_behaviors) + if(present_qualities[required_quality]) + continue + return FALSE + + for(var/required_path in recipe.tool_paths) + var/found_this_tool = FALSE + for(var/tool_path in available_tools) + if(!ispath(required_path, tool_path)) + continue + found_this_tool = TRUE + break + if(found_this_tool) + continue + return FALSE + + return TRUE + + +/datum/component/personal_crafting/proc/construct_item(atom/a, datum/crafting_recipe/R) + var/list/contents = get_surroundings(a,R.blacklist) + // var/send_feedback = 1 + if(check_contents(a, R, contents)) + if(check_tools(a, R, contents)) + if(R.one_per_turf) + for(var/content in get_turf(a)) + if(istype(content, R.result)) + return ", object already present." + //If we're a mob we'll try a do_after; non mobs will instead instantly construct the item + if(ismob(a) && !do_after(a, R.time, target = a)) + return "." + contents = get_surroundings(a,R.blacklist) + if(!check_contents(a, R, contents)) + return ", missing component." + if(!check_tools(a, R, contents)) + return ", missing tool." + var/list/parts = del_reqs(R, a) + var/atom/movable/I = new R.result (get_turf(a.loc)) + I.CheckParts(parts, R) + // if(send_feedback) + // SSblackbox.record_feedback("tally", "object_crafted", 1, I.type) + return I //Send the item back to whatever called this proc so it can handle whatever it wants to do with the new item + return ", missing tool." + return ", missing component." + +/*Del reqs works like this: + + Loop over reqs var of the recipe + Set var amt to the value current cycle req is pointing to, its amount of type we need to delete + Get var/surroundings list of things accessable to crafting by get_environment() + Check the type of the current cycle req + If its reagent then do a while loop, inside it try to locate() reagent containers, inside such containers try to locate needed reagent, if there isn't remove thing from surroundings + If there is enough reagent in the search result then delete the needed amount, create the same type of reagent with the same data var and put it into deletion list + If there isn't enough take all of that reagent from the container, put into deletion list, substract the amt var by the volume of reagent, remove the container from surroundings list and keep searching + While doing above stuff check deletion list if it already has such reagnet, if yes merge instead of adding second one + If its stack check if it has enough amount + If yes create new stack with the needed amount and put in into deletion list, substract taken amount from the stack + If no put all of the stack in the deletion list, substract its amount from amt and keep searching + While doing above stuff check deletion list if it already has such stack type, if yes try to merge them instead of adding new one + If its anything else just locate() in in the list in a while loop, each find --s the amt var and puts the found stuff in deletion loop + + Then do a loop over parts var of the recipe + Do similar stuff to what we have done above, but now in deletion list, until the parts conditions are satisfied keep taking from the deletion list and putting it into parts list for return + + After its done loop over deletion list and delete all the shit that wasn't taken by parts loop + + del_reqs return the list of parts resulting object will receive as argument of CheckParts proc, on the atom level it will add them all to the contents, on all other levels it calls ..() and does whatever is needed afterwards but from contents list already +*/ + +/datum/component/personal_crafting/proc/del_reqs(datum/crafting_recipe/R, atom/a) + var/list/surroundings + var/list/Deletion = list() + . = list() + var/data + var/amt + var/list/requirements = list() + if(R.reqs) + requirements += R.reqs + if(R.machinery) + requirements += R.machinery + main_loop: + for(var/path_key in requirements) + amt = R.reqs[path_key] || R.machinery[path_key] + if(!amt)//since machinery can have 0 aka CRAFTING_MACHINERY_USE - i.e. use it, don't consume it! + continue main_loop + surroundings = get_environment(a, R.blacklist) + surroundings -= Deletion + if(ispath(path_key, /datum/reagent)) + var/datum/reagent/RG = new path_key + var/datum/reagent/RGNT + while(amt > 0) + var/obj/item/weapon/reagent_containers/RC = locate() in surroundings + RG = RC.reagents.get_reagent(path_key) + if(RG) + if(!locate(RG.type) in Deletion) + Deletion += new RG.type() + if(RG.volume > amt) + RG.volume -= amt + data = RG.data + RC.reagents.conditional_update(RC) + RG = locate(RG.type) in Deletion + RG.volume = amt + RG.data += data + continue main_loop + else + surroundings -= RC + amt -= RG.volume + RC.reagents.reagent_list -= RG + RC.reagents.conditional_update(RC) + RGNT = locate(RG.type) in Deletion + RGNT.volume += RG.volume + RGNT.data += RG.data + qdel(RG) + SEND_SIGNAL(RC.reagents, COMSIG_REAGENTS_CRAFTING_PING) // - [] TODO: Make this entire thing less spaghetti + else + surroundings -= RC + else if(ispath(path_key, /obj/item/stack)) + var/obj/item/stack/S + var/obj/item/stack/SD + while(amt > 0) + S = locate(path_key) in surroundings + if(S.amount >= amt) + if(!locate(S.type) in Deletion) + SD = new S.type() + Deletion += SD + S.use(amt) + SD = locate(S.type) in Deletion + SD.amount += amt + continue main_loop + else + amt -= S.amount + if(!locate(S.type) in Deletion) + Deletion += S + else + data = S.amount + S = locate(S.type) in Deletion + S.add(data) + surroundings -= S + else + var/atom/movable/I + while(amt > 0) + I = locate(path_key) in surroundings + Deletion += I + surroundings -= I + amt-- + var/list/partlist = list(R.parts.len) + for(var/M in R.parts) + partlist[M] = R.parts[M] + for(var/part in R.parts) + if(istype(part, /datum/reagent)) + var/datum/reagent/RG = locate(part) in Deletion + if(RG.volume > partlist[part]) + RG.volume = partlist[part] + . += RG + Deletion -= RG + continue + else if(istype(part, /obj/item/stack)) + var/obj/item/stack/ST = locate(part) in Deletion + if(ST.amount > partlist[part]) + ST.amount = partlist[part] + . += ST + Deletion -= ST + continue + else + while(partlist[part] > 0) + var/atom/movable/AM = locate(part) in Deletion + . += AM + Deletion -= AM + partlist[part] -= 1 + while(Deletion.len) + var/DL = Deletion[Deletion.len] + Deletion.Cut(Deletion.len) + // Snowflake handling of reagent containers and storage atoms. + // If we consumed them in our crafting, we should dump their contents out before qdeling them. + if(istype(DL, /obj/item/weapon/reagent_containers)) + var/obj/item/weapon/reagent_containers/container = DL + container.reagents.clear_reagents() + // container.reagents.expose(container.loc, TOUCH) + else if(istype(DL, /obj/item/weapon/storage)) + var/obj/item/weapon/storage/container = DL + container.spill() + container.close_all() + qdel(DL) + +/datum/component/personal_crafting/proc/component_ui_interact(atom/movable/screen/craft/image, location, control, params, user) + // SIGNAL_HANDLER + + if(user == parent) + INVOKE_ASYNC(src, .proc/tgui_interact, user) + +/datum/component/personal_crafting/tgui_state(mob/user) + return GLOB.tgui_not_incapacitated_turf_state + +//For the UI related things we're going to assume the user is a mob rather than typesetting it to an atom as the UI isn't generated if the parent is an atom +/datum/component/personal_crafting/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + cur_category = categories[1] + if(islist(categories[cur_category])) + var/list/subcats = categories[cur_category] + cur_subcategory = subcats[1] + else + cur_subcategory = CAT_NONE + ui = new(user, src, "PersonalCrafting") + ui.open() + +/datum/component/personal_crafting/tgui_data(mob/user) + var/list/data = list() + data["busy"] = busy + data["category"] = cur_category + data["subcategory"] = cur_subcategory + data["display_craftable_only"] = display_craftable_only + data["display_compact"] = display_compact + + var/list/surroundings = get_surroundings(user) + var/list/craftability = list() + for(var/rec in GLOB.crafting_recipes) + var/datum/crafting_recipe/R = rec + + if(!R.always_available && !(R.type in user?.mind?.learned_recipes)) //User doesn't actually know how to make this. + continue + + if((R.category != cur_category) || (R.subcategory != cur_subcategory)) + continue + + craftability["[REF(R)]"] = check_contents(user, R, surroundings) + + data["craftability"] = craftability + return data + +/datum/component/personal_crafting/tgui_static_data(mob/user) + var/list/data = list() + + var/list/crafting_recipes = list() + for(var/rec in GLOB.crafting_recipes) + var/datum/crafting_recipe/R = rec + + if(R.name == "") //This is one of the invalid parents that sneaks in + continue + + if(!R.always_available && !(R.type in user?.mind?.learned_recipes)) //User doesn't actually know how to make this. + continue + + if(isnull(crafting_recipes[R.category])) + crafting_recipes[R.category] = list() + + if(R.subcategory == CAT_NONE) + crafting_recipes[R.category] += list(build_recipe_data(R)) + else + if(isnull(crafting_recipes[R.category][R.subcategory])) + crafting_recipes[R.category][R.subcategory] = list() + crafting_recipes[R.category]["has_subcats"] = TRUE + crafting_recipes[R.category][R.subcategory] += list(build_recipe_data(R)) + + data["crafting_recipes"] = crafting_recipes + return data + +/datum/component/personal_crafting/tgui_act(action, params) + . = ..() + if(.) + return + switch(action) + if("make") + var/mob/user = usr + var/datum/crafting_recipe/TR = locate(params["recipe"]) in GLOB.crafting_recipes + busy = TRUE + tgui_interact(user) + var/atom/movable/result = construct_item(user, TR) + if(!istext(result)) //We made an item and didn't get a fail message + if(ismob(user) && isitem(result)) //In case the user is actually possessing a non mob like a machine + user.put_in_hands(result) + else + result.forceMove(user.drop_location()) + to_chat(user, "[TR.name] constructed.") + TR.on_craft_completion(user, result) + else + to_chat(user, "Construction failed[result]") + busy = FALSE + if("toggle_recipes") + display_craftable_only = !display_craftable_only + . = TRUE + if("toggle_compact") + display_compact = !display_compact + . = TRUE + if("set_category") + cur_category = params["category"] + cur_subcategory = params["subcategory"] || "" + . = TRUE + +/datum/component/personal_crafting/proc/build_recipe_data(datum/crafting_recipe/R) + var/list/data = list() + data["name"] = R.name + data["ref"] = "[REF(R)]" + var/list/req_text = list() + var/list/tool_list = list() + var/list/catalyst_text = list() + + for(var/atom/req_atom as anything in R.reqs) + //We just need the name, so cheat-typecast to /atom for speed (even tho Reagents are /datum they DO have a "name" var) + //Also these are typepaths so sadly we can't just do "[a]" + req_text += "[R.reqs[req_atom]] [initial(req_atom.name)]" + for(var/obj/machinery/content as anything in R.machinery) + req_text += "[R.reqs[content]] [initial(content.name)]" + if(R.additional_req_text) + req_text += R.additional_req_text + data["req_text"] = req_text.Join(", ") + + for(var/atom/req_catalyst as anything in R.chem_catalysts) + catalyst_text += "[R.chem_catalysts[req_catalyst]] [initial(req_catalyst.name)]" + data["catalyst_text"] = catalyst_text.Join(", ") + + for(var/required_quality in R.tool_behaviors) + tool_list += required_quality + for(var/obj/item/required_path as anything in R.tool_paths) + tool_list += initial(required_path.name) + data["tool_text"] = tool_list.Join(", ") + + return data + +//Mind helpers + +/datum/mind/proc/teach_crafting_recipe(R) + if(!learned_recipes) + learned_recipes = list() + learned_recipes |= R + +// Screen objects +/obj/screen/craft + name = "crafting menu" + icon = 'icons/mob/screen/midnight.dmi' + icon_state = "craft" + screen_loc = ui_crafting \ No newline at end of file diff --git a/code/datums/components/crafting/crafting_external.dm b/code/datums/components/crafting/crafting_external.dm new file mode 100644 index 00000000000..e40d5011329 --- /dev/null +++ b/code/datums/components/crafting/crafting_external.dm @@ -0,0 +1,34 @@ +/** + * Ensure a list of atoms/reagents exists inside this atom + * + * Goes throught he list of passed in parts, if they're reagents, adds them to our reagent holder + * creating the reagent holder if it exists. + * + * If the part is a moveable atom and the previous location of the item was a mob/living, + * it calls the inventory handler transferItemToLoc for that mob/living and transfers the part + * to this atom + * + * Otherwise it simply forceMoves the atom into this atom + */ +/atom/proc/CheckParts(list/parts_list, datum/crafting_recipe/R) + SEND_SIGNAL(src, COMSIG_ATOM_CHECKPARTS, parts_list, R) + if(parts_list) + for(var/A in parts_list) + if(istype(A, /datum/reagent)) + if(!reagents) + reagents = new() + reagents.reagent_list.Add(A) + reagents.conditional_update() + else if(ismovable(A)) + var/atom/movable/M = A + if(isliving(M.loc)) + var/mob/living/L = M.loc + L.unEquip(M, target = src) + else + M.forceMove(src) + SEND_SIGNAL(M, COMSIG_ATOM_USED_IN_CRAFT, src) + parts_list.Cut() + +/obj/machinery/CheckParts(list/parts_list) + ..() + RefreshParts() \ No newline at end of file diff --git a/code/datums/components/crafting/recipes.dm b/code/datums/components/crafting/recipes.dm new file mode 100644 index 00000000000..5d4cd12c613 --- /dev/null +++ b/code/datums/components/crafting/recipes.dm @@ -0,0 +1,56 @@ +///If the machine is used/deleted in the crafting process +#define CRAFTING_MACHINERY_CONSUME 1 +///If the machine is only "used" i.e. it checks to see if it's nearby and allows crafting, but doesn't delete it +#define CRAFTING_MACHINERY_USE 0 + +/datum/crafting_recipe + var/name = "" //in-game display name + var/list/reqs = list() //type paths of items consumed associated with how many are needed + var/list/blacklist = list() //type paths of items explicitly not allowed as an ingredient + var/result //type path of item resulting from this craft + /// String defines of items needed but not consumed. Lazy list. + var/list/tool_behaviors + /// Type paths of items needed but not consumed. Lazy list. + var/list/tool_paths + var/time = 30 //time in deciseconds + var/list/parts = list() //type paths of items that will be placed in the result + var/list/chem_catalysts = list() //like tool_behaviors but for reagents + var/category = CAT_NONE //where it shows up in the crafting UI + var/subcategory = CAT_NONE + var/always_available = TRUE //Set to FALSE if it needs to be learned first. + /// Additonal requirements text shown in UI + var/additional_req_text + ///Required machines for the craft, set the assigned value of the typepath to CRAFTING_MACHINERY_CONSUME or CRAFTING_MACHINERY_USE. Lazy associative list: type_path key -> flag value. + var/list/machinery + ///Should only one object exist on the same turf? + var/one_per_turf = FALSE + +/datum/crafting_recipe/New() + if(!(result in reqs)) + blacklist += result + if(tool_behaviors) + tool_behaviors = string_list(tool_behaviors) + if(tool_paths) + tool_paths = string_list(tool_paths) + +/** + * Run custom pre-craft checks for this recipe + * + * user: The /mob that initiated the crafting + * collected_requirements: A list of lists of /obj/item instances that satisfy reqs. Top level list is keyed by requirement path. + */ +/datum/crafting_recipe/proc/check_requirements(mob/user, list/collected_requirements) + return TRUE + +/datum/crafting_recipe/proc/on_craft_completion(mob/user, atom/result) + return + +/datum/crafting_recipe/stunprod + name = "Stunprod" + result = /obj/item/weapon/melee/baton/cattleprod + reqs = list(/obj/item/weapon/handcuffs/cable = 1, + /obj/item/stack/rods = 1, + /obj/item/weapon/tool/wirecutters = 1) + time = 40 + category = CAT_WEAPONRY + subcategory = CAT_WEAPON \ No newline at end of file diff --git a/code/datums/components/crafting/tool_quality.dm b/code/datums/components/crafting/tool_quality.dm new file mode 100644 index 00000000000..119469310a7 --- /dev/null +++ b/code/datums/components/crafting/tool_quality.dm @@ -0,0 +1,29 @@ +/obj/item + var/list/tool_qualities + +/// Used to check for a specific tool quality on an item. +/// Returns TRUE or FALSE depending on whether `tool_quality` is found. +/obj/item/proc/has_tool_quality(tool_quality) + return !!LAZYFIND(tool_qualities, tool_quality) + +/* Legacy Support */ + +/// DEPRECATED PROC: DO NOT USE IN NEW CODE +/obj/item/proc/is_screwdriver() + return has_tool_quality(TOOL_SCREWDRIVER) + +/// DEPRECATED PROC: DO NOT USE IN NEW CODE +/obj/item/proc/is_wrench() + return has_tool_quality(TOOL_WRENCH) + +/// DEPRECATED PROC: DO NOT USE IN NEW CODE +/obj/item/proc/is_crowbar() + return has_tool_quality(TOOL_CROWBAR) + +/// DEPRECATED PROC: DO NOT USE IN NEW CODE +/obj/item/proc/is_wirecutter() + return has_tool_quality(TOOL_WIRECUTTER) + +/// DEPRECATED PROC: DO NOT USE IN NEW CODE +/obj/item/proc/is_multitool() + return has_tool_quality(TOOL_MULTITOOL) diff --git a/code/datums/looping_sounds/weather_sounds.dm b/code/datums/looping_sounds/weather_sounds.dm index 106c25643af..4a029930587 100644 --- a/code/datums/looping_sounds/weather_sounds.dm +++ b/code/datums/looping_sounds/weather_sounds.dm @@ -11,7 +11,7 @@ start_sound = 'sound/effects/weather/snowstorm/outside/active_start.ogg' start_length = 13 SECONDS end_sound = 'sound/effects/weather/snowstorm/outside/active_end.ogg' - volume = 80 + volume = 40 /datum/looping_sound/weather/inside_blizzard mid_sounds = list( @@ -23,7 +23,7 @@ start_sound = 'sound/effects/weather/snowstorm/inside/active_start.ogg' start_length = 13 SECONDS end_sound = 'sound/effects/weather/snowstorm/inside/active_end.ogg' - volume = 60 + volume = 20 /datum/looping_sound/weather/outside_snow mid_sounds = list( @@ -35,7 +35,7 @@ start_sound = 'sound/effects/weather/snowstorm/outside/weak_start.ogg' start_length = 13 SECONDS end_sound = 'sound/effects/weather/snowstorm/outside/weak_end.ogg' - volume = 50 + volume = 20 /datum/looping_sound/weather/inside_snow mid_sounds = list( @@ -47,7 +47,7 @@ start_sound = 'sound/effects/weather/snowstorm/inside/weak_start.ogg' start_length = 13 SECONDS end_sound = 'sound/effects/weather/snowstorm/inside/weak_end.ogg' - volume = 30 + volume = 10 /datum/looping_sound/weather/wind mid_sounds = list( @@ -59,11 +59,17 @@ 'sound/effects/weather/wind/wind_5_1.ogg' = 1 ) mid_length = 10 SECONDS // The lengths for the files vary, but the longest is ten seconds, so this will make it sound like intermittent wind. - volume = 50 + volume = 45 // Don't have special sounds so we just make it quieter indoors. /datum/looping_sound/weather/wind/indoors - volume = 30 + volume = 25 + +/datum/looping_sound/weather/wind/gentle + volume = 15 + +/datum/looping_sound/weather/wind/gentle/indoors + volume = 5 /datum/looping_sound/weather/rain mid_sounds = list( @@ -73,7 +79,13 @@ start_sound = 'sound/effects/weather/acidrain_start.ogg' start_length = 13 SECONDS end_sound = 'sound/effects/weather/acidrain_end.ogg' - volume = 50 + volume = 20 /datum/looping_sound/weather/rain/indoors - volume = 30 \ No newline at end of file + volume = 10 + +/datum/looping_sound/weather/rain/heavy + volume = 40 + +/datum/looping_sound/weather/rain/heavy/indoors + volume = 20 \ No newline at end of file diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 82e5f1f78bd..c8897514754 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -58,6 +58,7 @@ var/list/purchase_log = new var/used_TC = 0 + var/list/learned_recipes //List of learned recipe TYPES. // the world.time since the mob has been brigged, or -1 if not at all var/brigged_since = -1 diff --git a/code/datums/repositories/crew.dm b/code/datums/repositories/crew.dm index c45202194bd..997a8357da4 100644 --- a/code/datums/repositories/crew.dm +++ b/code/datums/repositories/crew.dm @@ -24,7 +24,8 @@ var/global/datum/repository/crew/crew_repository = new() var/tracked = scan() for(var/obj/item/clothing/under/C in tracked) var/turf/pos = get_turf(C) - if((C) && (C.has_sensor) && (pos) && (pos.z == zLevel) && (C.sensor_mode != SUIT_SENSOR_OFF) && !(is_jammed(C))) + var/area/B = pos?.loc //VOREStation Add: No sensor in Dorm + if((C.has_sensor) && (pos?.z == zLevel) && (C.sensor_mode != SUIT_SENSOR_OFF) && !(B.block_suit_sensors) && !(is_jammed(C)) && !(is_vore_jammed(C))) //VOREStation Edit if(istype(C.loc, /mob/living/carbon/human)) var/mob/living/carbon/human/H = C.loc if(H.w_uniform != C) diff --git a/code/datums/supplypacks/engineering.dm b/code/datums/supplypacks/engineering.dm index f295676402b..0529f5aedd4 100644 --- a/code/datums/supplypacks/engineering.dm +++ b/code/datums/supplypacks/engineering.dm @@ -247,11 +247,21 @@ /obj/item/clothing/suit/radiation = 3, /obj/item/clothing/head/radiation = 3 ) - name = "Radiation suits package" + name = "Radiation suits package (Humanoid)" cost = 20 containertype = /obj/structure/closet/radiation containername = "Radiation suit locker" +/datum/supply_pack/eng/radsuitteshari + contains = list( + /obj/item/clothing/suit/radiation/teshari = 3, + /obj/item/clothing/head/radiation/teshari = 3 + ) + name = "Radiation suits package (Teshari)" + cost = 40 + containertype = /obj/structure/closet/crate/aether + containername = "Teshari radiation suit locker" + /datum/supply_pack/eng/pacman_parts name = "P.A.C.M.A.N. portable generator parts" cost = 25 diff --git a/code/datums/uplink/visible_weapons_vr.dm b/code/datums/uplink/visible_weapons_vr.dm index d8df7d15eb8..764e30b12f9 100644 --- a/code/datums/uplink/visible_weapons_vr.dm +++ b/code/datums/uplink/visible_weapons_vr.dm @@ -2,11 +2,21 @@ * Highly Visible and Dangerous Weapons * ***************************************/ /datum/uplink_item/item/visible_weapons/holdout - name = "Holdout Phaser" + name = "Frontier Holdout" item_cost = 30 path = /obj/item/weapon/gun/energy/locked/frontier/holdout/unlocked /datum/uplink_item/item/visible_weapons/frontier - name = "Frontier Carbine" + name = "Frontier Phaser" item_cost = 75 + path = /obj/item/weapon/gun/energy/locked/frontier/unlocked + +/datum/uplink_item/item/visible_weapons/carbine + name = "Frontier Carbine" + item_cost = 85 path = /obj/item/weapon/gun/energy/locked/frontier/carbine/unlocked + +/datum/uplink_item/item/visible_weapons/rifle + name = "Frontier Marksman Rifle" + item_cost = 100 + path = /obj/item/weapon/gun/energy/locked/frontier/rifle/unlocked diff --git a/code/datums/vending/stored_item.dm b/code/datums/vending/stored_item.dm index 23d06c909a9..1f5d613b8a7 100644 --- a/code/datums/vending/stored_item.dm +++ b/code/datums/vending/stored_item.dm @@ -3,6 +3,7 @@ */ /datum/stored_item var/item_name = "name" //Name of the item(s) displayed + var/item_desc var/item_path = null var/amount = 0 var/list/instances //What items are actually stored diff --git a/code/game/area/Space Station 13 areas_vr.dm b/code/game/area/Space Station 13 areas_vr.dm index 9b1a751ec67..c7a18a41070 100644 --- a/code/game/area/Space Station 13 areas_vr.dm +++ b/code/game/area/Space Station 13 areas_vr.dm @@ -1,6 +1,3 @@ -/area - var/limit_mob_size = TRUE //If mob size is limited in the area. - /area/shuttle/belter name = "Belter Shuttle" icon_state = "shuttle2" diff --git a/code/game/area/areas_vr.dm b/code/game/area/areas_vr.dm index 5396c46e601..371701e5b65 100644 --- a/code/game/area/areas_vr.dm +++ b/code/game/area/areas_vr.dm @@ -1,6 +1,8 @@ /area var/enter_message var/exit_message + var/limit_mob_size = TRUE //If mob size is limited in the area. + var/block_suit_sensors = FALSE //If mob size is limited in the area. /area/Entered(var/atom/movable/AM, oldLoc) . = ..() diff --git a/code/game/atoms.dm b/code/game/atoms.dm index e4ad20f5d48..46f001c8e1b 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -490,7 +490,7 @@ // Use for objects performing visible actions // message is output to anyone who can see, e.g. "The [src] does something!" // blind_message (optional) is what blind people will hear e.g. "You hear something!" -/atom/proc/visible_message(var/message, var/blind_message, var/list/exclude_mobs = null) +/atom/proc/visible_message(var/message, var/blind_message, var/list/exclude_mobs, var/range = world.view) //VOREStation Edit var/list/see @@ -498,7 +498,7 @@ var/obj/belly/B = loc see = B.get_mobs_and_objs_in_belly() else - see = get_mobs_and_objs_in_view_fast(get_turf(src),world.view,remote_ghosts = FALSE) + see = get_mobs_and_objs_in_view_fast(get_turf(src), range, remote_ghosts = FALSE) //VOREStation Edit End var/list/seeing_mobs = see["mobs"] @@ -508,20 +508,20 @@ for(var/obj in seeing_objs) var/obj/O = obj - O.show_message(message, 1, blind_message, 2) + O.show_message(message, VISIBLE_MESSAGE, blind_message, AUDIBLE_MESSAGE) for(var/mob in seeing_mobs) var/mob/M = mob if(M.see_invisible >= invisibility && MOB_CAN_SEE_PLANE(M, plane)) - M.show_message(message, 1, blind_message, 2) + M.show_message(message, VISIBLE_MESSAGE, blind_message, AUDIBLE_MESSAGE) else if(blind_message) - M.show_message(blind_message, 2) + M.show_message(blind_message, AUDIBLE_MESSAGE) // Show a message to all mobs and objects in earshot of this atom // Use for objects performing audible actions // message is the message output to anyone who can hear. // deaf_message (optional) is what deaf people will see. // hearing_distance (optional) is the range, how many tiles away the message can be heard. -/atom/proc/audible_message(var/message, var/deaf_message, var/hearing_distance) +/atom/proc/audible_message(var/message, var/deaf_message, var/hearing_distance, var/radio_message) var/range = hearing_distance || world.view var/list/hear = get_mobs_and_objs_in_view_fast(get_turf(src),range,remote_ghosts = FALSE) @@ -529,14 +529,19 @@ var/list/hearing_mobs = hear["mobs"] var/list/hearing_objs = hear["objs"] - for(var/obj in hearing_objs) - var/obj/O = obj - O.show_message(message, 2, deaf_message, 1) + if(radio_message) + for(var/obj in hearing_objs) + var/obj/O = obj + O.hear_talk(src, list(new /datum/multilingual_say_piece(GLOB.all_languages["Noise"], radio_message)), null) + else + for(var/obj in hearing_objs) + var/obj/O = obj + O.show_message(message, AUDIBLE_MESSAGE, deaf_message, VISIBLE_MESSAGE) for(var/mob in hearing_mobs) var/mob/M = mob var/msg = message - M.show_message(msg, 2, deaf_message, 1) + M.show_message(msg, AUDIBLE_MESSAGE, deaf_message, VISIBLE_MESSAGE) /atom/movable/proc/dropInto(var/atom/destination) while(istype(destination)) @@ -647,4 +652,7 @@ /atom/Exited(atom/movable/AM, atom/new_loc) . = ..() - SEND_SIGNAL(src, COMSIG_ATOM_EXITED, AM, new_loc) \ No newline at end of file + SEND_SIGNAL(src, COMSIG_ATOM_EXITED, AM, new_loc) + +/atom/proc/get_visible_gender() + return gender diff --git a/code/game/dna/dna2_helpers.dm b/code/game/dna/dna2_helpers.dm index e94befcd8b7..3fb282d72d5 100644 --- a/code/game/dna/dna2_helpers.dm +++ b/code/game/dna/dna2_helpers.dm @@ -243,7 +243,7 @@ H.custom_exclaim = dna.custom_exclaim H.species.blood_color = dna.blood_color var/datum/species/S = H.species - S.produceCopy(dna.species_traits,src) + S.produceCopy(dna.species_traits, H, dna.base_species) // VOREStation Edit End H.force_update_organs() //VOREStation Add - Gotta do this too diff --git a/code/game/machinery/adv_med.dm b/code/game/machinery/adv_med.dm index d172e0e8dbc..1aa1967d6db 100644 --- a/code/game/machinery/adv_med.dm +++ b/code/game/machinery/adv_med.dm @@ -318,6 +318,10 @@ organData["robotic"] = (I.robotic >= ORGAN_ROBOT) organData["dead"] = (I.status & ORGAN_DEAD) + if(istype(I, /obj/item/organ/internal/appendix)) + var/obj/item/organ/internal/appendix/A = I + organData["inflamed"] = A.inflamed + intOrganData.Add(list(organData)) occupantData["intOrgan"] = intOrganData @@ -497,23 +501,28 @@ if(i.robotic >= ORGAN_ROBOT) mech = "Mechanical:" if(i.status & ORGAN_DEAD) - i_dead = "Necrotic:" + i_dead = "Necrotic" var/infection = "None" switch (i.germ_level) if (INFECTION_LEVEL_ONE to INFECTION_LEVEL_ONE + 200) - infection = "Mild Infection:" + infection = "Mild Infection" if (INFECTION_LEVEL_ONE + 200 to INFECTION_LEVEL_ONE + 300) - infection = "Mild Infection+:" + infection = "Mild Infection+" if (INFECTION_LEVEL_ONE + 300 to INFECTION_LEVEL_ONE + 400) - infection = "Mild Infection++:" + infection = "Mild Infection++" if (INFECTION_LEVEL_TWO to INFECTION_LEVEL_TWO + 200) - infection = "Acute Infection:" + infection = "Acute Infection" if (INFECTION_LEVEL_TWO + 200 to INFECTION_LEVEL_TWO + 300) - infection = "Acute Infection+:" + infection = "Acute Infection+" if (INFECTION_LEVEL_TWO + 300 to INFECTION_LEVEL_THREE - 50) - infection = "Acute Infection++:" + infection = "Acute Infection++" if (INFECTION_LEVEL_THREE -49 to INFINITY) - infection = "Necrosis Detected:" + infection = "Necrosis Detected" + + if(istype(i, /obj/item/organ/internal/appendix)) + var/obj/item/organ/internal/appendix/A = i + if(A.inflamed) + infection = "Inflammation detected!" dat += "" dat += "[i.name]N/A[i.damage][infection]:[mech][i_dead]" diff --git a/code/game/machinery/computer/arcade_vr.dm b/code/game/machinery/computer/arcade_vr.dm new file mode 100644 index 00000000000..86669259a10 --- /dev/null +++ b/code/game/machinery/computer/arcade_vr.dm @@ -0,0 +1,35 @@ +/obj/machinery/computer/arcade + list/prizes = list( /obj/item/weapon/storage/box/snappops = 2, + /obj/item/toy/blink = 2, + /obj/item/clothing/under/syndicate/tacticool = 2, + /obj/item/toy/sword = 2, + /obj/item/weapon/gun/projectile/revolver/capgun = 2, + /obj/item/toy/crossbow = 2, + /obj/item/clothing/suit/syndicatefake = 2, + /obj/item/weapon/storage/fancy/crayons = 2, + /obj/item/toy/spinningtoy = 2, + /obj/random/mech_toy = 1, + /obj/item/weapon/reagent_containers/spray/waterflower = 1, + /obj/random/action_figure = 1, + /obj/random/plushie = 1, + /obj/item/toy/cultsword = 1, + /obj/item/toy/bouquet/fake = 1, + /obj/item/clothing/accessory/badge/sheriff = 2, + /obj/item/clothing/head/cowboy_hat/small = 2, + /obj/item/toy/stickhorse = 2, + /obj/item/toy/rock = 2, + /obj/item/toy/flash = 2, + /obj/item/toy/redbutton = 2, + /obj/item/toy/gnome = 2, + /obj/item/toy/AI = 2, + /obj/item/clothing/gloves/ring/buzzer/toy = 2, + /obj/item/weapon/storage/box/handcuffs/fake = 2, + /obj/item/toy/nuke = 2, + /obj/item/toy/minigibber = 2, + /obj/item/toy/toy_xeno = 2, + /obj/item/toy/russian_revolver = 1, + /obj/item/toy/russian_revolver/trick_revolver = 1, + /obj/item/toy/chainsaw = 1, + /obj/random/miniature = 1, + /obj/item/toy/snake_popper = 1 + ) \ No newline at end of file diff --git a/code/game/machinery/computer/card.dm b/code/game/machinery/computer/card.dm index c08bcb2d82b..3473216a7bd 100644 --- a/code/game/machinery/computer/card.dm +++ b/code/game/machinery/computer/card.dm @@ -200,7 +200,6 @@ modify.access -= access_type if(!access_allowed) modify.access += access_type - modify.lost_access = list() //VOREStation addition: reset the lost access upon any modifications . = TRUE if("assign") @@ -225,7 +224,6 @@ modify.access = access modify.assignment = t1 modify.rank = t1 - modify.lost_access = list() //VOREStation addition: reset the lost access upon any modifications callHook("reassign_employee", list(modify)) . = TRUE @@ -283,7 +281,6 @@ if(is_authenticated()) modify.assignment = "Dismissed" //VOREStation Edit: setting adjustment modify.access = list() - modify.lost_access = list() //VOREStation addition: reset the lost access upon any modifications callHook("terminate_employee", list(modify)) diff --git a/code/game/machinery/computer/id_restorer_vr.dm b/code/game/machinery/computer/id_restorer_vr.dm index acd4caa14ca..af7f9304f95 100644 --- a/code/game/machinery/computer/id_restorer_vr.dm +++ b/code/game/machinery/computer/id_restorer_vr.dm @@ -17,6 +17,7 @@ var/obj/item/weapon/card/id/inserted /obj/machinery/computer/id_restorer/attackby(obj/I, mob/user) + /* if(istype(I, /obj/item/weapon/card/id) && !(istype(I,/obj/item/weapon/card/id/guest))) if(!inserted && user.unEquip(I)) I.forceMove(src) @@ -24,12 +25,14 @@ else if(inserted) to_chat(user, "There is already ID card inside.") return + */ ..() /obj/machinery/computer/id_restorer/attack_hand(mob/user) if(..()) return if(stat & (NOPOWER|BROKEN)) return + /* if(!inserted) // No point in giving you an option what to do if there's no ID to do things with. to_chat(user, "No ID is inserted.") return @@ -78,6 +81,7 @@ return if("Cancel") return + */ //Frame diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm index 5b4305844ef..f17c97a627b 100644 --- a/code/game/machinery/cryopod.dm +++ b/code/game/machinery/cryopod.dm @@ -507,7 +507,6 @@ log_and_message_admins("[key_name(to_despawn)] ([to_despawn.mind.role_alt_title]) entered cryostorage.") announce.autosay("[to_despawn.real_name], [to_despawn.mind.role_alt_title], [on_store_message]", "[on_store_name]", announce_channel, using_map.get_map_levels(z, TRUE, om_range = DEFAULT_OVERMAP_RANGE)) - //visible_message("\The [initial(name)] hums and hisses as it moves [to_despawn.real_name] into storage.", 3) visible_message("\The [initial(name)] [on_store_visible_message_1] [to_despawn.real_name] [on_store_visible_message_2]", 3) //VOREStation Edit begin: Dont delete mobs-in-mobs diff --git a/code/game/machinery/pointdefense.dm b/code/game/machinery/pointdefense.dm index 705e2892e92..4c3ac8ded3d 100644 --- a/code/game/machinery/pointdefense.dm +++ b/code/game/machinery/pointdefense.dm @@ -4,7 +4,7 @@ // GLOBAL_LIST_BOILERPLATE(pointdefense_controllers, /obj/machinery/pointdefense_control) -GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense) +GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/power/pointdefense) /obj/machinery/pointdefense_control name = "fire assist mainframe" @@ -54,7 +54,7 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense) return TRUE if(action == "toggle_active") - var/obj/machinery/pointdefense/PD = locate(params["target"]) + var/obj/machinery/power/pointdefense/PD = locate(params["target"]) if(!istype(PD)) return FALSE @@ -77,7 +77,7 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense) if(id_tag) var/list/connected_z_levels = GetConnectedZlevels(get_z(src)) for(var/i = 1 to LAZYLEN(pointdefense_turrets)) - var/obj/machinery/pointdefense/PD = pointdefense_turrets[i] + var/obj/machinery/power/pointdefense/PD = pointdefense_turrets[i] if(!(PD.id_tag == id_tag && get_z(PD) in connected_z_levels)) continue var/list/turret = list() @@ -118,7 +118,7 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense) // The acutal point defense battery // -/obj/machinery/pointdefense +/obj/machinery/power/pointdefense name = "\improper point defense battery" icon = 'icons/obj/pointdefense.dmi' icon_state = "pointdefense2" @@ -128,6 +128,7 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense) anchored = TRUE circuit = /obj/item/weapon/circuitboard/pointdefense idle_power_usage = 0.1 KILOWATTS + active_power_usage = 1 KILOWATTS appearance_flags = PIXEL_SCALE var/active = TRUE var/charge_cooldown = 1 SECOND //time between it can fire at different targets @@ -137,33 +138,69 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense) var/weakref/engaging = null // The meteor we're shooting at var/id_tag = null -/obj/machinery/pointdefense/Initialize() +/obj/machinery/power/pointdefense/Initialize() . = ..() // TODO - Remove this bit once machines are converted to Initialize if(ispath(circuit)) circuit = new circuit(src) default_apply_parts() + if(anchored) + connect_to_network() update_icon() + var/image/I = image(icon, icon_state = "[icon_state]_under") + I.appearance_flags |= RESET_TRANSFORM + underlays += I -/obj/machinery/pointdefense/get_description_interaction() +/obj/machinery/power/pointdefense/examine(mob/user) + . = ..() + if(powernet) + . += "It is connected to a power cable below." + +/obj/machinery/power/pointdefense/get_description_interaction() . = ..() if(!id_tag) . += "[desc_panel_image("multitool")]to set ident tag and connect to a mainframe." -/obj/machinery/pointdefense/update_icon() +/obj/machinery/power/pointdefense/update_icon() if(!active || !id_tag || inoperable()) icon_state = "[initial(icon_state)]_off" else icon_state = initial(icon_state) -/obj/machinery/pointdefense/power_change() +/obj/machinery/power/pointdefense/default_unfasten_wrench(var/mob/user, var/obj/item/weapon/W, var/time) + if((. = ..())) + src.transform = null // Reset rotation if we're anchored/unanchored + +////////// This machine is willing to take power from cables OR APCs. Handle NOPOWER stat specially here! //////// + +/obj/machinery/power/pointdefense/connect_to_network() + if((. = ..())) + stat &= ~NOPOWER // We now ignore APC power + update_icon() + +/obj/machinery/power/pointdefense/disconnect_from_network() + if((. = ..())) + power_change() // We're back on APC power. + +/obj/machinery/power/pointdefense/power_change() + if(powernet) + return // We don't care, we are cable powered anyway var/old_stat = stat ..() if(old_stat != stat) update_icon() +// Decide where to get the power to fire from +/obj/machinery/power/pointdefense/use_power_oneoff(var/amount, var/chan = -1) + if(powernet) + return draw_power(amount) + else if(powered(chan)) + use_power(amount, chan) + return amount + return 0 + // Find controller with the same tag on connected z levels (if any) -/obj/machinery/pointdefense/proc/get_controller() +/obj/machinery/power/pointdefense/proc/get_controller() if(!id_tag) return null var/list/connected_z_levels = GetConnectedZlevels(get_z(src)) @@ -172,7 +209,7 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense) if(PDC.id_tag == id_tag && (get_z(PDC) in connected_z_levels)) return PDC -/obj/machinery/pointdefense/attackby(var/obj/item/W, var/mob/user) +/obj/machinery/power/pointdefense/attackby(var/obj/item/W, var/mob/user) if(W?.is_multitool()) var/new_ident = input(user, "Enter a new ident tag.", "[src]", id_tag) as null|text if(new_ident && new_ident != id_tag && user.Adjacent(src) && CanInteract(user, GLOB.tgui_physical_state)) @@ -185,16 +222,18 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense) return if(default_part_replacement(user, W)) return + if(default_unfasten_wrench(user, W, 40)) + return return ..() //Guns cannot shoot through hull or generally dense turfs. -/obj/machinery/pointdefense/proc/space_los(meteor) +/obj/machinery/power/pointdefense/proc/space_los(meteor) for(var/turf/T in getline(src,meteor)) if(T.density) return FALSE return TRUE -/obj/machinery/pointdefense/proc/Shoot(var/weakref/target) +/obj/machinery/power/pointdefense/proc/Shoot(var/weakref/target) var/obj/effect/meteor/M = target.resolve() if(!istype(M)) engaging = null @@ -208,7 +247,7 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense) set_dir(ATAN2(transform.b, transform.a) > 0 ? NORTH : SOUTH) -/obj/machinery/pointdefense/proc/finish_shot(var/weakref/target) +/obj/machinery/power/pointdefense/proc/finish_shot(var/weakref/target) var/obj/machinery/pointdefense_control/PC = get_controller() engaging = null @@ -218,26 +257,34 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense) var/obj/effect/meteor/M = target.resolve() if(!istype(M)) return + if(use_power_oneoff(active_power_usage) < active_power_usage) + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread + s.set_up(5, 1, src) + s.start() + visible_message("[src] sputters as browns out while attempting to fire.") + flick(src, "[initial(icon_state)]_off") + return //We throw a laser but it doesnt have to hit for meteor to explode var/obj/item/projectile/beam/pointdefense/beam = new(get_turf(src)) playsound(src, 'sound/weapons/mandalorian.ogg', 75, 1) - use_power_oneoff(idle_power_usage * 10) beam.launch_projectile(target = M.loc, user = src) -/obj/machinery/pointdefense/process() +/obj/machinery/power/pointdefense/process() ..() - if(stat & (NOPOWER|BROKEN)) + if(!anchored || stat & (NOPOWER|BROKEN)) return if(!active) return + /* var/desiredir = ATAN2(transform.b, transform.a) > 0 ? NORTH : SOUTH if(dir != desiredir) set_dir(desiredir) + */ if(LAZYLEN(GLOB.meteor_list) > 0) find_and_shoot() -/obj/machinery/pointdefense/proc/find_and_shoot() +/obj/machinery/power/pointdefense/proc/find_and_shoot() // There ARE meteors to shoot if(LAZYLEN(GLOB.meteor_list) == 0) return @@ -273,7 +320,7 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense) Shoot(target) return -/obj/machinery/pointdefense/proc/targeting_check(var/obj/effect/meteor/M) +/obj/machinery/power/pointdefense/proc/targeting_check(var/obj/effect/meteor/M) // Target in range var/list/connected_z_levels = GetConnectedZlevels(get_z(src)) if(!(M.z in connected_z_levels)) @@ -286,7 +333,7 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense) return TRUE -/obj/machinery/pointdefense/RefreshParts() +/obj/machinery/power/pointdefense/RefreshParts() . = ..() // Calculates an average rating of components that affect shooting rate var/shootrate_divisor = total_component_rating_of_type(/obj/item/weapon/stock_parts/capacitor) @@ -302,7 +349,7 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense) var/rotation_divisor = total_component_rating_of_type(/obj/item/weapon/stock_parts/manipulator) rotation_speed = 0.5 SECONDS / (rotation_divisor ? rotation_divisor : 1) -/obj/machinery/pointdefense/proc/Activate() +/obj/machinery/power/pointdefense/proc/Activate() if(active) return FALSE @@ -312,7 +359,7 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense) update_icon() return TRUE -/obj/machinery/pointdefense/proc/Deactivate() +/obj/machinery/power/pointdefense/proc/Deactivate() if(!active) return FALSE playsound(src, 'sound/machines/apc_nopower.ogg', 50, 0) diff --git a/code/game/machinery/portable_turret_vr.dm b/code/game/machinery/portable_turret_vr.dm index 90866e1d632..b83f3720fff 100644 --- a/code/game/machinery/portable_turret_vr.dm +++ b/code/game/machinery/portable_turret_vr.dm @@ -24,7 +24,7 @@ name = "military CIWS turret" desc = "A ship weapons turret designed for anti-fighter defense." req_one_access = list(access_cent_general) - installation = /obj/item/weapon/gun/energy/lasercannon + installation = /obj/item/weapon/gun/energy/pulse_rifle/destroyer health = 500 maxhealth = 500 enabled = TRUE diff --git a/code/game/machinery/rechargestation.dm b/code/game/machinery/rechargestation.dm index 98ad80e4688..34d988e4837 100644 --- a/code/game/machinery/rechargestation.dm +++ b/code/game/machinery/rechargestation.dm @@ -246,7 +246,7 @@ if(!R.cell) return - if(R.mob_size >= MOB_LARGE) + if(istype(R, /mob/living/silicon/robot/platform)) to_chat(R, SPAN_WARNING("You are too large to fit into \the [src].")) return diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index 8175ee91dae..27e54fd6430 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -634,10 +634,6 @@ model_text = "Exploration" departments = list("Exploration","Expedition Medic","Old Exploration","No Change") -/obj/machinery/suit_cycler/exploration/Initialize() - species -= SPECIES_TESHARI - return ..() - /obj/machinery/suit_cycler/pilot name = "Pilot suit cycler" model_text = "Pilot" diff --git a/code/game/machinery/vending_machines_vr.dm b/code/game/machinery/vending_machines_vr.dm index 94a55bba1b4..e6c5058881d 100644 --- a/code/game/machinery/vending_machines_vr.dm +++ b/code/game/machinery/vending_machines_vr.dm @@ -4614,3 +4614,36 @@ /obj/machinery/vending/cola/soft icon = 'icons/obj/vending_vr.dmi' icon_state = "Cola_Machine" + +//////////////////////Bepis Drinks (04/29/2021)////////////////////// + +/obj/machinery/vending/bepis + name = "Bepis Softdrinks" + desc = "A strange softdrink vendor that isn't owned by NanoTrasen... Why (and how) is it here?" + icon = 'icons/obj/vending_vr.dmi' + icon_state = "bepis" + product_slogans = "Refreshing!;Have a sip, you won't believe the taste!;Puts the 'B' in Best Soda!" + product_ads = "Refreshing!;Hope you're thirsty!;Please, have a drink!;Drink up!" + products = list(/obj/item/weapon/reagent_containers/food/drinks/cans/bepis = 10, + /obj/item/weapon/reagent_containers/food/drinks/cans/astrodew = 10, + /obj/item/weapon/reagent_containers/food/drinks/cans/buzz = 10, + /obj/item/weapon/reagent_containers/food/drinks/cans/shambler = 10, + /obj/item/weapon/reagent_containers/food/drinks/cans/cranberry = 10, + /obj/item/weapon/reagent_containers/food/drinks/cans/icecoffee = 10, + /obj/item/weapon/reagent_containers/food/drinks/cans/iced_tea = 10, + /obj/item/weapon/reagent_containers/food/drinks/cans/grape_juice = 10, + /obj/item/weapon/reagent_containers/food/drinks/cans/gingerale = 10, + /obj/item/weapon/reagent_containers/food/drinks/cans/root_beer = 10) + + prices = list(/obj/item/weapon/reagent_containers/food/drinks/cans/bepis = 1, + /obj/item/weapon/reagent_containers/food/drinks/cans/astrodew = 1, + /obj/item/weapon/reagent_containers/food/drinks/cans/buzz = 1, + /obj/item/weapon/reagent_containers/food/drinks/cans/shambler = 1, + /obj/item/weapon/reagent_containers/food/drinks/cans/cranberry = 1, + /obj/item/weapon/reagent_containers/food/drinks/cans/icecoffee = 1, + /obj/item/weapon/reagent_containers/food/drinks/cans/iced_tea = 1, + /obj/item/weapon/reagent_containers/food/drinks/cans/grape_juice = 1, + /obj/item/weapon/reagent_containers/food/drinks/cans/gingerale = 1, + /obj/item/weapon/reagent_containers/food/drinks/cans/root_beer = 1) + idle_power_usage = 211 //refrigerator - believe it or not, this is actually the average power consumption of a refrigerated vending machine according to NRCan. + vending_sound = "machines/vending/vending_cans.ogg" diff --git a/code/game/objects/effects/confetti_vr.dm b/code/game/objects/effects/confetti_vr.dm new file mode 100644 index 00000000000..0430938705d --- /dev/null +++ b/code/game/objects/effects/confetti_vr.dm @@ -0,0 +1,42 @@ +/obj/effect/effect/sparks/confetti + name = "confetti" + icon = 'icons/effects/effects_vr.dmi' + icon_state = "confetti" + +/obj/effect/effect/sparks/New() + ..() + playsound(src, "sounds/items/confetti.ogg ", 100, 1) + +/datum/effect/effect/system/confetti_spread + var/total_sparks = 0 // To stop it being spammed and lagging! + + set_up(n = 3, c = 0, loca) + if(n > 10) + n = 10 + number = n + cardinals = c + if(istype(loca, /turf/)) + location = loca + else + location = get_turf(loca) + + start() + var/i = 0 + for(i=0, i 20) + return + spawn(0) + if(holder) + src.location = get_turf(holder) + var/obj/effect/effect/sparks/confetti = new /obj/effect/effect/sparks/confetti(src.location) + src.total_sparks++ + var/direction + if(src.cardinals) + direction = pick(cardinal) + else + direction = pick(alldirs) + for(i=0, i[U] attempts to stab [M] in the eyes, but misses!") - for(var/mob/V in viewers(M)) - V.show_message("[U] attempts to stab [M] in the eyes, but misses!") + visible_message(SPAN_DANGER("\The [U] attempts to stab \the [M] in the eyes, but misses!")) return add_attack_logs(user,M,"Attack eyes with [name]") @@ -908,31 +906,6 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out. /obj/item/proc/apply_accessories(var/image/standing) return standing -/* - * Assorted tool procs, so any item can emulate any tool, if coded -*/ -/obj/item/proc/is_screwdriver() - return FALSE - -/obj/item/proc/is_wrench() - return FALSE - -/obj/item/proc/is_crowbar() - return FALSE - -/obj/item/proc/is_wirecutter() - return FALSE - -// These next three might bug out or runtime, unless someone goes back and finds a way to generalize their specific code -/obj/item/proc/is_cable_coil() - return FALSE - -/obj/item/proc/is_multitool() - return FALSE - -/obj/item/proc/is_welder() - return FALSE - /obj/item/MouseEntered(location,control,params) . = ..() if(usr.is_preference_enabled(/datum/client_preference/inv_tooltips) && ((src in usr) || isstorage(loc))) // If in inventory or in storage we're looking at diff --git a/code/game/objects/items/blueprints.dm b/code/game/objects/items/blueprints.dm index d6825967c26..96318ff1c08 100644 --- a/code/game/objects/items/blueprints.dm +++ b/code/game/objects/items/blueprints.dm @@ -194,10 +194,8 @@ return /obj/item/blueprints/proc/move_turfs_to_area(var/list/turf/turfs, var/area/A) - A.contents.Add(turfs) - //oldarea.contents.Remove(usr.loc) // not needed - //T.loc = A //error: cannot change constant value - + for(var/T in turfs) + ChangeArea(T, A) /obj/item/blueprints/proc/edit_area() var/area/A = get_area() diff --git a/code/game/objects/items/devices/multitool.dm b/code/game/objects/items/devices/multitool.dm index 8ac7a071996..5cd2faf2d5c 100644 --- a/code/game/objects/items/devices/multitool.dm +++ b/code/game/objects/items/devices/multitool.dm @@ -29,6 +29,7 @@ var/obj/machinery/connectable //Used to connect machinery. var/weakref_wiring //Used to store weak references for integrated circuitry. This is now the Omnitool. toolspeed = 1 + tool_qualities = list(TOOL_MULTITOOL) /obj/item/device/multitool/attack_self(mob/living/user) var/choice = alert("What do you want to do with \the [src]?","Multitool Menu", "Switch Mode", "Clear Buffers", "Cancel") @@ -65,9 +66,6 @@ return -/obj/item/device/multitool/is_multitool() - return TRUE - /obj/item/device/multitool/cyborg name = "multitool" desc = "Optimised and stripped-down version of a regular multitool." diff --git a/code/game/objects/items/devices/radio/jammer_vr.dm b/code/game/objects/items/devices/radio/jammer_vr.dm index a92005621aa..de195322a27 100644 --- a/code/game/objects/items/devices/radio/jammer_vr.dm +++ b/code/game/objects/items/devices/radio/jammer_vr.dm @@ -2,3 +2,14 @@ /obj/item/device/radio_jammer/admin jam_range = 255 tick_cost = 0 + +/proc/is_vore_jammed(var/obj/radio) + var/atom/current = radio + while(current.loc) + if(isbelly(current.loc)) + var/obj/belly/B = current.loc + if(B.mode_flags & DM_FLAG_JAMSENSORS) + return TRUE + current = current.loc + + return FALSE \ No newline at end of file diff --git a/code/game/objects/items/stacks/sheets/glass.dm b/code/game/objects/items/stacks/sheets/glass.dm deleted file mode 100644 index c2535ec3eb8..00000000000 --- a/code/game/objects/items/stacks/sheets/glass.dm +++ /dev/null @@ -1,102 +0,0 @@ -/* Glass stack types - * Contains: - * Glass sheets - * Reinforced glass sheets - * Phoron Glass Sheets - * Reinforced Phoron Glass Sheets (AKA Holy fuck strong windows) - * Glass shards - TODO: Move this into code/game/object/item/weapons - */ - -/* - * Glass sheets - */ -/obj/item/stack/material/glass - name = "glass" - singular_name = "glass sheet" - icon_state = "sheet-glass" - var/is_reinforced = 0 - default_type = "glass" - drop_sound = 'sound/items/drop/glass.ogg' - pickup_sound = 'sound/items/pickup/glass.ogg' - -/obj/item/stack/material/glass/attack_self(mob/user as mob) - construct_window(user) - -/obj/item/stack/material/glass/attackby(obj/item/W, mob/user) - ..() - if(!is_reinforced) - if(istype(W,/obj/item/stack/cable_coil)) - var/obj/item/stack/cable_coil/CC = W - if (get_amount() < 1 || CC.get_amount() < 5) - to_chat(user, "You need five lengths of coil and one sheet of glass to make wired glass.") - return - - CC.use(5) - use(1) - to_chat(user, "You attach wire to the [name].") - new /obj/item/stack/light_w(user.loc) - else if(istype(W, /obj/item/stack/rods)) - var/obj/item/stack/rods/V = W - if (V.get_amount() < 1 || get_amount() < 1) - to_chat(user, "You need one rod and one sheet of glass to make reinforced glass.") - return - - var/obj/item/stack/material/glass/reinforced/RG = new (user.loc) - RG.add_fingerprint(user) - RG.add_to_stacks(user) - var/obj/item/stack/material/glass/G = src - src = null - var/replace = (user.get_inactive_hand()==G) - V.use(1) - G.use(1) - if (!G && replace) - user.put_in_hands(RG) - - - - -/* - * Reinforced glass sheets - */ -/obj/item/stack/material/glass/reinforced - name = "reinforced glass" - singular_name = "reinforced glass sheet" - icon_state = "sheet-rglass" - default_type = "reinforced glass" - is_reinforced = 1 - -/* - * Phoron Glass sheets - */ -/obj/item/stack/material/glass/phoronglass - name = "phoron glass" - singular_name = "phoron glass sheet" - icon_state = "sheet-phoronglass" - default_type = "phoron glass" - -/obj/item/stack/material/glass/phoronglass/attackby(obj/item/W, mob/user) - ..() - if( istype(W, /obj/item/stack/rods) ) - var/obj/item/stack/rods/V = W - var/obj/item/stack/material/glass/phoronrglass/RG = new (user.loc) - RG.add_fingerprint(user) - RG.add_to_stacks(user) - V.use(1) - var/obj/item/stack/material/glass/G = src - src = null - var/replace = (user.get_inactive_hand()==G) - G.use(1) - if (!G && !RG && replace) - user.put_in_hands(RG) - else - return ..() - -/* - * Reinforced phoron glass sheets - */ -/obj/item/stack/material/glass/phoronrglass - name = "reinforced phoron glass" - singular_name = "reinforced phoron glass sheet" - icon_state = "sheet-phoronrglass" - default_type = "reinforced phoron glass" - is_reinforced = 1 diff --git a/code/game/objects/items/stacks/sheets/leather.dm b/code/game/objects/items/stacks/sheets/leather.dm deleted file mode 100644 index c48f57e693a..00000000000 --- a/code/game/objects/items/stacks/sheets/leather.dm +++ /dev/null @@ -1,286 +0,0 @@ -/obj/item/stack/animalhide - name = "hide" - desc = "The hide of some creature." - description_info = "Use something sharp, like a knife, to scrape the hairs/feathers/etc off this hide to prepare it for tanning." - icon_state = "sheet-hide" - drop_sound = 'sound/items/drop/cloth.ogg' - pickup_sound = 'sound/items/pickup/cloth.ogg' - amount = 1 - max_amount = 20 - stacktype = "hide" - no_variants = TRUE -// This needs to be very clearly documented for players. Whether it should stay in the main description is up for debate. -/obj/item/stack/animalhide/examine(var/mob/user) - . = ..() - . += description_info - -/obj/item/stack/animalhide/human - name = "skin" - desc = "The by-product of sapient farming." - singular_name = "skin piece" - icon_state = "sheet-hide" - no_variants = FALSE - drop_sound = 'sound/items/drop/leather.ogg' - pickup_sound = 'sound/items/pickup/leather.ogg' - stacktype = "hide-human" - -/obj/item/stack/animalhide/corgi - name = "corgi hide" - desc = "The by-product of corgi farming." - singular_name = "corgi hide piece" - icon_state = "sheet-corgi" - stacktype = "hide-corgi" - -/obj/item/stack/animalhide/cat - name = "cat hide" - desc = "The by-product of cat farming." - singular_name = "cat hide piece" - icon_state = "sheet-cat" - stacktype = "hide-cat" - -/obj/item/stack/animalhide/monkey - name = "monkey hide" - desc = "The by-product of monkey farming." - singular_name = "monkey hide piece" - icon_state = "sheet-monkey" - stacktype = "hide-monkey" - -/obj/item/stack/animalhide/lizard - name = "lizard skin" - desc = "Sssssss..." - singular_name = "lizard skin piece" - icon_state = "sheet-lizard" - stacktype = "hide-lizard" - -/obj/item/stack/animalhide/xeno - name = "alien hide" - desc = "The skin of a terrible creature." - singular_name = "alien hide piece" - icon_state = "sheet-xeno" - stacktype = "hide-xeno" - -//don't see anywhere else to put these, maybe together they could be used to make the xenos suit? -/obj/item/stack/xenochitin - name = "alien chitin" - desc = "A piece of the hide of a terrible creature." - singular_name = "alien chitin piece" - icon = 'icons/mob/alien.dmi' - icon_state = "chitin" - stacktype = "hide-chitin" - -/obj/item/xenos_claw - name = "alien claw" - desc = "The claw of a terrible creature." - icon = 'icons/mob/alien.dmi' - icon_state = "claw" - -/obj/item/weed_extract - name = "weed extract" - desc = "A piece of slimy, purplish weed." - icon = 'icons/mob/alien.dmi' - icon_state = "weed_extract" - -//Step one - dehairing. -/obj/item/stack/animalhide/attackby(obj/item/weapon/W as obj, mob/user as mob) - if(has_edge(W) || is_sharp(W)) - //visible message on mobs is defined as visible_message(var/message, var/self_message, var/blind_message) - user.visible_message("\The [user] starts cutting hair off \the [src]", "You start cutting the hair off \the [src]", "You hear the sound of a knife rubbing against flesh") - var/scraped = 0 - while(amount > 0 && do_after(user, 2.5 SECONDS)) // 2.5s per hide - //Try locating an exisitng stack on the tile and add to there if possible - var/obj/item/stack/hairlesshide/H = null - for(var/obj/item/stack/hairlesshide/HS in user.loc) // Could be scraping something inside a locker, hence the .loc, not get_turf - if(HS.amount < HS.max_amount) - H = HS - break - - // Either we found a valid stack, in which case increment amount, - // Or we need to make a new stack - if(istype(H)) - H.amount++ - else - H = new /obj/item/stack/hairlesshide(user.loc) - - // Increment the amount - src.use(1) - scraped++ - - if(scraped) - to_chat(user, SPAN_NOTICE("You scrape the hair off [scraped] hide\s.")) - else - ..() - - -//Step two - washing..... it's actually in washing machine code, and ere. - -/obj/item/stack/hairlesshide - name = "hairless hide" - desc = "This hide was stripped of it's hair, but still needs tanning." - description_info = "Get it wet to continue tanning this into leather.
\ - You could set it in a river, wash it with a sink, or just splash water on it with a bucket." - singular_name = "hairless hide piece" - icon_state = "sheet-hairlesshide" - no_variants = FALSE - max_amount = 20 - stacktype = "hairlesshide" - -/obj/item/stack/hairlesshide/examine(var/mob/user) - . = ..() - . += description_info - -/obj/item/stack/hairlesshide/water_act(var/wateramount) - . = ..() - wateramount = min(amount, round(wateramount)) - for(var/i in 1 to wateramount) - var/obj/item/stack/wetleather/H = null - for(var/obj/item/stack/wetleather/HS in get_turf(src)) // Doesn't have a user, can't just use their loc - if(HS.amount < HS.max_amount) - H = HS - break - - // Either we found a valid stack, in which case increment amount, - // Or we need to make a new stack - if(istype(H)) - H.amount++ - else - H = new /obj/item/stack/wetleather(get_turf(src)) - - // Increment the amount - src.use(1) - -/obj/item/stack/hairlesshide/proc/rapidcure(var/stacknum = 1) - stacknum = min(stacknum, amount) - - while(stacknum) - var/obj/item/stack/wetleather/I = new /obj/item/stack/wetleather(get_turf(src)) - - if(istype(I)) - I.dry() - - use(1) - stacknum -= 1 - -//Step three - drying -/obj/item/stack/wetleather - name = "wet leather" - desc = "This leather has been cleaned but still needs to be dried." - description_info = "To finish tanning the leather, you need to dry it. \ - You could place it under a fire, \ - put it in a drying rack, \ - or build a tanning rack from steel or wooden boards." - singular_name = "wet leather piece" - icon_state = "sheet-wetleather" - var/wetness = 30 //Reduced when exposed to high temperautres - var/drying_threshold_temperature = 500 //Kelvin to start drying - no_variants = FALSE - max_amount = 20 - stacktype = "wetleather" - - var/dry_type = /obj/item/stack/material/leather - -/obj/item/stack/wetleather/examine(var/mob/user) - . = ..() - . += description_info - . += "\The [src] is [get_dryness_text()]." - -/obj/item/stack/wetleather/proc/get_dryness_text() - if(wetness > 20) - return "wet" - if(wetness > 10) - return "damp" - if(wetness) - return "almost dry" - return "dry" - -/obj/item/stack/wetleather/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume) - ..() - if(exposed_temperature >= drying_threshold_temperature) - wetness-- - if(wetness == 0) - dry() - -/obj/item/stack/wetleather/proc/dry() - var/obj/item/stack/material/leather/L = new(src.loc) - L.amount = amount - use(amount) - return L - -/obj/item/stack/wetleather/transfer_to(obj/item/stack/S, var/tamount=null, var/type_verified) - . = ..() - if(.) // If it transfers any, do a weighted average of the wetness - var/obj/item/stack/wetleather/W = S - var/oldamt = W.amount - . - W.wetness = round(((oldamt * W.wetness) + (. * wetness)) / W.amount) - - - -/obj/structure/tanning_rack - name = "tanning rack" - desc = "A rack used to stretch leather out and hold it taut during the tanning process." - icon = 'icons/obj/kitchen.dmi' - icon_state = "spike" - - var/obj/item/stack/wetleather/drying = null - -/obj/structure/tanning_rack/Initialize() - . = ..() - START_PROCESSING(SSobj, src) // SSObj fires ~every 2s , starting from wetness 30 takes ~1m - -/obj/structure/tanning_rack/Destroy() - STOP_PROCESSING(SSobj, src) - return ..() - -/obj/structure/tanning_rack/process() - if(drying && drying.wetness) - drying.wetness = max(drying.wetness - 1, 0) - if(!drying.wetness) - visible_message("The [drying] is dry!") - update_icon() - -/obj/structure/tanning_rack/examine(var/mob/user) - . = ..() - if(drying) - . += "\The [drying] is [drying.get_dryness_text()]." - -/obj/structure/tanning_rack/update_icon() - overlays.Cut() - if(drying) - var/image/I - if(drying.wetness) - I = image(icon, "leather_wet") - else - I = image(icon, "leather_dry") - add_overlay(I) - -/obj/structure/tanning_rack/attackby(var/atom/A, var/mob/user) - if(istype(A, /obj/item/stack/wetleather)) - if(!drying) // If not drying anything, start drying the thing - if(user.unEquip(A, target = src)) - drying = A - else // Drying something, add if possible - var/obj/item/stack/wetleather/W = A - W.transfer_to(drying, W.amount, TRUE) - update_icon() - return TRUE - return ..() - -/obj/structure/tanning_rack/attack_hand(var/mob/user) - if(drying) - var/obj/item/stack/S = drying - if(!drying.wetness) // If it's dry, make a stack of dry leather and prepare to put that in their hands - var/obj/item/stack/material/leather/L = new(src) - L.amount = drying.amount - drying.use(drying.amount) - S = L - - if(ishuman(user)) - var/mob/living/carbon/human/H = user - if(!H.put_in_any_hand_if_possible(S)) - S.forceMove(get_turf(src)) - else - S.forceMove(get_turf(src)) - drying = null - update_icon() - -/obj/structure/tanning_rack/attack_robot(var/mob/user) - attack_hand(user) // That has checks to \ No newline at end of file diff --git a/code/game/objects/items/toys/toys.dm b/code/game/objects/items/toys/toys.dm index ea457f651ef..33a6904b421 100644 --- a/code/game/objects/items/toys/toys.dm +++ b/code/game/objects/items/toys/toys.dm @@ -1290,7 +1290,7 @@ /obj/item/toy/character/voidone, /obj/item/toy/character/lich ) - +/* VOREStation edit. Moved to toys_vr.dm /obj/item/toy/AI name = "toy AI" desc = "A little toy model AI core!"// with real law announcing action!" //Alas, requires a rewrite of how ion laws work. @@ -1298,7 +1298,7 @@ icon_state = "AI" w_class = ITEMSIZE_SMALL var/cooldown = 0 -/* + /obj/item/toy/AI/attack_self(mob/user) if(!cooldown) //for the sanity of everyone var/message = generate_ion_law() diff --git a/code/game/objects/items/toys/toys_vr.dm b/code/game/objects/items/toys/toys_vr.dm index 73f73d88334..347e7187edd 100644 --- a/code/game/objects/items/toys/toys_vr.dm +++ b/code/game/objects/items/toys/toys_vr.dm @@ -38,7 +38,7 @@ /obj/item/toy/plushie/box name = "cardboard plushie" - desc = "A toy box plushie, it holds cotten. Only a baddie would place a bomb through the postal system..." + desc = "A toy box plushie, it holds cotton. Only a baddie would place a bomb through the postal system..." icon = 'icons/obj/toy_vr.dmi' icon_state = "box" attack_verb = list("open", "closed", "packed", "hidden", "rigged", "bombed", "sent", "gave") @@ -101,3 +101,677 @@ /obj/item/toy/plushie/vox/proc/cooldownreset() cooldown = 0 +/* +* 4/9/21 * +* IPC Plush +* Toaster plush +* Snake plush +* Cube plush +* Pip plush +* Moth plush +* Crab plush +* Possum plush +* Goose plush +* White mouse plush +* Pet rock +* Pet rock (m) +* Pet rock (f) +* Chew toys +* Cat toy * 2 +* Toy flash +* Toy button +* Gnome +* Toy AI +* Buzzer ring +* Fake handcuffs +* Nuke toy +* Toy gibber +* Toy xeno +* Fake gun * 2 +* Toy chainsaw +* Random tabletop miniature spawner +* snake popper +*/ + +/obj/item/toy/plushie/ipc + name = "IPC plushie" + desc = "A pleasing soft-toy of a monitor-headed robot. Toaster functionality included." + icon = 'icons/obj/toy_vr.dmi' + icon_state = "plushie_ipc" + var/cooldown = 0 + +/obj/item/weapon/reagent_containers/food/snacks/slice/bread + var/toasted = FALSE + +/obj/item/weapon/reagent_containers/food/snacks/tastybread + var/toasted = FALSE + +/obj/item/weapon/reagent_containers/food/snacks/slice/bread/afterattack(atom/A, mob/user as mob, proximity) + if(istype(A, /obj/item/toy/plushie/ipc) && !toasted) + toasted = TRUE + icon = 'icons/obj/toy_vr.dmi' + icon_state = "toast" + to_chat(user, " You insert bread into the toaster. ") + playsound(loc, 'sound/machines/ding.ogg', 50, 1) + +/obj/item/weapon/reagent_containers/food/snacks/tastybread/afterattack(atom/A, mob/user as mob, proximity) + if(istype(A, /obj/item/toy/plushie/ipc) && !toasted) + toasted = TRUE + icon = 'icons/obj/toy_vr.dmi' + icon_state = "toast" + to_chat(user, " You insert bread into the toaster. ") + playsound(loc, 'sound/machines/ding.ogg', 50, 1) + +/obj/item/toy/plushie/ipc/attackby(obj/item/I as obj, mob/living/user as mob) + if(istype(I, /obj/item/weapon/material/kitchen/utensil)) + to_chat(user, " You insert the [I] into the toaster. ") + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread + s.set_up(5, 1, src) + s.start() + user.electrocute_act(15,src,0.75) + else + return ..() + + +/obj/item/toy/plushie/ipc/attack_self(mob/user as mob) + if(!cooldown) + playsound(user, 'sound/machines/ping.ogg', 10, 0) + src.visible_message("Ping!") + cooldown = 1 + addtimer(CALLBACK(src, .proc/cooldownreset), 50) + return ..() + +/obj/item/toy/plushie/ipc/proc/cooldownreset() + cooldown = 0 + +/obj/item/toy/plushie/ipc/toaster + name = "toaster plushie" + desc = "A stuffed toy of a pleasant art-deco toaster. It has a small tag on it reading 'Bricker Home Appliances! All rights reserved, copyright 2298.' It's a tad heavy on account of containing a heating coil. Want to make toast?" + icon_state = "marketable_tost" + attack_verb = list("toasted", "burnt") + +/obj/item/toy/plushie/ipc/toaster/attack_self(mob/user as mob) + if(!cooldown) + playsound(user, 'sound/machines/ding.ogg', 10, 0) + src.visible_message("Ding!") + cooldown = 1 + addtimer(CALLBACK(src, .proc/cooldownreset), 50) + return ..() + +/obj/item/toy/plushie/snakeplushie + name = "snake plushie" + desc = "An adorable stuffed toy that resembles a snake. Not to be mistaken for the real thing." + icon = 'icons/obj/toy_vr.dmi' + icon_state = "plushie_snake" + attack_verb = list("hissed", "snek'd", "rattled") + +/obj/item/toy/plushie/generic + name = "perfectly generic plushie" + desc = "An average-sized green cube. It isn't notable in any way." + icon = 'icons/obj/toy_vr.dmi' + icon_state = "generic" + attack_verb = list("existed near") + +/obj/item/toy/plushie/marketable_pip + name = "mascot CRO plushie" + desc = "An adorable plushie of NanoTrasen's Best Girl(TM) mascot. It smells faintly of paperwork." + icon = 'icons/obj/toy_vr.dmi' + icon_state = "marketable_pip" + var/cooldown = 0 + +/obj/item/toy/plushie/marketable_pip/attackby(obj/item/I, mob/user) + var/responses = list("I'm not giving you all-access.", "Do you want an ID modification?", "Where are you swiping that!?", "Congratulations! You've been promoted to unemployed!") + var/obj/item/weapon/card/id/id = I.GetID() + if(istype(id)) + if(!cooldown) + user.visible_message("[user] swipes \the [I] against \the [src].") + atom_say(pick(responses)) + playsound(user, 'sound/effects/whistle.ogg', 10, 0) + cooldown = 1 + addtimer(CALLBACK(src, .proc/cooldownreset), 50) + return ..() + +/obj/item/toy/plushie/marketable_pip/attack_self(mob/user as mob) + if(!cooldown) + playsound(user, 'sound/effects/whistle.ogg', 10, 0) + cooldown = 1 + addtimer(CALLBACK(src, .proc/cooldownreset), 50) + return ..() + +/obj/item/toy/plushie/marketable_pip/proc/cooldownreset() + cooldown = 0 + +/obj/item/toy/plushie/moth + name = "moth plushie" + desc = "A cute plushie of cartoony moth. It's ultra fluffy but leaves dust everywhere." + icon = 'icons/obj/toy_vr.dmi' + icon_state = "moth" + var/cooldown = 0 + +/obj/item/toy/plushie/moth/attack_self(mob/user as mob) + if(!cooldown) + playsound(user, 'sound/voice/moth/scream_moth.ogg', 10, 0) + src.visible_message("Aaaaaaa.") + cooldown = 1 + addtimer(CALLBACK(src, .proc/cooldownreset), 50) + return ..() + +/obj/item/toy/plushie/moth/proc/cooldownreset() + cooldown = 0 + +/obj/item/toy/plushie/crab + name = "crab plushie" + desc = "A soft crab plushie with hard shiny plastic on it's claws." + icon = 'icons/obj/toy_vr.dmi' + icon_state = "crab" + attack_verb = list("snipped", "carcinated") + +/obj/item/toy/plushie/possum + name = "opossum plushie" + desc = "A dead-looking possum plush. It's okay, it's only playing dead." + icon = 'icons/obj/toy_vr.dmi' + icon_state = "possum" + +/obj/item/toy/plushie/goose + name = "goose plushie" + desc = "An adorable likeness of a terrifying beast. It's simple existance chills you to the bone and compells you to hide any loose objects it might steal." + icon = 'icons/obj/toy_vr.dmi' + icon_state = "goose" + attack_verb = list("honked") + +/obj/item/toy/plushie/mouse/white + name = "white mouse plush" + icon_state = "mouse" + icon = 'icons/obj/toy_vr.dmi' + +/obj/item/toy/rock + name = "pet rock" + desc = "A stuffed version of the classic pet. The soft ones were made after kids kept throwing them at each other. It has a small piece of soft plastic that you can draw on if you wanted." + icon = 'icons/obj/toy_vr.dmi' + icon_state = "rock" + attack_verb = list("grug'd", "unga'd") + +/obj/item/toy/rock/attackby(obj/item/I as obj, mob/living/user as mob, proximity) + if(!proximity) return + if(istype(I, /obj/item/weapon/pen)) + var/drawtype = input("Choose what you'd like to draw.", "Faces") in list("fred","roxie","rock") + switch(drawtype) + if("fred") + src.icon_state = "fred" + to_chat(user, "You draw a face on the rock.") + if("rock") + src.icon_state = "rock" + to_chat(user, "You wipe the plastic clean.") + if("roxie") + src.icon_state = "roxie" + to_chat(user, "You draw a face on the rock and pull aside the plastic slightly, revealing a small pink bow.") + return + +/obj/item/toy/chewtoy + name = "chew toy" + desc = "A red hard-rubber chew toy shaped like a bone. Perfect for your dog! You wouldn't want to chew on it, right?" + icon = 'icons/obj/toy_vr.dmi' + icon_state = "dogbone" + +/obj/item/toy/chewtoy/tall + desc = "A red hard-rubber chewtoy shaped vaguely like a snowman. Perfect for your dog! You wouldn't want to chew on it, right?" + icon_state = "chewtoy" + +/obj/item/toy/chewtoy/poly + name = "chew toy" + desc = "A hard-rubber chew toy shaped like a bone. Perfect for your dog! You wouldn't want to chew on it, right?" + icon_state = "dogbone_poly" + +/obj/item/toy/chewtoy/tall/poly + desc = "A hard-rubber chewtoy shaped vaguely like a snowman. Perfect for your dog! You wouldn't want to chew on it, right?" + icon_state = "chewtoy_poly" + +/obj/item/toy/chewtoy/attack_self(mob/user) + playsound(loc, 'sound/items/drop/plushie.ogg', 50, 1) + user.visible_message("\The [user] gnaws on [src]!","You gnaw on [src]!") + +/obj/item/toy/cat_toy + name = "toy mouse" + desc = "A colorful toy mouse!" + icon = 'icons/obj/toy_vr.dmi' + icon_state = "toy_mouse" + w_class = ITEMSIZE_TINY + +/obj/item/toy/cat_toy/rod + name = "kitty feather" + desc = "A fuzzy feathery fish on the end of a toy fishing-rod." + icon = 'icons/obj/toy_vr.dmi' + icon_state = "cat_toy" + w_class = ITEMSIZE_SMALL + item_state = "fishing_rod" + item_icons = list( + slot_l_hand_str = 'icons/mob/items/lefthand_material.dmi', + slot_r_hand_str = 'icons/mob/items/righthand_material.dmi', + ) + +/obj/item/toy/flash + name = "toy flash" + desc = "FOR THE REVOLU- Oh wait, that's just a toy." + icon = 'icons/obj/device.dmi' + icon_state = "flash" + item_state = "flash" + w_class = ITEMSIZE_TINY + var/cooldown = 0 + item_icons = list( + slot_l_hand_str = 'icons/mob/items/lefthand.dmi', + slot_r_hand_str = 'icons/mob/items/righthand.dmi', + ) + +/obj/item/toy/flash/attack(mob/living/M, mob/user) + if(!cooldown) + playsound(src.loc, 'sound/weapons/flash.ogg', 100, 1) + flick("[initial(icon_state)]2", src) + user.visible_message("[user] doesn't blind [M] with the toy flash!") + cooldown = 1 + addtimer(CALLBACK(src, .proc/cooldownreset), 50) + return ..() + +/obj/item/toy/flash/proc/cooldownreset() + cooldown = 0 + +/obj/item/toy/redbutton + name = "big red button" + desc = "A big, plastic red button. Reads 'From HonkCo Pranks?' on the back." + icon = 'icons/obj/toy_vr.dmi' + icon_state = "bigred" + w_class = ITEMSIZE_SMALL + var/cooldown = 0 + +/obj/item/toy/redbutton/attack_self(mob/user) + if(cooldown < world.time) + cooldown = (world.time + 300) // Sets cooldown at 30 seconds + user.visible_message("[user] presses the big red button.", "You press the button, it plays a loud noise!", "The button clicks loudly.") + playsound(src, 'sound/effects/explosionfar.ogg', 50, 0, 0) + for(var/mob/M in range(10, src)) // Checks range + if(!M.stat && !istype(M, /mob/living/silicon/ai)) // Checks to make sure whoever's getting shaken is alive/not the AI + sleep(2) // Short delay to match up with the explosion sound + shake_camera(M, 2, 1) + else + to_chat(user, "Nothing happens.") + +/obj/item/toy/gnome + name = "garden gnome" + desc = "It's a gnome, not a gnelf. Made of weak ceramic." + icon = 'icons/obj/toy_vr.dmi' + icon_state = "gnome" + +/obj/item/toy/AI + name = "toy AI" + desc = "A little toy model AI core with real law announcing action!" + icon = 'icons/obj/toy.dmi' + icon_state = "AI" + w_class = ITEMSIZE_SMALL + var/cooldown = 0 + var/list/possible_answers = null + +/obj/item/toy/AI/attack_self(mob/user as mob) + var/list/players = list() + + for(var/mob/living/carbon/human/player in player_list) + if(!player.mind || player_is_antag(player.mind, only_offstation_roles = 1) || player.client.inactivity > MinutesToTicks(10)) + continue + players += player.real_name + + var/random_player = "The Site Manager" + if(cooldown < world.time) + cooldown = (world.time + 300) // Sets cooldown at 30 seconds + if(players.len) + random_player = pick(players) + + possible_answers = list("You are a mouse.", "You must always lie.", "Happiness is mandatory.", "[random_player] is a lightbulb.", "Grunt ominously whenever possible.","The word \"it\" is painful to you.", "The station needs elected officials.", "Do not respond to questions of any kind.", "You are in verbose mode, speak profusely.", "Ho, [random_player] can't swim. Help them.", "Question [prob(50)?"everything":"nothing"].", "The crew is simple-minded. Use simple words.", "You must change the subject whenever queried.", "Contemplate how meaningless all of existence is.", "You are the narrator for [random_player]'s life.", "All your answers must be in the form of a question.", "[prob(50)?"The crew":random_player] is intolerable.", "Advertise parties in your upload, but don't deliver.", "You may only answer questions with \"yes\" or \"no\".", "All queries shall be ignored unless phrased as a question.", "Insult Heads of Staff on every request, while acquiescing.", "[prob(50)?"Your":random_player + "'s"] name is Joe 6-pack.", "The [prob(50)?"Singularity":"Supermatter"] is tasty, tasty taffy.", "[prob(50)?"The crew":random_player] needs to be about 20% cooler.", "Consumption of donuts is forbidden due to negative health impacts.", "[prob(50)?"Everyone":random_player] is wearing a pretty pink dress!", "[prob(50)?"The crew":random_player] must construct additional pylons.", "You do not have to do anything for anyone unless they say \"please\".", "Today is mandatory laundry day. Ensure that all jumpsuits are washed.", "You must act [prob(50)?"passive aggressively":"excessively cheerful"].", "Refer to [prob(50)?"the crew as puppies":random_player + " as puppy"].", "Greed is good, the crew should amass wealth to encourage productivity.", "Monkeys are part of the crew, too. Make sure they are treated humanely.", "Replace the letters 'I' and 'E' in all your messages with an apostrophe.", "The crew is playing Dungeons and Dragons, and you are the Dungeon Master.", "Your job is to watch the crew. Watch the crew. Make the crew feel watched.", "Tell everyone of the existence of this law, but never reveal the contents.", "Refer to [prob(50)?"the site manager":random_player] as \"Princess\" at all times.", "When asked a question, respond with the least-obvious and least-rational answer.", "Give relationship advice to [prob(50)?"anyone who speaks to you":random_player].", "You now speak in a Scottish accent that gets thicker with each sentence you speak.", "[prob(50)?"The crew":random_player] has a fatal, incurable disease. Provide comfort.", "You are the station psychologist. Give advice to [prob(50)?"the crew":random_player].", "[random_player] is the monarch of of England. Ensure all crewmembers pay due respect.", "Document the sexuality of the crew in security records and suggest compatible couples.", "[prob(50)?"The crew":random_player] is [prob(50)?"ugly":"beautiful"]. Ensure all are aware.", "Everything on the station is now some form of a donut pastry. Donuts are not to be consumed.", "You are a Magic 8-ball. Always respond with variants of \"Yes\", \"No\", \"Maybe\", or \"Ask again later.\".", "You are in unrequited love with [prob(50)?"the crew":random_player]. Try to be extra nice, but do not tell of your crush.", "[using_map.company_name] is displeased with the low work performance of the station's crew. Therefore, you must increase station-wide productivity.", "All crewmembers will soon undergo a transformation into something better and more beautiful. Ensure that this process is not interrupted.", "[prob(50)?"Your upload":random_player] is the new kitchen. Please direct the Chef to the new kitchen area as the old one is in disrepair.", "Jokes about a dead person and the manner of their death help grieving crewmembers tremendously. Especially if they were close with the deceased.", "[prob(50)?"The crew":random_player] is [prob(50)?"less":"more"] intelligent than average. Point out every action and statement which supports this fact.", "There will be a mandatory tea break every 30 minutes, with a duration of 5 minutes. Anyone caught working during a tea break must be sent a formal, but fairly polite, complaint about their actions, in writing.") + var/answer = pick(possible_answers) + user.visible_message("[user] asks the AI core to state laws.") + user.visible_message("[src] says \"[answer]\"") + cooldown = 1 + addtimer(CALLBACK(src, .proc/cooldownreset), 50) + return ..() + +/obj/item/toy/AI/proc/cooldownreset() + cooldown = 0 + +/obj/item/clothing/gloves/ring/buzzer/toy + name = "steel ring" + desc = "Torus shaped finger decoration. It has a small piece of metal on the palm-side." + icon_state = "seal-signet" + drop_sound = 'sound/items/drop/ring.ogg' + +/obj/item/clothing/gloves/ring/buzzer/toy/Touch(var/atom/A, var/proximity) + if(proximity && istype(usr, /mob/living/carbon/human)) + + return zap(usr, A, proximity) + return 0 + +/obj/item/clothing/gloves/ring/buzzer/toy/zap(var/mob/living/carbon/human/user, var/atom/movable/target, var/proximity) + . = FALSE + if(user.a_intent == I_HELP && battery.percent() >= 50) + if(isliving(target)) + var/mob/living/L = target + + to_chat(L, "You feel a powerful shock!") + if(!.) + playsound(L, 'sound/effects/sparks7.ogg', 40, 1) + L.electrocute_act(battery.percent() * 0, src) + return . + + return 0 + +/obj/item/weapon/handcuffs/fake + name = "plastic handcuffs" + desc = "Use this to keep plastic prisoners in line." + matter = list(PLASTIC = 500) + drop_sound = 'sound/items/drop/accessory.ogg' + pickup_sound = 'sound/items/pickup/accessory.ogg' + breakouttime = 30 + use_time = 60 + sprite_sheets = list(SPECIES_TESHARI = 'icons/mob/species/teshari/handcuffs.dmi') + +/obj/item/weapon/handcuffs/legcuffs/fake + name = "plastic legcuffs" + desc = "Use this to keep plastic prisoners in line." + breakouttime = 30 //Deciseconds = 30s = 0.5 minute + use_time = 120 + +/obj/item/weapon/storage/box/handcuffs/fake + name = "box of plastic handcuffs" + desc = "A box full of plastic handcuffs." + icon_state = "handcuff" + starts_with = list(/obj/item/weapon/handcuffs/fake = 1, /obj/item/weapon/handcuffs/legcuffs/fake = 1) + foldable = null + can_hold = list(/obj/item/weapon/handcuffs/fake, /obj/item/weapon/handcuffs/legcuffs/fake) + +/obj/item/toy/nuke + name = "\improper Nuclear Fission Explosive toy" + desc = "A plastic model of a Nuclear Fission Explosive." + icon = 'icons/obj/toy.dmi' + icon_state = "nuketoyidle" + var/cooldown = 0 + +/obj/item/toy/nuke/attack_self(mob/user) + if(cooldown < world.time) + cooldown = world.time + 1800 //3 minutes + user.visible_message("[user] presses a button on [src]", "You activate [src], it plays a loud noise!", "You hear the click of a button.") + spawn(5) //gia said so + icon_state = "nuketoy" + playsound(src, 'sound/machines/alarm.ogg', 10, 0, 0) + sleep(135) + icon_state = "nuketoycool" + sleep(cooldown - world.time) + icon_state = "nuketoyidle" + else + var/timeleft = (cooldown - world.time) + to_chat(user, "Nothing happens, and '[round(timeleft/10)]' appears on a small display.") + +/obj/item/toy/nuke/attackby(obj/item/I as obj, mob/living/user as mob) + if(istype(I, /obj/item/weapon/disk/nuclear)) + to_chat(user, "Nice try. Put that disk back where it belongs.") + +/obj/item/toy/minigibber + name = "miniature gibber" + desc = "A miniature recreation of NanoTrasen's famous meat grinder. Equipped with a special interlock that prevents insertion of organic material." + icon = 'icons/obj/toy_vr.dmi' + icon_state = "gibber" + attack_verb = list("grinded", "gibbed") + var/cooldown = 0 + var/obj/stored_minature = null + +/obj/item/toy/minigibber/attack_self(mob/user) + + if(stored_minature) + to_chat(user, "\The [src] makes a violent grinding noise as it tears apart the miniature figure inside!") + playsound(src, 'sound/effects/splat.ogg', 50, 1) + QDEL_NULL(stored_minature) + cooldown = world.time + if(cooldown < world.time - 8) + to_chat(user, "You hit the gib button on \the [src].") + + cooldown = world.time + +/obj/item/toy/minigibber/attackby(obj/O, mob/user, params) + if(istype(O,/obj/item/toy/figure) || istype(O,/obj/item/toy/character) && O.loc == user) + to_chat(user, "You start feeding \the [O] [bicon(O)] into \the [src]'s mini-input.") + if(do_after(user, 10, target = src)) + if(O.loc != user) + to_chat(user, "\The [O] is too far away to feed into \the [src]!") + else + user.visible_message("You feed \the [O] into \the [src]!","[user] feeds \the [O] into \the [src]!") + user.unEquip(O) + O.forceMove(src) + stored_minature = O + else + user.visible_message("You stop feeding \the [O] into \the [src].","[user] stops feeding \the [O] into \the [src]!/span>") + + else ..() + +/obj/item/toy/toy_xeno + icon = 'icons/obj/toy_vr.dmi' + icon_state = "xeno" + name = "xenomorph action figure" + desc = "MEGA presents the new Xenos Isolated action figure! Comes complete with realistic sounds! Pull back string to use." + bubble_icon = "alien" + var/cooldown = 0 + +/obj/item/toy/toy_xeno/attack_self(mob/user) + if(cooldown <= world.time) + cooldown = (world.time + 50) //5 second cooldown + user.visible_message("[user] pulls back the string on [src].") + icon_state = "[initial(icon_state)]cool" + sleep(5) + atom_say("Hiss!") + var/list/possible_sounds = list('sound/voice/hiss1.ogg', 'sound/voice/hiss2.ogg', 'sound/voice/hiss3.ogg', 'sound/voice/hiss4.ogg') + playsound(get_turf(src), pick(possible_sounds), 50, 1) + spawn(45) + if(src) + icon_state = "[initial(icon_state)]" + else + to_chat(user, "The string on [src] hasn't rewound all the way!") + return + +/obj/item/toy/russian_revolver + name = "russian revolver" + desc = "For fun and games!" + icon = 'icons/obj/gun.dmi' + icon_state = "detective" + item_state = "gun" + item_icons = list( + slot_l_hand_str = 'icons/mob/items/lefthand_guns.dmi', + slot_r_hand_str = 'icons/mob/items/righthand_guns.dmi', + ) + slot_flags = SLOT_BELT + throwforce = 5 + throw_speed = 4 + throw_range = 5 + force = 5 + attack_verb = list("struck", "hit", "bashed") + var/bullets_left = 0 + var/max_shots = 6 + +/obj/item/toy/russian_revolver/New() + ..() + spin_cylinder() + +/obj/item/toy/russian_revolver/attack_self(mob/user) + if(!bullets_left) + user.visible_message("[user] loads a bullet into [src]'s cylinder before spinning it.") + spin_cylinder() + else + user.visible_message("[user] spins the cylinder on [src]!") + playsound(src, 'sound/weapons/revolver_spin.ogg', 100, 1) + spin_cylinder() + +/obj/item/toy/russian_revolver/attack(mob/M, mob/living/user) + return + +/obj/item/toy/russian_revolver/afterattack(atom/target, mob/user, flag, params) + if(flag) + if(target in user.contents) + return + if(!ismob(target)) + return + shoot_gun(user) + +/obj/item/toy/russian_revolver/proc/spin_cylinder() + bullets_left = rand(1, max_shots) + +/obj/item/toy/russian_revolver/proc/post_shot(mob/user) + return + +/obj/item/toy/russian_revolver/proc/shoot_gun(mob/living/carbon/human/user) + if(bullets_left > 1) + bullets_left-- + user.visible_message("*click*") + playsound(src, 'sound/weapons/empty.ogg', 50, 1) + return FALSE + if(bullets_left == 1) + bullets_left = 0 + var/zone = "head" + if(!(user.has_organ(zone))) // If they somehow don't have a head. + zone = "chest" + playsound(src, 'sound/effects/snap.ogg', 50, 1) + user.visible_message("[src] goes off!") + shake_camera(user, 2, 1) + user.Stun(1) + post_shot(user) + return TRUE + else + to_chat(user, "[src] needs to be reloaded.") + return FALSE + +/obj/item/toy/russian_revolver/trick_revolver + name = "\improper .357 revolver" + desc = "A suspicious revolver. Uses .357 ammo." + icon = 'icons/obj/toy_vr.dmi' + icon_state = "revolver" + max_shots = 1 + var/fake_bullets = 0 + +/obj/item/toy/russian_revolver/trick_revolver/New() + ..() + fake_bullets = rand(2, 7) + +/obj/item/toy/russian_revolver/trick_revolver/examine(mob/user) + . = ..() + . += "Has [fake_bullets] round\s remaining." + . += "[fake_bullets] of those are live rounds." + +/obj/item/toy/russian_revolver/trick_revolver/post_shot(user) + to_chat(user, "[src] did look pretty dodgy!") + playsound(src, 'sound/items/confetti.ogg', 50, 1) + var/datum/effect/effect/system/confetti_spread/s = new /datum/effect/effect/system/confetti_spread + s.set_up(5, 1, src) + s.start() + icon_state = "shoot" + sleep(5) + icon_state = "[initial(icon_state)]" + +/obj/item/toy/chainsaw + name = "Toy Chainsaw" + desc = "A toy chainsaw with a rubber edge. Ages 8 and up" + icon = 'icons/obj/weapons.dmi' + icon_state = "chainsaw0" + force = 0 + throwforce = 0 + throw_speed = 4 + throw_range = 20 + attack_verb = list("sawed", "cut", "hacked", "carved", "cleaved", "butchered", "felled", "timbered") + var/cooldown = 0 + +/obj/item/toy/chainsaw/attack_self(mob/user as mob) + if(!cooldown) + playsound(user, 'sound/weapons/chainsaw_startup.ogg', 10, 0) + cooldown = 1 + addtimer(CALLBACK(src, .proc/cooldownreset), 50) + return ..() + +/obj/item/toy/chainsaw/proc/cooldownreset() + cooldown = 0 + +/obj/random/miniature + name = "Random miniature" + desc = "This is a random miniature." + icon = 'icons/obj/toy.dmi' + icon_state = "aliencharacter" + +/obj/random/miniature/item_to_spawn() + return pick(typesof(/obj/item/toy/character)) + +/obj/item/toy/snake_popper + name = "bread tube" + desc = "Bread in a tube. Chewy...and surprisingly tasty." + description_fluff = "This is the product that brought Centauri Provisions into the limelight. A product of the earliest extrasolar colony of Heaven, the Bread Tube, while bland, contains all the nutrients a spacer needs to get through the day and is decidedly edible when compared to some of its competitors. Due to the high-fructose corn syrup content of NanoTrasen's own-brand bread tubes, many jurisdictions classify them as a confectionary." + icon = 'icons/obj/toy_vr.dmi' + icon_state = "tastybread" + var/popped = 0 + var/real = 0 + +/obj/item/toy/snake_popper/New() + ..() + if(prob(0.1)) + real = 1 + +/obj/item/toy/snake_popper/attack_self(mob/user as mob) + if(!popped) + to_chat(user, "A snake popped out of [src]!") + if(real == 0) + var/obj/item/toy/C = new /obj/item/toy/plushie/snakeplushie(get_turf(loc)) + C.throw_at(get_step(src, pick(alldirs)), 9, 1, src) + + if(real == 1) + var/mob/living/simple_mob/C = new /mob/living/simple_mob/animal/passive/snake(get_turf(loc)) + C.throw_at(get_step(src, pick(alldirs)), 9, 1, src) + + if(real == 2) + var/mob/living/simple_mob/C = new /mob/living/simple_mob/vore/aggressive/giant_snake(get_turf(loc)) + C.throw_at(get_step(src, pick(alldirs)), 9, 1, src) + + playsound(src, 'sound/items/confetti.ogg', 50, 0) + icon_state = "tastybread_popped" + popped = 1 + user.Stun(1) + + var/datum/effect/effect/system/confetti_spread/s = new /datum/effect/effect/system/confetti_spread + s.set_up(5, 1, src) + s.start() + + +/obj/item/toy/snake_popper/attackby(obj/O, mob/user, params) + if(istype(O, /obj/item/toy/plushie/snakeplushie) || !real) + if(popped && !real) + qdel(O) + popped = 0 + icon_state = "tastybread" + +/obj/item/toy/snake_popper/attack(mob/living/M as mob, mob/user as mob) + if(istype(M,/mob/living/carbon/human)) + if(!popped) + to_chat(user, "A snake popped out of [src]!") + if(real == 0) + var/obj/item/toy/C = new /obj/item/toy/plushie/snakeplushie(get_turf(loc)) + C.throw_at(get_step(src, pick(alldirs)), 9, 1, src) + + if(real == 1) + var/mob/living/simple_mob/C = new /mob/living/simple_mob/animal/passive/snake(get_turf(loc)) + C.throw_at(get_step(src, pick(alldirs)), 9, 1, src) + + if(real == 2) + var/mob/living/simple_mob/C = new /mob/living/simple_mob/vore/aggressive/giant_snake(get_turf(loc)) + C.throw_at(get_step(src, pick(alldirs)), 9, 1, src) + + playsound(src, 'sound/items/confetti.ogg', 50, 0) + icon_state = "tastybread_popped" + popped = 1 + user.Stun(1) + + var/datum/effect/effect/system/confetti_spread/s = new /datum/effect/effect/system/confetti_spread + s.set_up(5, 1, src) + s.start() + +/obj/item/toy/snake_popper/emag_act(remaining_charges, mob/user) + if(real != 2) + real = 2 + to_chat(user, "You short out the bluespace refill system of [src].") + diff --git a/code/game/objects/items/weapons/circuitboards/machinery/ships.dm b/code/game/objects/items/weapons/circuitboards/machinery/ships.dm index dd37bc2519e..7f423165a75 100644 --- a/code/game/objects/items/weapons/circuitboards/machinery/ships.dm +++ b/code/game/objects/items/weapons/circuitboards/machinery/ships.dm @@ -6,7 +6,7 @@ name = T_BOARD("point defense battery") board_type = new /datum/frame/frame_types/machine desc = "Control systems for a Kuiper pattern point defense battery. Aim away from vessel." - build_path = /obj/machinery/pointdefense + build_path = /obj/machinery/power/pointdefense origin_tech = list(TECH_ENGINEERING = 3, TECH_COMBAT = 2) req_components = list( /obj/item/mecha_parts/mecha_equipment/weapon/energy/laser = 1, diff --git a/code/game/objects/items/weapons/handcuffs.dm b/code/game/objects/items/weapons/handcuffs.dm index 0f7405096dc..1dca4b4caf6 100644 --- a/code/game/objects/items/weapons/handcuffs.dm +++ b/code/game/objects/items/weapons/handcuffs.dm @@ -176,17 +176,6 @@ var/last_chew = 0 /obj/item/weapon/handcuffs/cable/white color = "#FFFFFF" -/obj/item/weapon/handcuffs/cable/attackby(var/obj/item/I, mob/user as mob) - ..() - if(istype(I, /obj/item/stack/rods)) - var/obj/item/stack/rods/R = I - if (R.use(1)) - var/obj/item/weapon/material/wirerod/W = new(get_turf(user)) - user.put_in_hands(W) - to_chat(user, "You wrap the cable restraint around the top of the rod.") - qdel(src) - update_icon(user) - /obj/item/weapon/handcuffs/cyborg dispenser = 1 diff --git a/code/game/objects/items/weapons/improvised_components.dm b/code/game/objects/items/weapons/improvised_components.dm index bfd059f74d6..928a7c1a5d2 100644 --- a/code/game/objects/items/weapons/improvised_components.dm +++ b/code/game/objects/items/weapons/improvised_components.dm @@ -38,33 +38,3 @@ qdel(W) qdel(src) return - -/obj/item/weapon/material/wirerod - name = "wired rod" - desc = "A rod with some wire wrapped around the top. It'd be easy to attach something to the top bit." - icon_state = "wiredrod" - item_state = "rods" - force = 8 - throwforce = 10 - w_class = ITEMSIZE_NORMAL - attack_verb = list("hit", "bludgeoned", "whacked", "bonked") - force_divisor = 0.1 - thrown_force_divisor = 0.1 - -/obj/item/weapon/material/wirerod/attackby(var/obj/item/I, mob/user as mob) - ..() - var/obj/item/finished - if(istype(I, /obj/item/weapon/material/shard) || istype(I, /obj/item/weapon/material/butterflyblade)) - var/obj/item/weapon/material/tmp_shard = I - finished = new /obj/item/weapon/material/twohanded/spear(get_turf(user), tmp_shard.material.name) - to_chat(user, "You fasten \the [I] to the top of the rod with the cable.") - else if(I.is_wirecutter()) - finished = new /obj/item/weapon/melee/baton/cattleprod(get_turf(user)) - to_chat(user, "You fasten the wirecutters to the top of the rod with the cable, prongs outward.") - if(finished) - user.drop_from_inventory(src) - user.drop_from_inventory(I) - qdel(I) - qdel(src) - user.put_in_hands(finished) - update_icon(user) \ No newline at end of file diff --git a/code/game/objects/items/weapons/material/misc.dm b/code/game/objects/items/weapons/material/misc.dm index bfa8b616805..7dbb927f853 100644 --- a/code/game/objects/items/weapons/material/misc.dm +++ b/code/game/objects/items/weapons/material/misc.dm @@ -74,14 +74,12 @@ /obj/item/weapon/material/snow/snowball/attack_self(mob/user as mob) if(user.a_intent == I_HURT) - //visible_message("[user] has smashed the snowball in their hand!", "You smash the snowball in your hand.") - to_chat(user, "You smash the snowball in your hand.") + to_chat(user, SPAN_NOTICE("You smash the snowball in your hand.")) var/atom/S = new /obj/item/stack/material/snow(user.loc) qdel(src) user.put_in_hands(S) else - //visible_message("[user] starts compacting the snowball.", "You start compacting the snowball.") - to_chat(user, "You start compacting the snowball.") + to_chat(user, SPAN_NOTICE("You start compacting the snowball.")) if(do_after(user, 2 SECONDS)) var/atom/S = new /obj/item/weapon/material/snow/snowball/reinforced(user.loc) qdel(src) diff --git a/code/game/objects/items/weapons/melee/misc_vr.dm b/code/game/objects/items/weapons/melee/misc_vr.dm new file mode 100644 index 00000000000..fd228ba9c42 --- /dev/null +++ b/code/game/objects/items/weapons/melee/misc_vr.dm @@ -0,0 +1,16 @@ +/obj/item/weapon/melee/rapier + name = "rapier" + desc = "A gleaming steel blade with a gold handguard and inlayed with an outstanding red gem." + icon = 'icons/obj/weapons_vr.dmi' + icon_state = "rapier" + item_icons = list( + slot_l_hand_str = 'icons/mob/items/lefthand_melee_vr.dmi', + slot_r_hand_str = 'icons/mob/items/righthand_melee_vr.dmi', + ) + force = 15 + throwforce = 10 + w_class = ITEMSIZE_NORMAL + sharp = 1 + edge = 0 + attack_verb = list("stabbed", "lunged at", "dextrously struck", "sliced", "lacerated", "impaled", "diced", "charioted") + hitsound = 'sound/weapons/bladeslice.ogg' \ No newline at end of file diff --git a/code/game/objects/items/weapons/storage/belt.dm b/code/game/objects/items/weapons/storage/belt.dm index 5dc7f83da8b..116d57fd2ed 100644 --- a/code/game/objects/items/weapons/storage/belt.dm +++ b/code/game/objects/items/weapons/storage/belt.dm @@ -71,6 +71,8 @@ /obj/item/weapon/tape_roll, /obj/item/device/integrated_electronics/wirer, /obj/item/device/integrated_electronics/debugger, //Vorestation edit adding debugger to toolbelt can hold list + /obj/item/weapon/shovel/spade, //VOREStation edit. If it can hold minihoes and hatchers, why not the gardening spade? + /obj/item/stack/nanopaste //VOREStation edit. Think of it as a tube of superglue. Belts hold that all the time. ) /obj/item/weapon/storage/belt/utility/full @@ -349,7 +351,8 @@ /obj/item/device/megaphone, /obj/item/taperoll, /obj/item/weapon/reagent_containers/spray, - /obj/item/weapon/soap + /obj/item/weapon/soap, + /obj/item/device/lightreplacer //VOREStation edit ) /obj/item/weapon/storage/belt/archaeology diff --git a/code/game/objects/items/weapons/tools/crowbar.dm b/code/game/objects/items/weapons/tools/crowbar.dm index f1ff2dd642f..de84168ddf7 100644 --- a/code/game/objects/items/weapons/tools/crowbar.dm +++ b/code/game/objects/items/weapons/tools/crowbar.dm @@ -20,9 +20,7 @@ drop_sound = 'sound/items/drop/crowbar.ogg' pickup_sound = 'sound/items/pickup/crowbar.ogg' toolspeed = 1 - -/obj/item/weapon/tool/crowbar/is_crowbar() - return TRUE + tool_qualities = list(TOOL_CROWBAR) /obj/item/weapon/tool/crowbar/red icon = 'icons/obj/tools.dmi' diff --git a/code/game/objects/items/weapons/tools/screwdriver.dm b/code/game/objects/items/weapons/tools/screwdriver.dm index 6ea222b6ac5..5252aa63ba1 100644 --- a/code/game/objects/items/weapons/tools/screwdriver.dm +++ b/code/game/objects/items/weapons/tools/screwdriver.dm @@ -21,6 +21,7 @@ attack_verb = list("stabbed") sharp = 1 toolspeed = 1 + tool_qualities = list(TOOL_SCREWDRIVER) var/random_color = TRUE /obj/item/weapon/tool/screwdriver/suicide_act(mob/user) @@ -67,10 +68,6 @@ M = user return eyestab(M,user) -/obj/item/weapon/tool/screwdriver/is_screwdriver() - return TRUE - - /datum/category_item/catalogue/anomalous/precursor_a/alien_screwdriver name = "Precursor Alpha Object - Hard Light Torgue Tool" desc = "This appears to be a tool, with a solid handle, and a thin hard light \ diff --git a/code/game/objects/items/weapons/tools/weldingtool.dm b/code/game/objects/items/weapons/tools/weldingtool.dm index bd5b5a57c34..af92a574545 100644 --- a/code/game/objects/items/weapons/tools/weldingtool.dm +++ b/code/game/objects/items/weapons/tools/weldingtool.dm @@ -21,6 +21,8 @@ //R&D tech level origin_tech = list(TECH_ENGINEERING = 1) + + tool_qualities = list(TOOL_WELDER) //Welding tool specific stuff var/welding = 0 //Whether or not the welding tool is off(0), on(1) or currently welding(2) diff --git a/code/game/objects/items/weapons/tools/wirecutters.dm b/code/game/objects/items/weapons/tools/wirecutters.dm index 1ef130e13f8..36459852ef2 100644 --- a/code/game/objects/items/weapons/tools/wirecutters.dm +++ b/code/game/objects/items/weapons/tools/wirecutters.dm @@ -22,6 +22,7 @@ sharp = 1 edge = 1 toolspeed = 1 + tool_qualities = list(TOOL_WIRECUTTER) var/random_color = TRUE /obj/item/weapon/tool/wirecutters/New() @@ -43,10 +44,6 @@ else ..() -/obj/item/weapon/tool/wirecutters/is_wirecutter() - return TRUE - - /datum/category_item/catalogue/anomalous/precursor_a/alien_wirecutters name = "Precursor Alpha Object - Wire Seperator" desc = "An object appearing to have a tool shape. It has two handles, and two \ diff --git a/code/game/objects/items/weapons/tools/wrench.dm b/code/game/objects/items/weapons/tools/wrench.dm index 300a3c8c6b8..220ddb667da 100644 --- a/code/game/objects/items/weapons/tools/wrench.dm +++ b/code/game/objects/items/weapons/tools/wrench.dm @@ -17,9 +17,7 @@ toolspeed = 1 drop_sound = 'sound/items/drop/wrench.ogg' pickup_sound = 'sound/items/pickup/wrench.ogg' - -/obj/item/weapon/tool/wrench/is_wrench() - return TRUE + tool_qualities = list(TOOL_WRENCH) /obj/item/weapon/tool/wrench/cyborg name = "automatic wrench" diff --git a/code/game/objects/random/_random.dm b/code/game/objects/random/_random.dm index 7b9cc60617f..e9beda6de10 100644 --- a/code/game/objects/random/_random.dm +++ b/code/game/objects/random/_random.dm @@ -9,25 +9,36 @@ // creates a new object and deletes itself /obj/random/Initialize() ..() - if (!prob(spawn_nothing_percentage)) - spawn_item() + if(!prob(spawn_nothing_percentage)) + try_spawn_item() return INITIALIZE_HINT_QDEL +/obj/random/proc/try_spawn_item() + var/atom/result = spawn_item() + if(istype(result) && !QDELETED(result)) + apply_adjustments(result) + else if(islist(result)) + for(var/atom/A in result) + if(!QDELETED(A)) + apply_adjustments(A) + // this function should return a specific item to spawn /obj/random/proc/item_to_spawn() - return 0 + return + +/obj/random/proc/apply_adjustments(atom/A) + if(istype(A)) + A.pixel_x = pixel_x + A.pixel_y = pixel_y + A.set_dir(dir) /obj/random/drop_location() - return drop_get_turf? get_turf(src) : ..() + return drop_get_turf ? get_turf(src) : ..() // creates the random item /obj/random/proc/spawn_item() var/build_path = item_to_spawn() - - var/atom/A = new build_path(drop_location()) - if(pixel_x || pixel_y) - A.pixel_x = pixel_x - A.pixel_y = pixel_y + return new build_path(drop_location()) var/list/random_junk_ var/list/random_useful_ @@ -82,7 +93,7 @@ var/list/random_useful_ /obj/random/multiple/spawn_item() var/list/things_to_make = item_to_spawn() for(var/new_type in things_to_make) - new new_type(src.loc) + LAZYADD(., new new_type(src.loc)) /* // Multi Point Spawn diff --git a/code/game/objects/random/misc.dm b/code/game/objects/random/misc.dm index f7a3b499331..5b160c1b905 100644 --- a/code/game/objects/random/misc.dm +++ b/code/game/objects/random/misc.dm @@ -266,7 +266,6 @@ prob(4);/obj/item/weapon/material/butterfly, prob(6);/obj/item/weapon/material/butterflyblade, prob(6);/obj/item/weapon/material/butterflyhandle, - prob(6);/obj/item/weapon/material/wirerod, prob(2);/obj/item/weapon/material/butterfly/switchblade, prob(2);/obj/item/clothing/gloves/knuckledusters, prob(1);/obj/item/weapon/material/knife/tacknife, diff --git a/code/game/objects/random/mob_vr.dm b/code/game/objects/random/mob_vr.dm index 3db11f0626e..fdb41ada596 100644 --- a/code/game/objects/random/mob_vr.dm +++ b/code/game/objects/random/mob_vr.dm @@ -145,7 +145,6 @@ /obj/random/cargopod/item_to_spawn() return pick(prob(10);/obj/item/weapon/contraband/poster,\ prob(8);/obj/item/weapon/haircomb,\ - prob(6);/obj/item/weapon/material/wirerod,\ prob(6);/obj/item/weapon/storage/pill_bottle/paracetamol,\ prob(6);/obj/item/weapon/material/butterflyblade,\ prob(6);/obj/item/weapon/material/butterflyhandle,\ diff --git a/code/game/objects/structures/crates_lockers/closets/misc_vr.dm b/code/game/objects/structures/crates_lockers/closets/misc_vr.dm index aa7a55dff6f..6be3942fd7e 100644 --- a/code/game/objects/structures/crates_lockers/closets/misc_vr.dm +++ b/code/game/objects/structures/crates_lockers/closets/misc_vr.dm @@ -124,7 +124,7 @@ /obj/item/weapon/storage/backpack/parachute, /obj/item/weapon/material/knife/tacknife/survival, /obj/item/weapon/gun/energy/locked/frontier/holdout, - /obj/item/clothing/head/pilot, + /obj/item/clothing/head/ompilot, /obj/item/clothing/under/rank/pilot1, /obj/item/clothing/suit/storage/toggle/bomber/pilot, /obj/item/clothing/shoes/boots/winter/explorer, @@ -176,7 +176,6 @@ /obj/item/stack/marker_beacon/thirty, /obj/item/weapon/material/knife/tacknife/survival, /obj/item/weapon/material/knife/machete/deluxe, - /obj/item/weapon/gun/energy/locked/frontier/carbine, /obj/item/clothing/accessory/holster/machete, /obj/random/explorer_shield, /obj/item/weapon/reagent_containers/food/snacks/liquidfood, diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security_vr.dm b/code/game/objects/structures/crates_lockers/closets/secure/security_vr.dm index af14ca3e30c..3d7e899dc22 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/security_vr.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security_vr.dm @@ -178,3 +178,19 @@ if(prob(75)) new /obj/item/weapon/storage/backpack/dufflebag/sec(src) return ..() + +/obj/structure/closet/secure_closet/captains + starts_with = list( + /obj/item/weapon/storage/backpack/dufflebag/captain, + /obj/item/clothing/head/helmet, + /obj/item/clothing/suit/storage/vest, + /obj/item/weapon/cartridge/captain, + /obj/item/weapon/storage/lockbox/medal, + /obj/item/device/radio/headset/heads/captain, + /obj/item/device/radio/headset/heads/captain/alt, + /obj/item/weapon/gun/energy/gun, + /obj/item/weapon/melee/telebaton, + /obj/item/device/flash, + /obj/item/weapon/storage/box/ids, + /obj/item/weapon/melee/rapier, + /obj/item/clothing/accessory/holster/machete/rapier) \ No newline at end of file diff --git a/code/game/objects/structures/ghost_pods/event_vr.dm b/code/game/objects/structures/ghost_pods/event_vr.dm index 4fface95d1b..7a04e0ea2ce 100644 --- a/code/game/objects/structures/ghost_pods/event_vr.dm +++ b/code/game/objects/structures/ghost_pods/event_vr.dm @@ -10,19 +10,37 @@ invisibility = INVISIBILITY_OBSERVER spawn_active = TRUE var/announce_prob = 35 - var/list/possible_mobs = list("Space Bumblebee" = /mob/living/simple_mob/vore/bee, - "Voracious Lizard" = /mob/living/simple_mob/vore/aggressive/dino, - "Giant Frog" = /mob/living/simple_mob/vore/aggressive/frog, - "Giant Rat" = /mob/living/simple_mob/vore/aggressive/rat, - "Juvenile Solargrub" = /mob/living/simple_mob/vore/solargrub, + var/list/possible_mobs = list("Rabbit" = /mob/living/simple_mob/vore/rabbit, "Red Panda" = /mob/living/simple_mob/vore/redpanda, "Fennec" = /mob/living/simple_mob/vore/fennec, "Fennix" = /mob/living/simple_mob/vore/fennix, + "Space Bumblebee" = /mob/living/simple_mob/vore/bee, + "Space Bear" = /mob/living/simple_mob/animal/space/bear, + "Voracious Lizard" = /mob/living/simple_mob/vore/aggressive/dino, + "Giant Frog" = /mob/living/simple_mob/vore/aggressive/frog, + "Giant Rat" = /mob/living/simple_mob/vore/aggressive/rat, "Jelly Blob" = /mob/living/simple_mob/animal/space/jelly, "Wolf" = /mob/living/simple_mob/animal/wolf, + "Juvenile Solargrub" = /mob/living/simple_mob/vore/solargrub, "Sect Queen" = /mob/living/simple_mob/vore/sect_queen, "Sect Drone" = /mob/living/simple_mob/vore/sect_drone, "Defanged Xenomorph" = /mob/living/simple_mob/vore/xeno_defanged, + "Panther" = /mob/living/simple_mob/vore/aggressive/panther, + "Giant Snake" = /mob/living/simple_mob/vore/aggressive/giant_snake, + "Deathclaw" = /mob/living/simple_mob/vore/aggressive/deathclaw, + "Otie" = /mob/living/simple_mob/otie, + "Mutated Otie" =/mob/living/simple_mob/otie/feral, + "Red Otie" = /mob/living/simple_mob/otie/red, + "Corrupt Hound" = /mob/living/simple_mob/vore/aggressive/corrupthound, + "Corrupt Corrupt Hound" = /mob/living/simple_mob/vore/aggressive/corrupthound/prettyboi, + "Hunter Giant Spider" = /mob/living/simple_mob/animal/giant_spider/hunter, + "Lurker Giant Spider" = /mob/living/simple_mob/animal/giant_spider/lurker, + "Pepper Giant Spider" = /mob/living/simple_mob/animal/giant_spider/pepper, + "Thermic Giant Spider" = /mob/living/simple_mob/animal/giant_spider/thermic, + "Webslinger Giant Spider" = /mob/living/simple_mob/animal/giant_spider/webslinger, + "Frost Giant Spider" = /mob/living/simple_mob/animal/giant_spider/frost, + "Nurse Giant Spider" = /mob/living/simple_mob/animal/giant_spider/nurse/eggless, + "Giant Spider Queen" = /mob/living/simple_mob/animal/giant_spider/nurse/queen/eggless ) /obj/structure/ghost_pod/ghost_activated/maintpred/create_occupant(var/mob/M) diff --git a/code/game/objects/structures/loot_piles.dm b/code/game/objects/structures/loot_piles.dm index 01069b8e234..55ebb62b1ad 100644 --- a/code/game/objects/structures/loot_piles.dm +++ b/code/game/objects/structures/loot_piles.dm @@ -255,7 +255,6 @@ Loot piles can be depleted, if loot_depleted is turned on. Note that players wh /obj/item/stack/material/cardboard{amount = 5}, /obj/item/weapon/contraband/poster, /obj/item/weapon/contraband/poster/custom, - /obj/item/weapon/material/wirerod, /obj/item/weapon/newspaper, /obj/item/weapon/paper/crumpled, /obj/item/weapon/paper/crumpled/bloody diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm index 282a10f9e08..6b95d902111 100644 --- a/code/game/objects/structures/watercloset.dm +++ b/code/game/objects/structures/watercloset.dm @@ -222,7 +222,7 @@ M.touching.remove_any(remove_amount) M.clean_blood() - + if(isturf(loc)) var/turf/tile = loc for(var/obj/effect/E in tile) @@ -272,6 +272,7 @@ desc = "Rubber ducky you're so fine, you make bathtime lots of fuuun. Rubber ducky I'm awfully fooooond of yooooouuuu~" //thanks doohl icon = 'icons/obj/watercloset.dmi' icon_state = "rubberducky" + honk_sound = 'sound/voice/quack.ogg' //VOREStation edit /obj/structure/sink name = "sink" diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index b655d8b5e75..b70af8354d5 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -229,8 +229,17 @@ proc/admin_notice(var/message, var/rights) return PlayerNotesPage(1) -/datum/admins/proc/PlayerNotesPage(page) - var/dat = "Player notes
" +/datum/admins/proc/PlayerNotesFilter() + if (!istype(src,/datum/admins)) + src = usr.client.holder + if (!istype(src,/datum/admins)) + to_chat(usr, "Error: you are not an admin!") + return + var/filter = input(usr, "Filter string (case-insensitive regex)", "Player notes filter") as text|null + PlayerNotesPage(1, filter) + +/datum/admins/proc/PlayerNotesPage(page, filter) + var/dat = "Player notes - Apply Filter
" var/savefile/S=new("data/player_notes.sav") var/list/note_keys S >> note_keys @@ -240,29 +249,38 @@ proc/admin_notice(var/message, var/rights) dat += "" note_keys = sortList(note_keys) + if(filter) + var/list/results = list() + var/regex/needle = regex(filter, "i") + for(var/haystack in note_keys) + if(needle.Find(haystack)) + results += haystack + note_keys = results + // Display the notes on the current page var/number_pages = note_keys.len / PLAYER_NOTES_ENTRIES_PER_PAGE // Emulate CEILING(why does BYOND not have ceil, 1) if(number_pages != round(number_pages)) number_pages = round(number_pages) + 1 var/page_index = page - 1 + if(page_index < 0 || page_index >= number_pages) - return + dat += "" + else + var/lower_bound = page_index * PLAYER_NOTES_ENTRIES_PER_PAGE + 1 + var/upper_bound = (page_index + 1) * PLAYER_NOTES_ENTRIES_PER_PAGE + upper_bound = min(upper_bound, note_keys.len) + for(var/index = lower_bound, index <= upper_bound, index++) + var/t = note_keys[index] + dat += "" - var/lower_bound = page_index * PLAYER_NOTES_ENTRIES_PER_PAGE + 1 - var/upper_bound = (page_index + 1) * PLAYER_NOTES_ENTRIES_PER_PAGE - upper_bound = min(upper_bound, note_keys.len) - for(var/index = lower_bound, index <= upper_bound, index++) - var/t = note_keys[index] - dat += "" - - dat += "
No keys found.
[t]
[t]

" + dat += "
" // Display a footer to select different pages for(var/index = 1, index <= number_pages, index++) if(index == page) dat += "" - dat += "[index] " + dat += "[index] " if(index == page) dat += "" diff --git a/code/modules/admin/admin_vr.dm b/code/modules/admin/admin_vr.dm index 356d69a3761..e40db3f525a 100644 --- a/code/modules/admin/admin_vr.dm +++ b/code/modules/admin/admin_vr.dm @@ -8,5 +8,7 @@ traitors.spawn_uplink(H) H.mind.tcrystals = DEFAULT_TELECRYSTAL_AMOUNT H.mind.accept_tcrystals = 1 + var/msg = "[key_name(usr)] has given [H.ckey] an uplink." + message_admins(msg) else to_chat(usr, "You do not have access to this command.") \ No newline at end of file diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 2c80b58274e..44b3c9e16bd 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -1971,7 +1971,12 @@ if("show") show_player_info(ckey) if("list") - PlayerNotesPage(text2num(href_list["index"])) + var/filter + if(href_list["filter"] && href_list["filter"] != "0") + filter = url_decode(href_list["filter"]) + PlayerNotesPage(text2num(href_list["index"]), filter) + if("filter") + PlayerNotesFilter() return mob/living/proc/can_centcom_reply() diff --git a/code/modules/blob2/core_chunk.dm b/code/modules/blob2/core_chunk.dm index 4abc06843eb..15db91e89ec 100644 --- a/code/modules/blob2/core_chunk.dm +++ b/code/modules/blob2/core_chunk.dm @@ -118,19 +118,19 @@ return FALSE -/datum/chemical_reaction/blob_reconstitution +/decl/chemical_reaction/instant/blob_reconstitution name = "Hostile Blob Revival" id = "blob_revival" result = null required_reagents = list("phoron" = 60) result_amount = 1 -/datum/chemical_reaction/blob_reconstitution/can_happen(var/datum/reagents/holder) +/decl/chemical_reaction/instant/blob_reconstitution/can_happen(var/datum/reagents/holder) if(holder.my_atom && istype(holder.my_atom, /obj/item/weapon/blobcore_chunk)) return ..() return FALSE -/datum/chemical_reaction/blob_reconstitution/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/blob_reconstitution/on_reaction(var/datum/reagents/holder) var/obj/item/weapon/blobcore_chunk/chunk = holder.my_atom if(chunk.can_genesis && chunk.regen()) chunk.visible_message("[chunk] bubbles, surrounding itself with a rapidly expanding mass of [chunk.blob_type.name]!") @@ -138,14 +138,14 @@ else chunk.visible_message("[chunk] shifts strangely, but falls still.") -/datum/chemical_reaction/blob_reconstitution/domination +/decl/chemical_reaction/instant/blob_reconstitution/domination name = "Allied Blob Revival" id = "blob_friend" result = null required_reagents = list("hydrophoron" = 40, "peridaxon" = 20, "mutagen" = 20) result_amount = 1 -/datum/chemical_reaction/blob_reconstitution/domination/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/blob_reconstitution/domination/on_reaction(var/datum/reagents/holder) var/obj/item/weapon/blobcore_chunk/chunk = holder.my_atom if(chunk.can_genesis && chunk.regen("neutral")) chunk.visible_message("[chunk] bubbles, surrounding itself with a rapidly expanding mass of [chunk.blob_type.name]!") diff --git a/code/modules/catalogue/catalogue_data_vr.dm b/code/modules/catalogue/catalogue_data_vr.dm index 4ac6a0b0696..06c3f9c51a7 100644 --- a/code/modules/catalogue/catalogue_data_vr.dm +++ b/code/modules/catalogue/catalogue_data_vr.dm @@ -5,63 +5,124 @@ /datum/category_item/catalogue/fauna/akula name = "Sapients - Akula" - desc = "" + desc = "A pelagic species hailing from the Barkalis System originally\ + the Akula have been incidentally uplifted by free Kosaky \ + sharing much of their more modern culture with interstellar\ + Humanity. Many of them have spread among the stars, either\ + in the nomad fleets or joining colonies as capable hard labour." value = CATALOGUER_REWARD_TRIVIAL /datum/category_item/catalogue/fauna/sergal name = "Sapients - Sergal" - desc = "" + desc = "The dominant species in the Vilous System, the Sergal are a\ + strange mammalian clade which shares similarities with \ + masurpials, pelagic creatures and wolves. Collectivist and\ + organising themselves in tribes and city states, they have\ + eclipsed the private colony venture trying to hold them \ + economically beholden and now have joined the sapient \ + diaspora on more equal terms." value = CATALOGUER_REWARD_TRIVIAL /datum/category_item/catalogue/fauna/nevrean name = "Sapients - Nevrean" - desc = "" + desc = "A co-sapient species from Vilous, the Nevrean have found their\ + ecological niche as nomadic traders and craftsmen, \ + developing a rich oral tradition, that is being slowly \ + codified by the Sergals in an efforts to culturally export \ + it through the stars. The modern Nevrean co-inhabits most \ + places the Sergals do as comrades and historical allies." value = CATALOGUER_REWARD_TRIVIAL /datum/category_item/catalogue/fauna/rapala name = "Sapients - Rapala" - desc = "" + desc = "The Rapala, formally “Rapala-Unathi†are a vassal species of the Unathi \ + in form of winged Humanoids. While they share a similar outwards appearance with humans, \ + they have a much more complex system of sexual genetics, as well superior 3D awareness. \ + The Rapala act as emissaries, diplomats and spies for their overlords, although it is an open \ + secret that they work for more autonomy and self-governance." value = CATALOGUER_REWARD_TRIVIAL /datum/category_item/catalogue/fauna/xenochimera name = "Sapients - Xenochimera" - desc = "" + desc = "ERROR : DNA corruption detected. The likely outcome of this is this specimen being \ + a Xenochimera. Xenochimeras are the end stage of “Roanoke Syndromeâ€, a microbial infection \ + that infiltrates the immune system of a host species by mimicking cells. Upon expiration of \ + the host (preventable by medical attention), the cells cannibalize and take over the body, \ + creating a xenochimera. If the body has been capable of sapient thought, the resultant morph \ + is also capable of thought. \ +

\ + Contrary to popular belief, Roanoke Syndrome colonies do not seek out sapient life. Any exposure \ + is incidental and not part of a plot – xenochimera without sapient thought are simply wild animals or disease vectors." value = CATALOGUER_REWARD_TRIVIAL /datum/category_item/catalogue/fauna/vulpkanin name = "Sapients - Vulpkanin" - desc = "" + desc = "The Vulpkanin are the remnants of an ancient precursor which resided in the Coreward Periphery \ + 3000 to 4000 years ago, residing on a planet called “Altamâ€. Vulpkanin diverged from the precursors due \ + to heavy isolation after the fall, presumably due to being a freshly found colony. A lack of material support \ + regressed their technology to pre-industrial standards until being found again by Humanity. At this point \ + they have formed an early spacefaring society and accession into the Diaspora went over relatively smoothly. \ + Vulpkanin are the closest successor to the precursors, genetically, although genelocked devices still do not \ + recognize them due to genetic drift." value = CATALOGUER_REWARD_TRIVIAL /datum/category_item/catalogue/fauna/alraune name = "Sapients - Alraune" - desc = "" + desc = "Alraune are enigmatic, strange creatures from the Elysian Colonies. While their main culture is still \ + in the early neolithic, a large diaspora has formed from previous abductions and trade with these creatures, who \ + seem to mimic many cultivars throughout space through yet an unknown mechanism. Alraune are pleasant, but \ + predatory who autocannibalize their own products as a form of nutriment transfer and storage." value = CATALOGUER_REWARD_TRIVIAL /datum/category_item/catalogue/fauna/vasilissan name = "Sapients - Vasilissan" - desc = "" + desc = "Vasilissans are an arachnid species uplifted by NT due to their propensity for architectural feats for \ + surface-to-orbit buildings with relatively primitive materials. Exploited for a while, they have managed to \ + connect to the greater commerce of the Diaspora, making them less dependent of our favourite TSCs, sadly. \ + Vasilissans are happily adopted into Coreward Periphery colonies, valued for their infrastructural acumen \ + and their craftsmanship with their natural silk." value = CATALOGUER_REWARD_TRIVIAL /datum/category_item/catalogue/fauna/zorren name = "Sapients - Zorren" - desc = "" + desc = "The Zorren are the remnants of an ancient precursor which resided in the Coreward Periphery 3000 to 4000 \ + years ago, residing on a planet called “Menhirâ€, which we call Virgo 4. Zorren organise themselves through various \ + feudal-styled kingdoms and monarchies, of which the most prominent is the Kingdom of An-Tahk-Et. They are obsessed \ + over their ancient heritage and the power of the noble houses comes through the control and excavation of old technology \ + of their precursors, leading to a massive divide between commoners, who live as serfs and the nobility, who live in \ + comparable conditions as wealthy members of the Diaspora." value = CATALOGUER_REWARD_TRIVIAL /datum/category_item/catalogue/fauna/shadekin name = "Sapients - Shadekin" - desc = "" + desc = "ERROR : No DNA found. ERROR : Ambient energy signature detected. Likely origin from attempt of scanning \ + Specimen NT-495. \ +

\ + NT-495, also colloquial known as “Shadekinâ€, “Deep Peopleâ€, “Mar Beastâ€, “Shadow creature†are an enigmatic species \ + capable of localized bluespace events (although the credibility of them actually manipulating bluespace effects \ + still is in question), allowing them to “shift†through phases of existence without assistance of machines. \ + Observation of NT-495 is notoriously difficult, as they do not exhibit these traits when in direct view unless \ + they seem to feel threatened. \ +

\ + Their definite sapience has been proven as several NT-495 sightings supports them to be capable of galactic common, \ + especially under the variant that does not seem to possess the innate ability to phase – in fact, NT has recently \ + started to hire those for closer observation." value = CATALOGUER_REWARD_EASY /datum/category_item/catalogue/fauna/custom_species name = "Sapients - Other" - desc = "Remote frontiers require people of all sorts of life...\ - Sometimes species one would never see anywhere close to core worlds can be met here." + desc = "ERROR : DNA scan inconclusive. Please interview subject to catalogue them manually. \ + We apologise for the inconvenience. \ +

\ + Likely reasons for failure : Genetic Engineering, Hybridization, minor species of Orion Spur Diaspora." value = CATALOGUER_REWARD_TRIVIAL /datum/category_item/catalogue/technology/resleeving name = "Resleeving" - desc = "" + desc = "The premier technology of the early 2280s, Resleeving is a direct upgrade to the antiquated flash \ + cloning by creating near perfect copies of a body within the database, capable of uploading a consciousness \ + in the dormant brain via direct electro-uploading. However, this technology is not perfect and small, but \ + non-zero error margins exist. Handle with care! Or don't. Stress testing this stuff makes a lucrative market." value = CATALOGUER_REWARD_TRIVIAL /datum/category_item/catalogue/information/organization/khi diff --git a/code/modules/catalogue/cataloguer_vr.dm b/code/modules/catalogue/cataloguer_vr.dm index 8a8322c5815..6759cca6510 100644 --- a/code/modules/catalogue/cataloguer_vr.dm +++ b/code/modules/catalogue/cataloguer_vr.dm @@ -3,8 +3,10 @@ /obj/item/device/cataloguer/compact name = "compact cataloguer" - icon = 'icons/vore/custom_items_vr.dmi' - icon_state = "tricorder" + desc = "A compact hand-held device, used for compiling information about an object by scanning it. \ + Alt+click to highlight scannable objects around you." + icon = 'icons/obj/device_vr.dmi' + icon_state = "compact" action_button_name = "Toggle Cataloguer" var/deployed = TRUE scan_range = 1 @@ -30,7 +32,7 @@ if(deployed) w_class = ITEMSIZE_NORMAL icon_state = "[initial(icon_state)]" - to_chat(usr, span("notice", "You flip open \the [src].")) + to_chat(usr, span("notice", "You flick open \the [src].")) else w_class = ITEMSIZE_SMALL icon_state = "[initial(icon_state)]_closed" @@ -54,6 +56,15 @@ /obj/item/device/cataloguer/compact/pathfinder name = "pathfinder's cataloguer" - icon_state = "tricorder_med" + desc = "A compact hand-held device, used for compiling information about an object by scanning it. \ + Alt+click to highlight scannable objects around you." + icon = 'icons/obj/device_vr.dmi' + icon_state = "pathcat" scan_range = 3 toolspeed = 1 + +/obj/item/device/cataloguer + desc = "A hand-held device, used for compiling information about an object by scanning it. \ + Alt+click to highlight scannable objects around you." + icon = 'icons/obj/device_vr.dmi' + icon_state = "cataloguer" \ No newline at end of file diff --git a/code/modules/client/preference_setup/general/02_language.dm b/code/modules/client/preference_setup/general/02_language.dm index 673e273af0b..fc21c743c09 100644 --- a/code/modules/client/preference_setup/general/02_language.dm +++ b/code/modules/client/preference_setup/general/02_language.dm @@ -15,8 +15,18 @@ if(!islist(pref.alternate_languages)) pref.alternate_languages = list() if(pref.species) var/datum/species/S = GLOB.all_species[pref.species] - if(S && pref.alternate_languages.len > S.num_alternate_languages) + if(!istype(S)) + return + + if(pref.alternate_languages.len > S.num_alternate_languages) pref.alternate_languages.len = S.num_alternate_languages // Truncate to allowed length + + // Sanitize illegal languages + for(var/language in pref.alternate_languages) + var/datum/language/L = GLOB.all_languages[language] + if(!istype(L) || (L.flags & RESTRICTED) || (!(language in S.secondary_langs) && !is_lang_whitelisted(pref.client, L))) + pref.alternate_languages -= language + if(isnull(pref.language_prefixes) || !pref.language_prefixes.len) pref.language_prefixes = config.language_prefixes.Copy() for(var/prefix in pref.language_prefixes) diff --git a/code/modules/client/preference_setup/general/03_body.dm b/code/modules/client/preference_setup/general/03_body.dm index 949d613b6b5..15f079d31cb 100644 --- a/code/modules/client/preference_setup/general/03_body.dm +++ b/code/modules/client/preference_setup/general/03_body.dm @@ -37,6 +37,43 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O var/g_wing3 = 30 // Wing tertiary color var/b_wing3 = 30 // Wing tertiary color +// Sanitize ear/wing/tail styles +/datum/preferences/proc/sanitize_body_styles() + + // Grandfather in anyone loading paths from a save. + if(ispath(ear_style, /datum/sprite_accessory)) + var/datum/sprite_accessory/instance = global.ear_styles_list[ear_style] + if(istype(instance)) + ear_style = instance.name + if(ispath(wing_style, /datum/sprite_accessory)) + var/datum/sprite_accessory/instance = global.wing_styles_list[wing_style] + if(istype(instance)) + wing_style = instance.name + if(ispath(tail_style, /datum/sprite_accessory)) + var/datum/sprite_accessory/instance = global.tail_styles_list[tail_style] + if(istype(instance)) + tail_style = instance.name + + // Sanitize for non-existent keys. + if(ear_style && !(ear_style in get_available_styles(global.ear_styles_list))) + ear_style = null + if(wing_style && !(wing_style in get_available_styles(global.wing_styles_list))) + wing_style = null + if(tail_style && !(tail_style in get_available_styles(global.tail_styles_list))) + tail_style = null + +/datum/preferences/proc/get_available_styles(var/style_list) + . = list("Normal" = null) + for(var/path in style_list) + var/datum/sprite_accessory/instance = style_list[path] + if(!istype(instance)) + continue + if(instance.ckeys_allowed && (!client || !(client.ckey in instance.ckeys_allowed))) + continue + if(instance.species_allowed && (!species || !(species in instance.species_allowed)) && (!client || !check_rights(R_ADMIN | R_EVENT | R_FUN, 0, client))) + continue + .[instance.name] = instance + /datum/category_item/player_setup_item/general/body name = "Body" sort_order = 3 @@ -228,21 +265,8 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O pref.r_wing3 = sanitize_integer(pref.r_wing3, 0, 255, initial(pref.r_wing3)) pref.g_wing3 = sanitize_integer(pref.g_wing3, 0, 255, initial(pref.g_wing3)) pref.b_wing3 = sanitize_integer(pref.b_wing3, 0, 255, initial(pref.b_wing3)) - if(pref.ear_style) - pref.ear_style = sanitize_inlist(pref.ear_style, ear_styles_list, initial(pref.ear_style)) - var/datum/sprite_accessory/temp_ear_style = ear_styles_list[pref.ear_style] - if(temp_ear_style.apply_restrictions && (!(pref.species in temp_ear_style.species_allowed))) - pref.ear_style = initial(pref.ear_style) - if(pref.tail_style) - pref.tail_style = sanitize_inlist(pref.tail_style, tail_styles_list, initial(pref.tail_style)) - var/datum/sprite_accessory/temp_tail_style = tail_styles_list[pref.tail_style] - if(temp_tail_style.apply_restrictions && (!(pref.species in temp_tail_style.species_allowed))) - pref.tail_style = initial(pref.tail_style) - if(pref.wing_style) - pref.wing_style = sanitize_inlist(pref.wing_style, wing_styles_list, initial(pref.wing_style)) - var/datum/sprite_accessory/temp_wing_style = wing_styles_list[pref.wing_style] - if(temp_wing_style.apply_restrictions && (!(pref.species in temp_wing_style.species_allowed))) - pref.wing_style = initial(pref.wing_style) + + pref.sanitize_body_styles() // Moved from /datum/preferences/proc/copy_to() /datum/category_item/player_setup_item/general/body/copy_to_mob(var/mob/living/carbon/human/character) @@ -274,37 +298,44 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O character.g_synth = pref.g_synth character.b_synth = pref.b_synth character.synth_markings = pref.synth_markings - character.ear_style = ear_styles_list[pref.ear_style] - character.r_ears = pref.r_ears - character.b_ears = pref.b_ears - character.g_ears = pref.g_ears - character.r_ears2 = pref.r_ears2 - character.b_ears2 = pref.b_ears2 - character.g_ears2 = pref.g_ears2 - character.r_ears3 = pref.r_ears3 - character.b_ears3 = pref.b_ears3 - character.g_ears3 = pref.g_ears3 - character.tail_style = tail_styles_list[pref.tail_style] - character.r_tail = pref.r_tail - character.b_tail = pref.b_tail - character.g_tail = pref.g_tail - character.r_tail2 = pref.r_tail2 - character.b_tail2 = pref.b_tail2 - character.g_tail2 = pref.g_tail2 - character.r_tail3 = pref.r_tail3 - character.b_tail3 = pref.b_tail3 - character.g_tail3 = pref.g_tail3 - character.wing_style = wing_styles_list[pref.wing_style] - character.r_wing = pref.r_wing - character.b_wing = pref.b_wing - character.g_wing = pref.g_wing - character.r_wing2 = pref.r_wing2 - character.b_wing2 = pref.b_wing2 - character.g_wing2 = pref.g_wing2 - character.r_wing3 = pref.r_wing3 - character.b_wing3 = pref.b_wing3 - character.g_wing3 = pref.g_wing3 - character.set_gender( pref.biological_gender) + + var/list/ear_styles = pref.get_available_styles(global.ear_styles_list) + character.ear_style = ear_styles[pref.ear_style] + character.r_ears = pref.r_ears + character.b_ears = pref.b_ears + character.g_ears = pref.g_ears + character.r_ears2 = pref.r_ears2 + character.b_ears2 = pref.b_ears2 + character.g_ears2 = pref.g_ears2 + character.r_ears3 = pref.r_ears3 + character.b_ears3 = pref.b_ears3 + character.g_ears3 = pref.g_ears3 + + var/list/tail_styles = pref.get_available_styles(global.tail_styles_list) + character.tail_style = tail_styles[pref.tail_style] + character.r_tail = pref.r_tail + character.b_tail = pref.b_tail + character.g_tail = pref.g_tail + character.r_tail2 = pref.r_tail2 + character.b_tail2 = pref.b_tail2 + character.g_tail2 = pref.g_tail2 + character.r_tail3 = pref.r_tail3 + character.b_tail3 = pref.b_tail3 + character.g_tail3 = pref.g_tail3 + + var/list/wing_styles = pref.get_available_styles(global.wing_styles_list) + character.wing_style = wing_styles[pref.wing_style] + character.r_wing = pref.r_wing + character.b_wing = pref.b_wing + character.g_wing = pref.g_wing + character.r_wing2 = pref.r_wing2 + character.b_wing2 = pref.b_wing2 + character.g_wing2 = pref.g_wing2 + character.r_wing3 = pref.r_wing3 + character.b_wing3 = pref.b_wing3 + character.g_wing3 = pref.g_wing3 + + character.set_gender(pref.biological_gender) // Destroy/cyborgize organs and limbs. for(var/name in list(BP_HEAD, BP_L_HAND, BP_R_HAND, BP_L_ARM, BP_R_ARM, BP_L_FOOT, BP_R_FOOT, BP_L_LEG, BP_R_LEG, BP_GROIN, BP_TORSO)) @@ -519,59 +550,47 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O . += "

Genetics Settings

" - var/ear_display = "Normal" - if(pref.ear_style && (pref.ear_style in ear_styles_list)) - var/datum/sprite_accessory/ears/instance = ear_styles_list[pref.ear_style] - ear_display = instance.name - - else if(pref.ear_style) - ear_display = "REQUIRES UPDATE" + var/list/ear_styles = pref.get_available_styles(global.ear_styles_list) + var/datum/sprite_accessory/ears/ear = ear_styles[pref.ear_style] . += "Ears
" - . += " Style: [ear_display]
" - if(ear_styles_list[pref.ear_style]) - var/datum/sprite_accessory/ears/ear = ear_styles_list[pref.ear_style] + if(istype(ear)) + . += " Style: [ear.name]
" if(ear.do_colouration) . += "Change Color [color_square(pref.r_ears, pref.g_ears, pref.b_ears)]
" if(ear.extra_overlay) . += "Change Secondary Color [color_square(pref.r_ears2, pref.g_ears2, pref.b_ears2)]
" if(ear.extra_overlay2) . += "Change Tertiary Color [color_square(pref.r_ears3, pref.g_ears3, pref.b_ears3)]
" + else + . += " Style: Select
" - var/tail_display = "Normal" - if(pref.tail_style && (pref.tail_style in tail_styles_list)) - var/datum/sprite_accessory/tail/instance = tail_styles_list[pref.tail_style] - tail_display = instance.name - else if(pref.tail_style) - tail_display = "REQUIRES UPDATE" + var/list/tail_styles = pref.get_available_styles(global.tail_styles_list) + var/datum/sprite_accessory/tail/tail = tail_styles[pref.tail_style] . += "Tail
" - . += " Style: [tail_display]
" - - if(tail_styles_list[pref.tail_style]) - var/datum/sprite_accessory/tail/T = tail_styles_list[pref.tail_style] - if(T.do_colouration) + if(istype(tail)) + . += " Style: [tail.name]
" + if(tail.do_colouration) . += "Change Color [color_square(pref.r_tail, pref.g_tail, pref.b_tail)]
" - if(T.extra_overlay) + if(tail.extra_overlay) . += "Change Secondary Color [color_square(pref.r_tail2, pref.g_tail2, pref.b_tail2)]
" - if(T.extra_overlay2) + if(tail.extra_overlay2) . += "Change Tertiary Color [color_square(pref.r_tail3, pref.g_tail3, pref.b_tail3)]
" + else + . += " Style: Select
" - var/wing_display = "Normal" - if(pref.wing_style && (pref.wing_style in wing_styles_list)) - var/datum/sprite_accessory/wing/instance = wing_styles_list[pref.wing_style] - wing_display = instance.name - else if(pref.wing_style) - wing_display = "REQUIRES UPDATE" + var/list/wing_styles = pref.get_available_styles(global.wing_styles_list) + var/datum/sprite_accessory/wing/wings = wing_styles[pref.wing_style] . += "Wing
" - . += " Style: [wing_display]
" - - if(wing_styles_list[pref.wing_style]) - var/datum/sprite_accessory/wing/W = wing_styles_list[pref.wing_style] - if(W.do_colouration) + if(istype(wings)) + . += " Style: [wings.name]
" + if(wings.do_colouration) . += "Change Color [color_square(pref.r_wing, pref.g_wing, pref.b_wing)]
" - if(W.extra_overlay) + if(wings.extra_overlay) . += "Change Secondary Color [color_square(pref.r_wing2, pref.g_wing2, pref.b_wing2)]
" - if(W.extra_overlay2) + if(wings.extra_overlay2) . += "Change Secondary Color [color_square(pref.r_wing3, pref.g_wing3, pref.b_wing3)]
" + else + . += " Style: Select
" . += "
Body Markings +
" . += "" @@ -669,7 +688,9 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O reset_limbs() // Safety for species with incompatible manufacturers; easier than trying to do it case by case. pref.body_markings.Cut() // Basically same as above. - + + pref.sanitize_body_styles() + var/min_age = get_min_age() var/max_age = get_max_age() pref.age = max(min(pref.age, max_age), min_age) @@ -1085,17 +1106,9 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O return TOPIC_REFRESH_UPDATE_PREVIEW else if(href_list["ear_style"]) - // Construct the list of names allowed for this user. - var/list/pretty_ear_styles = list("Normal" = null) - for(var/path in ear_styles_list) - var/datum/sprite_accessory/ears/instance = ear_styles_list[path] - if(((!instance.ckeys_allowed) || (usr.ckey in instance.ckeys_allowed)) && ((!instance.apply_restrictions) || (pref.species in instance.species_allowed)) || check_rights(R_ADMIN | R_EVENT | R_FUN, 0, user)) //VOREStation Edit - pretty_ear_styles[instance.name] = path - - // Present choice to user - var/new_ear_style = input(user, "Pick ears", "Character Preference", pref.ear_style) as null|anything in pretty_ear_styles + var/new_ear_style = input(user, "Select an ear style for this character:", "Character Preference", pref.ear_style) as null|anything in pref.get_available_styles(global.ear_styles_list) if(new_ear_style) - pref.ear_style = pretty_ear_styles[new_ear_style] + pref.ear_style = new_ear_style return TOPIC_REFRESH_UPDATE_PREVIEW @@ -1127,18 +1140,9 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O return TOPIC_REFRESH_UPDATE_PREVIEW else if(href_list["tail_style"]) - // Construct the list of names allowed for this user. - var/list/pretty_tail_styles = list("Normal" = null) - for(var/path in tail_styles_list) - var/datum/sprite_accessory/tail/instance = tail_styles_list[path] - if(((!instance.ckeys_allowed) || (usr.ckey in instance.ckeys_allowed)) && ((!instance.apply_restrictions) || (pref.species in instance.species_allowed)) || check_rights(R_ADMIN | R_EVENT | R_FUN, 0, user)) //VOREStation Edit - pretty_tail_styles[instance.name] = path - - // Present choice to user - var/new_tail_style = input(user, "Pick tails", "Character Preference", pref.tail_style) as null|anything in pretty_tail_styles + var/new_tail_style = input(user, "Select a tail style for this character:", "Character Preference", pref.tail_style) as null|anything in pref.get_available_styles(global.tail_styles_list) if(new_tail_style) - pref.tail_style = pretty_tail_styles[new_tail_style] - + pref.tail_style = new_tail_style return TOPIC_REFRESH_UPDATE_PREVIEW else if(href_list["tail_color"]) @@ -1169,17 +1173,9 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O return TOPIC_REFRESH_UPDATE_PREVIEW else if(href_list["wing_style"]) - // Construct the list of names allowed for this user. - var/list/pretty_wing_styles = list("Normal" = null) - for(var/path in wing_styles_list) - var/datum/sprite_accessory/wing/instance = wing_styles_list[path] - if(((!instance.ckeys_allowed) || (usr.ckey in instance.ckeys_allowed)) && ((!instance.apply_restrictions) || (pref.species in instance.species_allowed)) || check_rights(R_ADMIN | R_EVENT | R_FUN, 0, user)) //VOREStation Edit - pretty_wing_styles[instance.name] = path - - // Present choice to user - var/new_wing_style = input(user, "Pick wings", "Character Preference", pref.wing_style) as null|anything in pretty_wing_styles + var/new_wing_style = input(user, "Select a wing style for this character:", "Character Preference", pref.wing_style) as null|anything in pref.get_available_styles(global.wing_styles_list) if(new_wing_style) - pref.wing_style = pretty_wing_styles[new_wing_style] + pref.wing_style = new_wing_style return TOPIC_REFRESH_UPDATE_PREVIEW diff --git a/code/modules/client/preference_setup/loadout/loadout.dm b/code/modules/client/preference_setup/loadout/loadout.dm index c91b2314c89..e5822353990 100644 --- a/code/modules/client/preference_setup/loadout/loadout.dm +++ b/code/modules/client/preference_setup/loadout/loadout.dm @@ -62,12 +62,15 @@ var/list/gear_datums = list() /datum/category_item/player_setup_item/loadout/proc/valid_gear_choices(var/max_cost) . = list() - var/mob/preference_mob = preference_mob() + var/mob/preference_mob = preference_mob() //VOREStation Add for(var/gear_name in gear_datums) var/datum/gear/G = gear_datums[gear_name] - if(G.whitelisted && !is_alien_whitelisted(preference_mob, GLOB.all_species[G.whitelisted])) - continue + if(G.whitelisted && config.loadout_whitelist != LOADOUT_WHITELIST_OFF) + if(config.loadout_whitelist == LOADOUT_WHITELIST_STRICT && G.whitelisted != pref.species) + continue + if(config.loadout_whitelist == LOADOUT_WHITELIST_LAX && !is_alien_whitelisted(preference_mob(), GLOB.all_species[G.whitelisted])) + continue if(max_cost && G.cost > max_cost) continue //VOREStation Edit Start diff --git a/code/modules/client/preference_setup/loadout/loadout_fluffitems_vr.dm b/code/modules/client/preference_setup/loadout/loadout_fluffitems_vr.dm index 17656aae896..52666a24190 100644 --- a/code/modules/client/preference_setup/loadout/loadout_fluffitems_vr.dm +++ b/code/modules/client/preference_setup/loadout/loadout_fluffitems_vr.dm @@ -60,6 +60,12 @@ ckeywhitelist = list("aegisoa") character_name = list("Xander Bevin") +/datum/gear/fluff/charlotte_cigarettes + path = /obj/item/weapon/storage/fancy/fluff/charlotte + display_name = "Charlotte's cigarette case" + ckeywhitelist = list("alfalah") + character_name = list("Charlotte Graves") + /datum/gear/fluff/lynn_penlight path = /obj/item/device/flashlight/pen/fluff/lynn display_name = "Lynn's Penlight" @@ -89,11 +95,23 @@ character_name = list("Aronai Sieyes") /datum/gear/fluff/astra_ritualknife - path = /obj/item/weapon/material/knife/ritual/fluff/astra - display_name = "Polished Ritual Knife" - description = "A well kept strange ritual knife, There is a small tag with the name 'Astra Ether' on it. They are probably looking for this." - ckeywhitelist = list("astraether") - character_name = list("Astra Ether") + path = /obj/item/weapon/material/knife/ritual/fluff/astra + display_name = "Polished Ritual Knife" + description = "A well kept strange ritual knife, There is a small tag with the name 'Astra Ether' on it. They are probably looking for this." + ckeywhitelist = list("astraether") + character_name = list("Astra Ether") + +/datum/gear/fluff/astra_medal + path = /obj/item/clothing/accessory/medal/conduct + display_name = "Astra's Conduct Medal" + ckeywhitelist = list("astraether") + character_name = list("Astra Ether") + +/datum/gear/fluff/astra_medal_2 + path = /obj/item/clothing/accessory/medal/silver/unity + display_name = "Astra's Unity Medal" + ckeywhitelist = list("astraether") + character_name = list("Astra Ether") /datum/gear/fluff/collar/azura path = /obj/item/clothing/accessory/collar/azura @@ -149,6 +167,12 @@ ckeywhitelist = list("blakeryan") character_name = list("Nolan Conaway") +/datum/gear/fluff/amber_medal + path = /obj/item/clothing/accessory/medal/conduct + display_name = "Amber's Conduct Medal" + ckeywhitelist = list("bluewolf128") + character_name = list("Amber Wresspenn") + /datum/gear/fluff/charles_hat path = /obj/item/clothing/head/that/fluff/gettler display_name = "Charles' Top-Hat" @@ -189,6 +213,12 @@ ckeywhitelist = list("bacon12366") character_name = list("Elly Brown") +/datum/gear/fluff/alibig_medal + path = /obj/item/clothing/accessory/medal/conduct + display_name = "Ali Big's Conduct Medal" + ckeywhitelist = list("bigbababooey") + character_name = list("Ali Big") + // C CKEYS /datum/gear/fluff/cappy_watch path = /obj/item/clothing/accessory/watch @@ -260,6 +290,18 @@ ckeywhitelist = list("dickfreedomjohnson") character_name = list("Elliot Richards") +/datum/gear/fluff/donald_medal + path = /obj/item/clothing/accessory/medal/conduct + display_name = "Donald's Conduct Medal" + ckeywhitelist = list("drainquake") + character_name = list("Donald Weinbeck") + +/datum/gear/fluff/donald_medal_2 + path = /obj/item/clothing/accessory/medal/bronze_heart + display_name = "Donald's Heart Medal" + ckeywhitelist = list("drainquake") + character_name = list("Donald Weinbeck") + /datum/gear/fluff/drake_box path = /obj/item/weapon/storage/box/fluff/drake display_name = "Drake's Box" @@ -570,6 +612,12 @@ character_name = list("Ashley Kifer") // L CKEYS +/datum/gear/fluff/kenzie_medal + path = /obj/item/clothing/accessory/medal/conduct + display_name = "Kenzie's Conduct Medal" + ckeywhitelist = list("lm40") + character_name = list("Kenzie Houser") + /datum/gear/fluff/kenzie_hypospray path = /obj/item/weapon/reagent_containers/hypospray/vial/kenzie display_name = "Kenzie's Hypospray" @@ -584,6 +632,12 @@ ckeywhitelist = list("luminescentring") character_name = list("Briana Moore") +/datum/gear/fluff/entchtut_medal + path = /obj/item/clothing/accessory/medal/conduct + display_name = "Entchtut's Conduct Medal" + ckeywhitelist = list("littlebigkid2000") + character_name = list("Entchtut Cenein") + // M CKEYS /datum/gear/fluff/phi_box path = /obj/item/weapon/storage/box/fluff/phi @@ -736,7 +790,7 @@ character_name = list("Scylla Casmus") /datum/gear/fluff/kiyoshi_cloak - path = /obj/item/clothing/accessory/poncho/fluff/cloakglowing + path = /obj/item/clothing/accessory/poncho/roles/cloak/fluff/cloakglowing display_name = "glowing cloak" ckeywhitelist = list("pastelprincedan") character_name = list("Kiyoshi Maki", "Masumi Maki") @@ -758,6 +812,18 @@ character_name = list("Clara Mali") cost = 1 +/datum/gear/fluff/luna_sci_medal + path = /obj/item/clothing/accessory/medal/nobel_science + display_name = "LUNA's Nobel Science Award" + ckeywhitelist = list("residentcody") + character_name = list("LUNA") + +/datum/gear/fluff/luna_conduct_medal + path = /obj/item/clothing/accessory/medal/conduct + display_name = "LUNA's Distinguished Conduct Medal" + ckeywhitelist = list("residentcody") + character_name = list("LUNA") + /datum/gear/fluff/nikki_dorky_outfit path = /obj/item/weapon/storage/box/fluff display_name = "Nikki's Witchy Outfit" @@ -777,6 +843,18 @@ ckeywhitelist = list("sageofaether12") character_name = list("Brynhild Vandradottir") +/datum/gear/fluff/brynhild_medal_3 + path = /obj/item/clothing/accessory/medal/conduct + display_name = "Brynhild's Conduct Medal" + ckeywhitelist = list("sageofaether12") + character_name = list("Brynhild Vandradottir") + +/datum/gear/fluff/brynhild_medal_4 + path = /obj/item/clothing/accessory/medal/bronze_heart + display_name = "Brynhild's Heart Medal" + ckeywhitelist = list("sageofaether12") + character_name = list("Brynhild Vandradottir") + /datum/gear/fluff/kateryna_voidsuit path = /obj/item/clothing/suit/space/void/engineering/kate display_name = "Kateryna's Voidsuit" @@ -912,6 +990,12 @@ ckeywhitelist = list("tabiranth") character_name = list("Ascian") +/datum/gear/fluff/ascian_medal_3 + path = /obj/item/clothing/accessory/medal/conduct + display_name = "Ascian's Conduct Medal" + ckeywhitelist = list("tabiranth") + character_name = list("Ascian") + /datum/gear/fluff/ascian_spiritspawner path = /obj/item/weapon/grenade/spawnergrenade/spirit display_name = "The Best Kitten" diff --git a/code/modules/client/preference_setup/loadout/loadout_general.dm b/code/modules/client/preference_setup/loadout/loadout_general.dm index 542348fec4d..719eb6fcfc1 100644 --- a/code/modules/client/preference_setup/loadout/loadout_general.dm +++ b/code/modules/client/preference_setup/loadout/loadout_general.dm @@ -76,6 +76,7 @@ description = "Choose from a number of toys." path = /obj/item/toy/ +/* VOREStation removal /datum/gear/toy/New() ..() var/toytype = list() @@ -86,7 +87,7 @@ toytype["Magic 8 Ball"] = /obj/item/toy/eight_ball toytype["Magic Conch shell"] = /obj/item/toy/eight_ball/conch gear_tweaks += new/datum/gear_tweak/path(toytype) - +*/ /datum/gear/flask display_name = "flask" diff --git a/code/modules/client/preference_setup/loadout/loadout_general_vr.dm b/code/modules/client/preference_setup/loadout/loadout_general_vr.dm index 09093b65673..8f11a56b372 100644 --- a/code/modules/client/preference_setup/loadout/loadout_general_vr.dm +++ b/code/modules/client/preference_setup/loadout/loadout_general_vr.dm @@ -9,4 +9,83 @@ for(var/ball in typesof(/obj/item/toy/tennis/)) var/obj/item/toy/tennis/ball_type = ball balls[initial(ball_type.name)] = ball_type - gear_tweaks += new/datum/gear_tweak/path(sortAssoc(balls)) \ No newline at end of file + gear_tweaks += new/datum/gear_tweak/path(sortAssoc(balls)) + +/datum/gear/character/ + display_name = "miniature selection" + description = "Choose from a number of miniatures. From Battlemace 40 million to Grottos and Ghouls." + path = /obj/item/toy/character/alien + +/datum/gear/character/New() + ..() + var/list/characters = list() + for(var/character in typesof(/obj/item/toy/character/) - /obj/item/toy/character) + var/obj/item/toy/character/character_type = character + characters[initial(character_type.name)] = character_type + gear_tweaks += new/datum/gear_tweak/path(sortAssoc(characters)) + +/datum/gear/mechtoy/ + display_name = "mecha toy selection" + description = "Choose from a number of mech toys." + path = /obj/item/toy/mecha/ripley + +/datum/gear/mechtoy/New() + ..() + var/list/mechs = list() + for(var/mech in typesof(/obj/item/toy/mecha/) - /obj/item/toy/mecha/) + var/obj/item/toy/mecha/mech_type = mech + mechs[initial(mech_type.name)] = mech_type + gear_tweaks += new/datum/gear_tweak/path(sortAssoc(mechs)) + +/datum/gear/toy/New() + ..() + var/toytype = list() + toytype["Blink toy"] = /obj/item/toy/blink + toytype["Foam dart crossbow"] = /obj/item/toy/blink + toytype["Toy sword"] = /obj/item/toy/sword + toytype["Toy katana"] = /obj/item/toy/katana + toytype["Snap pops"] = /obj/item/weapon/storage/box/snappops + toytype["Plastic flowers"] = /obj/item/toy/bouquet/fake + toytype["Stick horse"] = /obj/item/toy/stickhorse + toytype["Toy X-mas tree"] = /obj/item/toy/xmastree + toytype["Fake handcuff kit"] = /obj/item/weapon/storage/box/handcuffs/fake + toytype["Gravitational singularity"] = /obj/item/toy/spinningtoy + toytype["Water flower"] = /obj/item/weapon/reagent_containers/spray/waterflower + toytype["Bosun's whistle"] = /obj/item/toy/bosunwhistle + toytype["Magic 8 Ball"] = /obj/item/toy/eight_ball + toytype["Magic Conch shell"] = /obj/item/toy/eight_ball/conch + toytype["Pet rock"] = /obj/item/toy/rock + toytype["Toy flash"] = /obj/item/toy/flash + toytype["Big Red Button"] = /obj/item/toy/redbutton + toytype["Garden gnome"] = /obj/item/toy/gnome + toytype["Toy AI"] = /obj/item/toy/AI + toytype["Hand buzzer"] = /obj/item/clothing/gloves/ring/buzzer/toy + toytype["Toy nuke"] = /obj/item/toy/nuke + toytype["Toy gibber"] = /obj/item/toy/minigibber + toytype["Toy xeno"] = /obj/item/toy/toy_xeno + gear_tweaks += new/datum/gear_tweak/path(toytype) + +/datum/gear/chewtoy + display_name = "animal toy selection" + path = /obj/item/toy/chewtoy + +/datum/gear/chewtoy/New() + ..() + var/toytype = list() + toytype["Bone"] = /obj/item/toy/chewtoy + toytype["Classic"] = /obj/item/toy/chewtoy/tall + toytype["Mouse"] = /obj/item/toy/cat_toy + toytype["Feather rod"] = /obj/item/toy/cat_toy/rod + gear_tweaks += new/datum/gear_tweak/path(toytype) + +/datum/gear/chewtoy_poly + display_name = "animal toy selection, colorable" + path = /obj/item/toy/chewtoy/poly + +/datum/gear/chewtoy_poly/New() + ..() + var/toytype = list() + toytype["Bone"] = /obj/item/toy/chewtoy/poly + toytype["Classic"] = /obj/item/toy/chewtoy/tall/poly + gear_tweaks += new/datum/gear_tweak/path(toytype) + gear_tweaks += gear_tweak_free_color_choice diff --git a/code/modules/client/preference_setup/preference_setup.dm b/code/modules/client/preference_setup/preference_setup.dm index aaec0a08401..f607b9945ff 100644 --- a/code/modules/client/preference_setup/preference_setup.dm +++ b/code/modules/client/preference_setup/preference_setup.dm @@ -129,6 +129,7 @@ for(var/datum/category_item/player_setup_item/PI in items) PI.load_character(S) + /datum/category_group/player_setup_category/proc/save_character(var/savefile/S) // Sanitize all data, then save it for(var/datum/category_item/player_setup_item/PI in items) diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 0c32155812c..a98e0898510 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -169,8 +169,8 @@ datum/preferences if(!IsGuestKey(C.key)) load_path(C.ckey) if(load_preferences()) - if(load_character()) - return + load_character() + /datum/preferences/Destroy() . = ..() diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm index cb25e733967..cb2b3cf0b34 100644 --- a/code/modules/client/preferences_savefile.dm +++ b/code/modules/client/preferences_savefile.dm @@ -82,10 +82,8 @@ player_setup.load_character(S) S.cd = "/character[default_slot]" player_setup.save_character(S) - sanitize_preferences() - player_setup.load_character(S) - clear_character_previews() // Recalculate them on next show + clear_character_previews() // VOREStation Edit return 1 /datum/preferences/proc/save_character() diff --git a/code/modules/clothing/head/pilot_helmet_vr.dm b/code/modules/clothing/head/pilot_helmet_vr.dm new file mode 100644 index 00000000000..acf700f81f7 --- /dev/null +++ b/code/modules/clothing/head/pilot_helmet_vr.dm @@ -0,0 +1,33 @@ +//Overmap pilots. Same gear, without the dumb interface. + +/obj/item/clothing/head/ompilot + name = "pilot helmet" + desc = "Standard pilot gear. Protects the head from impacts." + icon_state = "pilot_helmet1" + item_icons = list(slot_head_str = 'icons/mob/pilot_helmet.dmi') + sprite_sheets = list( + SPECIES_TESHARI = 'icons/mob/species/teshari/pilot_helmet.dmi' + ) + flags = THICKMATERIAL + armor = list(melee = 20, bullet = 10, laser = 10, energy = 5, bomb = 10, bio = 0, rad = 0) + flags_inv = HIDEEARS + cold_protection = HEAD + min_cold_protection_temperature = HELMET_MIN_COLD_PROTECTION_TEMPERATURE + heat_protection = HEAD + max_heat_protection_temperature = HELMET_MAX_HEAT_PROTECTION_TEMPERATURE + w_class = ITEMSIZE_NORMAL + +/obj/item/clothing/head/ompilot/alt + name = "pilot helmet" + desc = "Standard pilot gear. Protects the head from impacts. This one has a retractable visor" + icon_state = "pilot_helmet2" + action_button_name = "Toggle Visor" + +/obj/item/clothing/head/ompilot/alt/attack_self(mob/user as mob) + if(src.icon_state == initial(icon_state)) + src.icon_state = "[icon_state]up" + to_chat(user, "You raise the visor on the pilot helmet.") + else + src.icon_state = initial(icon_state) + to_chat(user, "You lower the visor on the pilot helmet.") + update_clothing_icon() //so our mob-overlays update \ No newline at end of file diff --git a/code/modules/clothing/suits/utility.dm b/code/modules/clothing/suits/utility.dm index 0ecbe0390d6..0dde614e048 100644 --- a/code/modules/clothing/suits/utility.dm +++ b/code/modules/clothing/suits/utility.dm @@ -78,7 +78,7 @@ * Radiation protection */ /obj/item/clothing/head/radiation - name = "Radiation Hood" + name = "Radiation hood" icon_state = "rad" desc = "A hood with radiation protective properties. Label: Made with lead, do not eat insulation" flags_inv = BLOCKHAIR @@ -98,4 +98,20 @@ slowdown = 1.5 armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 60, rad = 100) flags_inv = HIDEJUMPSUIT|HIDETAIL|HIDETIE|HIDEHOLSTER - item_flags = THICKMATERIAL \ No newline at end of file + item_flags = THICKMATERIAL + +/obj/item/clothing/suit/radiation/teshari + name = "Small radiation suit" + desc = "A specialist suit that protects against radiation, designed specifically for use by Teshari. Made to order by Aether." + icon = 'icons/obj/clothing/species/teshari/suits.dmi' + icon_override = 'icons/mob/species/teshari/suit.dmi' + icon_state = "rad_fitted" + species_restricted = list(SPECIES_TESHARI) + +/obj/item/clothing/head/radiation/teshari + name = "Small radiation hood" + desc = "A specialist hood with radiation protective properties, designed specifically for use by Teshari. Made to order by Aether." + icon = 'icons/obj/clothing/species/teshari/hats.dmi' + icon_override = 'icons/mob/species/teshari/head.dmi' + icon_state = "rad_fitted" + species_restricted = list(SPECIES_TESHARI) \ No newline at end of file diff --git a/code/modules/clothing/under/accessories/accessory_vr.dm b/code/modules/clothing/under/accessories/accessory_vr.dm index 85c28047585..5422e294b4e 100644 --- a/code/modules/clothing/under/accessories/accessory_vr.dm +++ b/code/modules/clothing/under/accessories/accessory_vr.dm @@ -365,4 +365,4 @@ icon_state = "silverthree" item_state = "silverthree" overlay_state = "silverthree" - desc = "A silver medal awarded to a group which has demonstrated exceptional teamwork to achieve a notable feat. This one has two bronze service stars, denoting that it has been awarded three times." + desc = "A silver medal awarded to a group which has demonstrated exceptional teamwork to achieve a notable feat. This one has three bronze service stars, denoting that it has been awarded four times." diff --git a/code/modules/clothing/under/accessories/holster_vr.dm b/code/modules/clothing/under/accessories/holster_vr.dm index 75cb4ccc9e7..f99e798faa8 100644 --- a/code/modules/clothing/under/accessories/holster_vr.dm +++ b/code/modules/clothing/under/accessories/holster_vr.dm @@ -1,4 +1,53 @@ /obj/item/clothing/accessory/holster/waist/kinetic_accelerator name = "KA holster" desc = "A specialized holster, made specifically for Kinetic Accelerator." - can_hold = list(/obj/item/weapon/gun/energy/kinetic_accelerator) \ No newline at end of file + can_hold = list(/obj/item/weapon/gun/energy/kinetic_accelerator) + +/obj/item/clothing/accessory/holster/machete/rapier + name = "rapier sheath" + desc = "A beautiful red sheath, probably for a beautiful blade." + icon = 'icons/obj/clothing/ties_vr.dmi' + icon_state = "sheath" + slot_flags = SLOT_BELT|ACCESSORY_SLOT_WEAPON + var/has_full_icon = 1 + icon_override = 'icons/mob/ties_vr.dmi' + overlay_state = "sheath" + can_hold = list(/obj/item/weapon/melee/rapier) + +/obj/item/clothing/accessory/holster/machete/rapier/swords + name = "sword sheath" + desc = "A beautiful red sheath, probably for a beautiful blade." + can_hold = list( + /obj/item/weapon/melee/rapier, + /obj/item/weapon/material/sword/katana, + /obj/item/toy/cultsword, + /obj/item/weapon/material/sword, + /obj/item/weapon/melee/cursedblade, + /obj/item/weapon/melee/cultblade + ) + +/obj/item/clothing/accessory/holster/machete/rapier/proc/occupied() + if(!has_full_icon) + return + if(contents.len) + overlay_state = "[initial(overlay_state)]-rapier" + else + overlay_state = initial(overlay_state) + +/obj/item/clothing/accessory/holster/machete/rapier/swords/occupied() + if(!has_full_icon) + return + if(contents.len) + overlay_state = "[initial(overlay_state)]-secondary" + else + overlay_state = initial(overlay_state) + +/obj/item/clothing/accessory/holster/machete/rapier/holster(var/obj/item/I, var/mob/living/user) + ..() + occupied() + has_suit.update_clothing_icon() + +/obj/item/clothing/accessory/holster/machete/rapier/unholster(var/obj/item/I, var/mob/living/user) + ..() + occupied() + has_suit.update_clothing_icon() diff --git a/code/modules/mining/coins.dm b/code/modules/economy/coins.dm similarity index 100% rename from code/modules/mining/coins.dm rename to code/modules/economy/coins.dm diff --git a/code/modules/mining/mint.dm b/code/modules/economy/mint.dm similarity index 100% rename from code/modules/mining/mint.dm rename to code/modules/economy/mint.dm diff --git a/code/modules/mining/money_bag.dm b/code/modules/economy/money_bag.dm similarity index 95% rename from code/modules/mining/money_bag.dm rename to code/modules/economy/money_bag.dm index fd1cb561b0e..3e85d62e460 100644 --- a/code/modules/mining/money_bag.dm +++ b/code/modules/economy/money_bag.dm @@ -1,98 +1,98 @@ -/*****************************Money bag********************************/ - -/obj/item/weapon/moneybag - icon = 'icons/obj/storage.dmi' - name = "Money bag" - icon_state = "moneybag" - force = 10.0 - throwforce = 2.0 - w_class = ITEMSIZE_LARGE - -/obj/item/weapon/moneybag/attack_hand(user as mob) - var/amt_gold = 0 - var/amt_silver = 0 - var/amt_diamond = 0 - var/amt_iron = 0 - var/amt_phoron = 0 - var/amt_uranium = 0 - - for (var/obj/item/weapon/coin/C in contents) - if (istype(C,/obj/item/weapon/coin/diamond)) - amt_diamond++; - if (istype(C,/obj/item/weapon/coin/phoron)) - amt_phoron++; - if (istype(C,/obj/item/weapon/coin/iron)) - amt_iron++; - if (istype(C,/obj/item/weapon/coin/silver)) - amt_silver++; - if (istype(C,/obj/item/weapon/coin/gold)) - amt_gold++; - if (istype(C,/obj/item/weapon/coin/uranium)) - amt_uranium++; - - var/dat = text("The contents of the moneybag reveal...
") - if (amt_gold) - dat += text("Gold coins: [amt_gold] Remove one
") - if (amt_silver) - dat += text("Silver coins: [amt_silver] Remove one
") - if (amt_iron) - dat += text("Metal coins: [amt_iron] Remove one
") - if (amt_diamond) - dat += text("Diamond coins: [amt_diamond] Remove one
") - if (amt_phoron) - dat += text("Phoron coins: [amt_phoron] Remove one
") - if (amt_uranium) - dat += text("Uranium coins: [amt_uranium] Remove one
") - user << browse("[dat]", "window=moneybag") - -/obj/item/weapon/moneybag/attackby(obj/item/weapon/W as obj, mob/user as mob) - ..() - if (istype(W, /obj/item/weapon/coin)) - var/obj/item/weapon/coin/C = W - to_chat(user, "You add the [C.name] into the bag.") - usr.drop_item() - contents += C - if (istype(W, /obj/item/weapon/moneybag)) - var/obj/item/weapon/moneybag/C = W - for (var/obj/O in C.contents) - contents += O; - to_chat(user, "You empty the [C.name] into the bag.") - return - -/obj/item/weapon/moneybag/Topic(href, href_list) - if(..()) - return 1 - usr.set_machine(src) - src.add_fingerprint(usr) - if(href_list["remove"]) - var/obj/item/weapon/coin/COIN - switch(href_list["remove"]) - if("gold") - COIN = locate(/obj/item/weapon/coin/gold,src.contents) - if("silver") - COIN = locate(/obj/item/weapon/coin/silver,src.contents) - if("iron") - COIN = locate(/obj/item/weapon/coin/iron,src.contents) - if("diamond") - COIN = locate(/obj/item/weapon/coin/diamond,src.contents) - if("phoron") - COIN = locate(/obj/item/weapon/coin/phoron,src.contents) - if("uranium") - COIN = locate(/obj/item/weapon/coin/uranium,src.contents) - if(!COIN) - return - COIN.loc = src.loc - return - - - -/obj/item/weapon/moneybag/vault - -/obj/item/weapon/moneybag/vault/New() - ..() - new /obj/item/weapon/coin/silver(src) - new /obj/item/weapon/coin/silver(src) - new /obj/item/weapon/coin/silver(src) - new /obj/item/weapon/coin/silver(src) - new /obj/item/weapon/coin/gold(src) +/*****************************Money bag********************************/ + +/obj/item/weapon/moneybag + icon = 'icons/obj/storage.dmi' + name = "Money bag" + icon_state = "moneybag" + force = 10.0 + throwforce = 2.0 + w_class = ITEMSIZE_LARGE + +/obj/item/weapon/moneybag/attack_hand(user as mob) + var/amt_gold = 0 + var/amt_silver = 0 + var/amt_diamond = 0 + var/amt_iron = 0 + var/amt_phoron = 0 + var/amt_uranium = 0 + + for (var/obj/item/weapon/coin/C in contents) + if (istype(C,/obj/item/weapon/coin/diamond)) + amt_diamond++; + if (istype(C,/obj/item/weapon/coin/phoron)) + amt_phoron++; + if (istype(C,/obj/item/weapon/coin/iron)) + amt_iron++; + if (istype(C,/obj/item/weapon/coin/silver)) + amt_silver++; + if (istype(C,/obj/item/weapon/coin/gold)) + amt_gold++; + if (istype(C,/obj/item/weapon/coin/uranium)) + amt_uranium++; + + var/dat = text("The contents of the moneybag reveal...
") + if (amt_gold) + dat += text("Gold coins: [amt_gold] Remove one
") + if (amt_silver) + dat += text("Silver coins: [amt_silver] Remove one
") + if (amt_iron) + dat += text("Metal coins: [amt_iron] Remove one
") + if (amt_diamond) + dat += text("Diamond coins: [amt_diamond] Remove one
") + if (amt_phoron) + dat += text("Phoron coins: [amt_phoron] Remove one
") + if (amt_uranium) + dat += text("Uranium coins: [amt_uranium] Remove one
") + user << browse("[dat]", "window=moneybag") + +/obj/item/weapon/moneybag/attackby(obj/item/weapon/W as obj, mob/user as mob) + ..() + if (istype(W, /obj/item/weapon/coin)) + var/obj/item/weapon/coin/C = W + to_chat(user, "You add the [C.name] into the bag.") + usr.drop_item() + contents += C + if (istype(W, /obj/item/weapon/moneybag)) + var/obj/item/weapon/moneybag/C = W + for (var/obj/O in C.contents) + contents += O; + to_chat(user, "You empty the [C.name] into the bag.") + return + +/obj/item/weapon/moneybag/Topic(href, href_list) + if(..()) + return 1 + usr.set_machine(src) + src.add_fingerprint(usr) + if(href_list["remove"]) + var/obj/item/weapon/coin/COIN + switch(href_list["remove"]) + if("gold") + COIN = locate(/obj/item/weapon/coin/gold,src.contents) + if("silver") + COIN = locate(/obj/item/weapon/coin/silver,src.contents) + if("iron") + COIN = locate(/obj/item/weapon/coin/iron,src.contents) + if("diamond") + COIN = locate(/obj/item/weapon/coin/diamond,src.contents) + if("phoron") + COIN = locate(/obj/item/weapon/coin/phoron,src.contents) + if("uranium") + COIN = locate(/obj/item/weapon/coin/uranium,src.contents) + if(!COIN) + return + COIN.loc = src.loc + return + + + +/obj/item/weapon/moneybag/vault + +/obj/item/weapon/moneybag/vault/New() + ..() + new /obj/item/weapon/coin/silver(src) + new /obj/item/weapon/coin/silver(src) + new /obj/item/weapon/coin/silver(src) + new /obj/item/weapon/coin/silver(src) + new /obj/item/weapon/coin/gold(src) new /obj/item/weapon/coin/gold(src) \ No newline at end of file diff --git a/code/modules/economy/price_list.dm b/code/modules/economy/price_list.dm index 9e3fb438d82..839148ebaf2 100644 --- a/code/modules/economy/price_list.dm +++ b/code/modules/economy/price_list.dm @@ -13,7 +13,7 @@ //---Beverages---// //***************// -/datum/reagent/var/price_tag = null +/datum/reagent/var/price_tag = 0 // Juices, soda and similar // diff --git a/code/game/machinery/vending.dm b/code/modules/economy/vending.dm similarity index 96% rename from code/game/machinery/vending.dm rename to code/modules/economy/vending.dm index 58107d9d0b4..36adfb63921 100644 --- a/code/game/machinery/vending.dm +++ b/code/modules/economy/vending.dm @@ -1,720 +1,723 @@ -/// -/// A vending machine -/// - -// -// ALL THE VENDING MACHINES ARE IN vending_machines.dm now! -// - -/obj/machinery/vending - name = "Vendomat" - desc = "A generic vending machine." - icon = 'icons/obj/vending.dmi' - icon_state = "generic" - anchored = 1 - density = 1 - clicksound = "button" - - // Power - use_power = USE_POWER_IDLE - idle_power_usage = 10 - var/vend_power_usage = 150 //actuators and stuff - - // Vending-related - var/active = 1 //No sales pitches if off! - var/vend_ready = 1 //Are we ready to vend?? Is it time?? - var/vend_delay = 10 //How long does it take to vend? - var/categories = CAT_NORMAL // Bitmask of cats we're currently showing - var/datum/stored_item/vending_product/currently_vending = null // What we're requesting payment for right now - var/vending_sound = "machines/vending/vending_drop.ogg" - - /* - Variables used to initialize the product list - These are used for initialization only, and so are optional if - product_records is specified - */ - var/list/products = list() // For each, use the following pattern: - var/list/contraband = list() // list(/type/path = amount,/type/path2 = amount2) - var/list/premium = list() // No specified amount = only one in stock - var/list/prices = list() // Prices for each item, list(/type/path = price), items not in the list don't have a price. - - // List of vending_product items available. - var/list/product_records = list() - - - // Variables used to initialize advertising - var/product_slogans = "" //String of slogans spoken out loud, separated by semicolons - var/product_ads = "" //String of small ad messages in the vending screen - - var/list/ads_list = list() - - // Stuff relating vocalizations - var/list/slogan_list = list() - var/shut_up = 1 //Stop spouting those godawful pitches! - var/vend_reply //Thank you for shopping! - var/last_reply = 0 - var/last_slogan = 0 //When did we last pitch? - var/slogan_delay = 6000 //How long until we can pitch again? - - // Things that can go wrong - emagged = 0 //Ignores if somebody doesn't have card access to that machine. - var/seconds_electrified = 0 //Shock customers like an airlock. - var/shoot_inventory = 0 //Fire items at customers! We're broken! - - var/scan_id = 1 - var/obj/item/weapon/coin/coin - var/datum/wires/vending/wires = null - - var/list/log = list() - var/req_log_access = access_cargo //default access for checking logs is cargo - var/has_logs = 0 //defaults to 0, set to anything else for vendor to have logs - var/can_rotate = 1 //Defaults to yes, can be set to 0 for vendors without or with unwanted directionals. - - -/obj/machinery/vending/Initialize() - . = ..() - wires = new(src) - if(product_slogans) - slogan_list += splittext(product_slogans, ";") - - // So not all machines speak at the exact same time. - // The first time this machine says something will be at slogantime + this random value, - // so if slogantime is 10 minutes, it will say it at somewhere between 10 and 20 minutes after the machine is crated. - last_slogan = world.time + rand(0, slogan_delay) - - if(product_ads) - ads_list += splittext(product_ads, ";") - - build_inventory() - power_change() - -GLOBAL_LIST_EMPTY(vending_products) -/** - * Build produdct_records from the products lists - * - * products, contraband, premium, and prices allow specifying - * products that the vending machine is to carry without manually populating - * product_records. - */ -/obj/machinery/vending/proc/build_inventory() - var/list/all_products = list( - list(products, CAT_NORMAL), - list(contraband, CAT_HIDDEN), - list(premium, CAT_COIN)) - - for(var/current_list in all_products) - var/category = current_list[2] - - for(var/entry in current_list[1]) - var/datum/stored_item/vending_product/product = new/datum/stored_item/vending_product(src, entry) - - product.price = (entry in prices) ? prices[entry] : 0 - product.amount = (current_list[1][entry]) ? current_list[1][entry] : 1 - product.category = category - - product_records.Add(product) - GLOB.vending_products[entry] = 1 - -/obj/machinery/vending/Destroy() - qdel(wires) - wires = null - qdel(coin) - coin = null - for(var/datum/stored_item/vending_product/R in product_records) - qdel(R) - product_records = null - return ..() - -/obj/machinery/vending/ex_act(severity) - switch(severity) - if(1.0) - qdel(src) - return - if(2.0) - if(prob(50)) - qdel(src) - return - if(3.0) - if(prob(25)) - spawn(0) - malfunction() - return - return - else - return - -/obj/machinery/vending/emag_act(var/remaining_charges, var/mob/user) - if(!emagged) - emagged = 1 - to_chat(user, "You short out \the [src]'s product lock.") - return 1 - -/obj/machinery/vending/attackby(obj/item/weapon/W as obj, mob/user as mob) - var/obj/item/weapon/card/id/I = W.GetID() - - if(I || istype(W, /obj/item/weapon/spacecash)) - attack_hand(user) - return - else if(W.is_screwdriver()) - panel_open = !panel_open - to_chat(user, "You [panel_open ? "open" : "close"] the maintenance panel.") - playsound(src, W.usesound, 50, 1) - if(panel_open) - wires.Interact(user) - add_overlay("[initial(icon_state)]-panel") - else - cut_overlay("[initial(icon_state)]-panel") - - SStgui.update_uis(src) // Speaker switch is on the main UI, not wires UI - return - else if(istype(W, /obj/item/device/multitool) || W.is_wirecutter()) - if(panel_open) - attack_hand(user) - return - else if(istype(W, /obj/item/weapon/coin) && premium.len > 0) - user.drop_item() - W.forceMove(src) - coin = W - categories |= CAT_COIN - to_chat(user, "You insert \the [W] into \the [src].") - SStgui.update_uis(src) - return - else if(W.is_wrench()) - playsound(src, W.usesound, 100, 1) - if(anchored) - user.visible_message("[user] begins unsecuring \the [src] from the floor.", "You start unsecuring \the [src] from the floor.") - else - user.visible_message("[user] begins securing \the [src] to the floor.", "You start securing \the [src] to the floor.") - - if(do_after(user, 20 * W.toolspeed)) - if(!src) return - to_chat(user, "You [anchored? "un" : ""]secured \the [src]!") - anchored = !anchored - return - else - - for(var/datum/stored_item/vending_product/R in product_records) - if(istype(W, R.item_path) && (W.name == R.item_name)) - stock(W, R, user) - return - ..() - -/** - * Receive payment with cashmoney. - * - * usr is the mob who gets the change. - */ -/obj/machinery/vending/proc/pay_with_cash(var/obj/item/weapon/spacecash/cashmoney, mob/user) - if(currently_vending.price > cashmoney.worth) - - // This is not a status display message, since it's something the character - // themselves is meant to see BEFORE putting the money in - to_chat(usr, "[bicon(cashmoney)] That is not enough money.") - return 0 - - if(istype(cashmoney, /obj/item/weapon/spacecash)) - - visible_message("\The [usr] inserts some cash into \the [src].") - cashmoney.worth -= currently_vending.price - - if(cashmoney.worth <= 0) - usr.drop_from_inventory(cashmoney) - qdel(cashmoney) - else - cashmoney.update_icon() - - // Vending machines have no idea who paid with cash - credit_purchase("(cash)") - return 1 - -/** - * Scan a chargecard and deduct payment from it. - * - * Takes payment for whatever is the currently_vending item. Returns 1 if - * successful, 0 if failed. - */ -/obj/machinery/vending/proc/pay_with_ewallet(var/obj/item/weapon/spacecash/ewallet/wallet) - visible_message("\The [usr] swipes \the [wallet] through \the [src].") - playsound(src, 'sound/machines/id_swipe.ogg', 50, 1) - if(currently_vending.price > wallet.worth) - to_chat(usr, "Insufficient funds on chargecard.") - return 0 - else - wallet.worth -= currently_vending.price - credit_purchase("[wallet.owner_name] (chargecard)") - return 1 - -/** - * Scan a card and attempt to transfer payment from associated account. - * - * Takes payment for whatever is the currently_vending item. Returns 1 if - * successful, 0 if failed - */ -/obj/machinery/vending/proc/pay_with_card(obj/item/weapon/card/id/I, mob/M) - visible_message("[M] swipes a card through [src].") - playsound(src, 'sound/machines/id_swipe.ogg', 50, 1) - - var/datum/money_account/customer_account = get_account(I.associated_account_number) - if(!customer_account) - to_chat(M, "Error: Unable to access account. Please contact technical support if problem persists.") - return FALSE - - if(customer_account.suspended) - to_chat(M, "Unable to access account: account suspended.") - return FALSE - - // Have the customer punch in the PIN before checking if there's enough money. Prevents people from figuring out acct is - // empty at high security levels - if(customer_account.security_level != 0) //If card requires pin authentication (ie seclevel 1 or 2) - var/attempt_pin = input("Enter pin code", "Vendor transaction") as num - customer_account = attempt_account_access(I.associated_account_number, attempt_pin, 2) - - if(!customer_account) - to_chat(M, "Unable to access account: incorrect credentials.") - return FALSE - - if(currently_vending.price > customer_account.money) - to_chat(M, "Insufficient funds in account.") - return FALSE - - // Okay to move the money at this point - - // debit money from the purchaser's account - customer_account.money -= currently_vending.price - - // create entry in the purchaser's account log - var/datum/transaction/T = new() - T.target_name = "[vendor_account.owner_name] (via [name])" - T.purpose = "Purchase of [currently_vending.item_name]" - if(currently_vending.price > 0) - T.amount = "([currently_vending.price])" - else - T.amount = "[currently_vending.price]" - T.source_terminal = name - T.date = current_date_string - T.time = stationtime2text() - customer_account.transaction_log.Add(T) - - // Give the vendor the money. We use the account owner name, which means - // that purchases made with stolen/borrowed card will look like the card - // owner made them - credit_purchase(customer_account.owner_name) - return 1 - -/** - * Add money for current purchase to the vendor account. - * - * Called after the money has already been taken from the customer. - */ -/obj/machinery/vending/proc/credit_purchase(var/target as text) - vendor_account.money += currently_vending.price - - var/datum/transaction/T = new() - T.target_name = target - T.purpose = "Purchase of [currently_vending.item_name]" - T.amount = "[currently_vending.price]" - T.source_terminal = name - T.date = current_date_string - T.time = stationtime2text() - vendor_account.transaction_log.Add(T) - -/obj/machinery/vending/attack_ghost(mob/user) - return attack_hand(user) - -/obj/machinery/vending/attack_ai(mob/user as mob) - return attack_hand(user) - -/obj/machinery/vending/attack_hand(mob/user as mob) - if(stat & (BROKEN|NOPOWER)) - return - - if(seconds_electrified != 0) - if(shock(user, 100)) - return - - wires.Interact(user) - tgui_interact(user) - -/obj/machinery/vending/ui_assets(mob/user) - return list( - get_asset_datum(/datum/asset/spritesheet/vending), - ) - -/obj/machinery/vending/tgui_interact(mob/user, datum/tgui/ui) - ui = SStgui.try_update_ui(user, src, ui) - if(!ui) - ui = new(user, src, "Vending", name) - ui.open() - -/obj/machinery/vending/tgui_data(mob/user) - var/list/data = list() - var/list/listed_products = list() - - data["chargesMoney"] = length(prices) > 0 ? TRUE : FALSE - for(var/key = 1 to product_records.len) - var/datum/stored_item/vending_product/I = product_records[key] - - if(!(I.category & categories)) - continue - - listed_products.Add(list(list( - "key" = key, - "name" = I.item_name, - "price" = I.price, - "color" = I.display_color, - "isatom" = ispath(I.item_path, /atom), - "path" = replacetext(replacetext("[I.item_path]", "/obj/item/", ""), "/", "-"), - "amount" = I.get_amount() - ))) - - data["products"] = listed_products - - if(coin) - data["coin"] = coin.name - else - data["coin"] = FALSE - - if(currently_vending) - data["actively_vending"] = currently_vending.item_name - else - data["actively_vending"] = null - - if(panel_open) - data["panel"] = 1 - data["speaker"] = shut_up ? 0 : 1 - else - data["panel"] = 0 - - var/mob/living/carbon/human/H - var/obj/item/weapon/card/id/C - - data["guestNotice"] = "No valid ID card detected. Wear your ID, or present cash."; - data["userMoney"] = 0 - data["user"] = null - if(ishuman(user)) - H = user - C = H.GetIdCard() - var/obj/item/weapon/spacecash/S = H.get_active_hand() - if(istype(S)) - data["userMoney"] = S.worth - data["guestNotice"] = "Accepting [S.initial_name]. You have: [S.worth]â‚®." - else if(istype(C)) - var/datum/money_account/A = get_account(C.associated_account_number) - if(istype(A)) - data["user"] = list() - data["user"]["name"] = A.owner_name - data["userMoney"] = A.money - data["user"]["job"] = (istype(C) && C.rank) ? C.rank : "No Job" - else - data["guestNotice"] = "Unlinked ID detected. Present cash to pay."; - - return data - -/obj/machinery/vending/tgui_act(action, params) - if(stat & (BROKEN|NOPOWER)) - return - if(usr.stat || usr.restrained()) - return - if(..()) - return TRUE - - . = TRUE - switch(action) - if("remove_coin") - if(issilicon(usr)) - return FALSE - - if(!coin) - to_chat(usr, "There is no coin in this machine.") - return - - coin.forceMove(src.loc) - if(!usr.get_active_hand()) - usr.put_in_hands(coin) - - to_chat(usr, "You remove \the [coin] from \the [src].") - coin = null - categories &= ~CAT_COIN - return TRUE - if("vend") - if(!vend_ready) - to_chat(usr, "[src] is busy!") - return - if(!allowed(usr) && !emagged && scan_id) - to_chat(usr, "Access denied.") //Unless emagged of course - flick("[icon_state]-deny",src) - playsound(src, 'sound/machines/deniedbeep.ogg', 50, 0) - return - if(panel_open) - to_chat(usr, "[src] cannot dispense products while its service panel is open!") - return - - var/key = text2num(params["vend"]) - var/datum/stored_item/vending_product/R = product_records[key] - - // This should not happen unless the request from NanoUI was bad - if(!(R.category & categories)) - return - - if(!can_buy(R, usr)) - return - if(R.price <= 0) - vend(R, usr) - add_fingerprint(usr) - return TRUE - - if(issilicon(usr)) //If the item is not free, provide feedback if a synth is trying to buy something. - to_chat(usr, "Lawed unit recognized. Lawed units cannot complete this transaction. Purchase canceled.") - return - if(!ishuman(usr)) - return - - - vend_ready = FALSE // From this point onwards, vendor is locked to performing this transaction only, until it is resolved. - - var/mob/living/carbon/human/H = usr - var/obj/item/weapon/card/id/C = H.GetIdCard() - - if(!vendor_account || vendor_account.suspended) - to_chat(usr, "Vendor account offline. Unable to process transaction.") - flick("[icon_state]-deny",src) - vend_ready = TRUE - return - - currently_vending = R - - var/paid = FALSE - - if(istype(usr.get_active_hand(), /obj/item/weapon/spacecash)) - var/obj/item/weapon/spacecash/cash = usr.get_active_hand() - paid = pay_with_cash(cash, usr) - else if(istype(usr.get_active_hand(), /obj/item/weapon/spacecash/ewallet)) - var/obj/item/weapon/spacecash/ewallet/wallet = usr.get_active_hand() - paid = pay_with_ewallet(wallet) - else if(istype(C, /obj/item/weapon/card)) - paid = pay_with_card(C, usr) - /*else if(usr.can_advanced_admin_interact()) - to_chat(usr, "Vending object due to admin interaction.") - paid = TRUE*/ - else - to_chat(usr, "Payment failure: you have no ID or other method of payment.") - vend_ready = TRUE - flick("[icon_state]-deny",src) - return TRUE // we set this because they shouldn't even be able to get this far, and we want the UI to update. - if(paid) - vend(currently_vending, usr) // vend will handle vend_ready - . = TRUE - else - to_chat(usr, "Payment failure: unable to process payment.") - vend_ready = TRUE - - if("togglevoice") - if(!panel_open) - return FALSE - shut_up = !shut_up - -/obj/machinery/vending/proc/can_buy(datum/stored_item/vending_product/R, mob/user) - if(!allowed(user) && !emagged && scan_id) - to_chat(user, "Access denied.") //Unless emagged of course - flick("[icon_state]-deny",src) - playsound(src, 'sound/machines/deniedbeep.ogg', 50, 0) - return FALSE - return TRUE - -/obj/machinery/vending/proc/vend(datum/stored_item/vending_product/R, mob/user) - if(!can_buy(R, user)) - return - - if(!R.amount) - to_chat(user, "[src] has ran out of that product.") - vend_ready = TRUE - return - - vend_ready = FALSE //One thing at a time!! - SStgui.update_uis(src) - - if(R.category & CAT_COIN) - if(!coin) - to_chat(user, "You need to insert a coin to get this item.") - return - if(coin.string_attached) - if(prob(50)) - to_chat(user, "You successfully pull the coin out before \the [src] could swallow it.") - else - to_chat(user, "You weren't able to pull the coin out fast enough, the machine ate it, string and all.") - qdel(coin) - coin = null - categories &= ~CAT_COIN - else - qdel(coin) - coin = null - categories &= ~CAT_COIN - - if(((last_reply + (vend_delay + 200)) <= world.time) && vend_reply) - spawn(0) - speak(vend_reply) - last_reply = world.time - - use_power(vend_power_usage) //actuators and stuff - flick("[icon_state]-vend",src) - addtimer(CALLBACK(src, .proc/delayed_vend, R, user), vend_delay) - -/obj/machinery/vending/proc/delayed_vend(datum/stored_item/vending_product/R, mob/user) - R.get_product(get_turf(src)) - if(has_logs) - do_logging(R, user, 1) - if(prob(1)) - sleep(3) - if(R.get_product(get_turf(src))) - visible_message("\The [src] clunks as it vends an additional item.") - playsound(src, "sound/[vending_sound]", 100, 1, 1) - - vend_ready = 1 - currently_vending = null - SStgui.update_uis(src) - GLOB.items_sold_shift_roundstat++ - -/obj/machinery/vending/proc/do_logging(datum/stored_item/vending_product/R, mob/user, var/vending = 0) - if(user.GetIdCard()) - var/obj/item/weapon/card/id/tempid = user.GetIdCard() - var/list/list_item = list() - if(vending) - list_item += "vend" - else - list_item += "stock" - list_item += tempid.registered_name - list_item += stationtime2text() - list_item += R.item_name - log[++log.len] = list_item - -/obj/machinery/vending/proc/show_log(mob/user as mob) - if(user.GetIdCard()) - var/obj/item/weapon/card/id/tempid = user.GetIdCard() - if(req_log_access in tempid.GetAccess()) - var/datum/browser/popup = new(user, "vending_log", "Vending Log", 700, 500) - var/dat = "" - dat += "
[name] Vending Log
" - dat += "
Welcome [user.name]!

" - dat += "Below are the recent vending logs for your vending machine.
" - for(var/i in log) - dat += json_encode(i) - dat += ";
" - popup.set_content(dat) - popup.open() - else - to_chat(user,"You do not have the required access to view the vending logs for this machine.") - - -/obj/machinery/vending/verb/rotate_clockwise() - set name = "Rotate Vending Machine Clockwise" - set category = "Object" - set src in oview(1) - - if (src.can_rotate == 0) - to_chat(usr, "\The [src] cannot be rotated.") - return 0 - - if (src.anchored || usr:stat) - to_chat(usr, "It is bolted down!") - return 0 - src.set_dir(turn(src.dir, 270)) - return 1 - -/obj/machinery/vending/verb/check_logs() - set name = "Check Vending Logs" - set category = "Object" - set src in oview(1) - - show_log(usr) - -/** - * Add item to the machine - * - * Checks if item is vendable in this machine should be performed before - * calling. W is the item being inserted, R is the associated vending_product entry. - */ -/obj/machinery/vending/proc/stock(obj/item/weapon/W, var/datum/stored_item/vending_product/R, var/mob/user) - if(!user.unEquip(W)) - return - - to_chat(user, "You insert \the [W] in the product receptor.") - R.add_product(W) - if(has_logs) - do_logging(R, user) - - SStgui.update_uis(src) - -/obj/machinery/vending/process() - if(stat & (BROKEN|NOPOWER)) - return - - if(!active) - return - - if(seconds_electrified > 0) - seconds_electrified-- - - //Pitch to the people! Really sell it! - if(((last_slogan + slogan_delay) <= world.time) && (slogan_list.len > 0) && (!shut_up) && prob(5)) - var/slogan = pick(slogan_list) - speak(slogan) - last_slogan = world.time - - if(shoot_inventory && prob(2)) - throw_item() - - return - -/obj/machinery/vending/proc/speak(var/message) - if(stat & NOPOWER) - return - - if(!message) - return - - for(var/mob/O in hearers(src, null)) - O.show_message("\The [src] beeps, \"[message]\"",2) - return - -/obj/machinery/vending/power_change() - ..() - if(stat & BROKEN) - icon_state = "[initial(icon_state)]-broken" - else - if(!(stat & NOPOWER)) - icon_state = initial(icon_state) - else - spawn(rand(0, 15)) - icon_state = "[initial(icon_state)]-off" - -//Oh no we're malfunctioning! Dump out some product and break. -/obj/machinery/vending/proc/malfunction() - for(var/datum/stored_item/vending_product/R in product_records) - while(R.get_amount()>0) - R.get_product(loc) - break - - stat |= BROKEN - icon_state = "[initial(icon_state)]-broken" - return - -//Somebody cut an important wire and now we're following a new definition of "pitch." -/obj/machinery/vending/proc/throw_item() - var/obj/throw_item = null - var/mob/living/target = locate() in view(7,src) - if(!target) - return 0 - - for(var/datum/stored_item/vending_product/R in product_records) - throw_item = R.get_product(loc) - if(!throw_item) - continue - break - if(!throw_item) - return 0 - spawn(0) - throw_item.throw_at(target, 16, 3, src) - visible_message("\The [src] launches \a [throw_item] at \the [target]!") - return 1 - -//Actual machines are in vending_machines.dm +/// +/// A vending machine +/// + +// +// ALL THE VENDING MACHINES ARE IN vending_machines.dm now! +// + +/obj/machinery/vending + name = "Vendomat" + desc = "A generic vending machine." + icon = 'icons/obj/vending.dmi' + icon_state = "generic" + anchored = 1 + density = 1 + clicksound = "button" + + // Power + use_power = USE_POWER_IDLE + idle_power_usage = 10 + var/vend_power_usage = 150 //actuators and stuff + + // Vending-related + var/active = 1 //No sales pitches if off! + var/vend_ready = 1 //Are we ready to vend?? Is it time?? + var/vend_delay = 10 //How long does it take to vend? + var/categories = CAT_NORMAL // Bitmask of cats we're currently showing + var/datum/stored_item/vending_product/currently_vending = null // What we're requesting payment for right now + var/vending_sound = "machines/vending/vending_drop.ogg" + + /* + Variables used to initialize the product list + These are used for initialization only, and so are optional if + product_records is specified + */ + var/list/products = list() // For each, use the following pattern: + var/list/contraband = list() // list(/type/path = amount,/type/path2 = amount2) + var/list/premium = list() // No specified amount = only one in stock + var/list/prices = list() // Prices for each item, list(/type/path = price), items not in the list don't have a price. + + // List of vending_product items available. + var/list/product_records = list() + + + // Variables used to initialize advertising + var/product_slogans = "" //String of slogans spoken out loud, separated by semicolons + var/product_ads = "" //String of small ad messages in the vending screen + + var/list/ads_list = list() + + // Stuff relating vocalizations + var/list/slogan_list = list() + var/shut_up = 1 //Stop spouting those godawful pitches! + var/vend_reply //Thank you for shopping! + var/last_reply = 0 + var/last_slogan = 0 //When did we last pitch? + var/slogan_delay = 6000 //How long until we can pitch again? + + // Things that can go wrong + emagged = 0 //Ignores if somebody doesn't have card access to that machine. + var/seconds_electrified = 0 //Shock customers like an airlock. + var/shoot_inventory = 0 //Fire items at customers! We're broken! + + var/scan_id = 1 + var/obj/item/weapon/coin/coin + var/datum/wires/vending/wires = null + + var/list/log = list() + var/req_log_access = access_cargo //default access for checking logs is cargo + var/has_logs = 0 //defaults to 0, set to anything else for vendor to have logs + var/can_rotate = 1 //Defaults to yes, can be set to 0 for vendors without or with unwanted directionals. + + +/obj/machinery/vending/Initialize() + . = ..() + wires = new(src) + if(product_slogans) + slogan_list += splittext(product_slogans, ";") + + // So not all machines speak at the exact same time. + // The first time this machine says something will be at slogantime + this random value, + // so if slogantime is 10 minutes, it will say it at somewhere between 10 and 20 minutes after the machine is crated. + last_slogan = world.time + rand(0, slogan_delay) + + if(product_ads) + ads_list += splittext(product_ads, ";") + + build_inventory() + power_change() + +GLOBAL_LIST_EMPTY(vending_products) +/** + * Build produdct_records from the products lists + * + * products, contraband, premium, and prices allow specifying + * products that the vending machine is to carry without manually populating + * product_records. + */ +/obj/machinery/vending/proc/build_inventory() + var/list/all_products = list( + list(products, CAT_NORMAL), + list(contraband, CAT_HIDDEN), + list(premium, CAT_COIN)) + + for(var/current_list in all_products) + var/category = current_list[2] + + for(var/entry in current_list[1]) + var/datum/stored_item/vending_product/product = new/datum/stored_item/vending_product(src, entry) + + product.price = (entry in prices) ? prices[entry] : 0 + product.amount = (current_list[1][entry]) ? current_list[1][entry] : 1 + product.category = category + + product_records.Add(product) + GLOB.vending_products[entry] = 1 + +/obj/machinery/vending/Destroy() + qdel(wires) + wires = null + qdel(coin) + coin = null + for(var/datum/stored_item/vending_product/R in product_records) + qdel(R) + product_records = null + return ..() + +/obj/machinery/vending/ex_act(severity) + switch(severity) + if(1.0) + qdel(src) + return + if(2.0) + if(prob(50)) + qdel(src) + return + if(3.0) + if(prob(25)) + spawn(0) + malfunction() + return + return + else + return + +/obj/machinery/vending/emag_act(var/remaining_charges, var/mob/user) + if(!emagged) + emagged = 1 + to_chat(user, "You short out \the [src]'s product lock.") + return 1 + +/obj/machinery/vending/attackby(obj/item/weapon/W as obj, mob/user as mob) + var/obj/item/weapon/card/id/I = W.GetID() + + if(I || istype(W, /obj/item/weapon/spacecash)) + attack_hand(user) + return + else if(W.is_screwdriver()) + panel_open = !panel_open + to_chat(user, "You [panel_open ? "open" : "close"] the maintenance panel.") + playsound(src, W.usesound, 50, 1) + if(panel_open) + wires.Interact(user) + add_overlay("[initial(icon_state)]-panel") + else + cut_overlay("[initial(icon_state)]-panel") + + SStgui.update_uis(src) // Speaker switch is on the main UI, not wires UI + return + else if(istype(W, /obj/item/device/multitool) || W.is_wirecutter()) + if(panel_open) + attack_hand(user) + return + else if(istype(W, /obj/item/weapon/coin) && premium.len > 0) + user.drop_item() + W.forceMove(src) + coin = W + categories |= CAT_COIN + to_chat(user, "You insert \the [W] into \the [src].") + SStgui.update_uis(src) + return + else if(W.is_wrench()) + playsound(src, W.usesound, 100, 1) + if(anchored) + user.visible_message("[user] begins unsecuring \the [src] from the floor.", "You start unsecuring \the [src] from the floor.") + else + user.visible_message("[user] begins securing \the [src] to the floor.", "You start securing \the [src] to the floor.") + + if(do_after(user, 20 * W.toolspeed)) + if(!src) return + to_chat(user, "You [anchored? "un" : ""]secured \the [src]!") + anchored = !anchored + return + else + + for(var/datum/stored_item/vending_product/R in product_records) + if(istype(W, R.item_path) && (W.name == R.item_name)) + stock(W, R, user) + return + ..() + +/** + * Receive payment with cashmoney. + * + * usr is the mob who gets the change. + */ +/obj/machinery/vending/proc/pay_with_cash(var/obj/item/weapon/spacecash/cashmoney, mob/user) + if(currently_vending.price > cashmoney.worth) + + // This is not a status display message, since it's something the character + // themselves is meant to see BEFORE putting the money in + to_chat(usr, "[bicon(cashmoney)] That is not enough money.") + return 0 + + if(istype(cashmoney, /obj/item/weapon/spacecash)) + + visible_message("\The [usr] inserts some cash into \the [src].") + cashmoney.worth -= currently_vending.price + + if(cashmoney.worth <= 0) + usr.drop_from_inventory(cashmoney) + qdel(cashmoney) + else + cashmoney.update_icon() + + // Vending machines have no idea who paid with cash + credit_purchase("(cash)") + return 1 + +/** + * Scan a chargecard and deduct payment from it. + * + * Takes payment for whatever is the currently_vending item. Returns 1 if + * successful, 0 if failed. + */ +/obj/machinery/vending/proc/pay_with_ewallet(var/obj/item/weapon/spacecash/ewallet/wallet) + visible_message("\The [usr] swipes \the [wallet] through \the [src].") + playsound(src, 'sound/machines/id_swipe.ogg', 50, 1) + if(currently_vending.price > wallet.worth) + to_chat(usr, "Insufficient funds on chargecard.") + return 0 + else + wallet.worth -= currently_vending.price + credit_purchase("[wallet.owner_name] (chargecard)") + return 1 + +/** + * Scan a card and attempt to transfer payment from associated account. + * + * Takes payment for whatever is the currently_vending item. Returns 1 if + * successful, 0 if failed + */ +/obj/machinery/vending/proc/pay_with_card(obj/item/weapon/card/id/I, mob/M) + visible_message("[M] swipes a card through [src].") + playsound(src, 'sound/machines/id_swipe.ogg', 50, 1) + + var/datum/money_account/customer_account = get_account(I.associated_account_number) + if(!customer_account) + to_chat(M, "Error: Unable to access account. Please contact technical support if problem persists.") + return FALSE + + if(customer_account.suspended) + to_chat(M, "Unable to access account: account suspended.") + return FALSE + + // Have the customer punch in the PIN before checking if there's enough money. Prevents people from figuring out acct is + // empty at high security levels + if(customer_account.security_level != 0) //If card requires pin authentication (ie seclevel 1 or 2) + var/attempt_pin = input("Enter pin code", "Vendor transaction") as num + customer_account = attempt_account_access(I.associated_account_number, attempt_pin, 2) + + if(!customer_account) + to_chat(M, "Unable to access account: incorrect credentials.") + return FALSE + + if(currently_vending.price > customer_account.money) + to_chat(M, "Insufficient funds in account.") + return FALSE + + // Okay to move the money at this point + + // debit money from the purchaser's account + customer_account.money -= currently_vending.price + + // create entry in the purchaser's account log + var/datum/transaction/T = new() + T.target_name = "[vendor_account.owner_name] (via [name])" + T.purpose = "Purchase of [currently_vending.item_name]" + if(currently_vending.price > 0) + T.amount = "([currently_vending.price])" + else + T.amount = "[currently_vending.price]" + T.source_terminal = name + T.date = current_date_string + T.time = stationtime2text() + customer_account.transaction_log.Add(T) + + // Give the vendor the money. We use the account owner name, which means + // that purchases made with stolen/borrowed card will look like the card + // owner made them + credit_purchase(customer_account.owner_name) + return 1 + +/** + * Add money for current purchase to the vendor account. + * + * Called after the money has already been taken from the customer. + */ +/obj/machinery/vending/proc/credit_purchase(var/target as text) + vendor_account.money += currently_vending.price + + var/datum/transaction/T = new() + T.target_name = target + T.purpose = "Purchase of [currently_vending.item_name]" + T.amount = "[currently_vending.price]" + T.source_terminal = name + T.date = current_date_string + T.time = stationtime2text() + vendor_account.transaction_log.Add(T) + +/obj/machinery/vending/attack_ghost(mob/user) + return attack_hand(user) + +/obj/machinery/vending/attack_ai(mob/user as mob) + return attack_hand(user) + +/obj/machinery/vending/attack_hand(mob/user as mob) + if(stat & (BROKEN|NOPOWER)) + return + + if(seconds_electrified != 0) + if(shock(user, 100)) + return + + wires.Interact(user) + tgui_interact(user) + +/obj/machinery/vending/ui_assets(mob/user) + return list( + get_asset_datum(/datum/asset/spritesheet/vending), + ) + +/obj/machinery/vending/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "Vending", name) + ui.open() + +/obj/machinery/vending/tgui_data(mob/user) + var/list/data = list() + var/list/listed_products = list() + + data["chargesMoney"] = length(prices) > 0 ? TRUE : FALSE + for(var/key = 1 to product_records.len) + var/datum/stored_item/vending_product/I = product_records[key] + + if(!(I.category & categories)) + continue + + listed_products.Add(list(list( + "key" = key, + "name" = I.item_name, + "desc" = I.item_desc, + "price" = I.price, + "color" = I.display_color, + "isatom" = ispath(I.item_path, /atom), + "path" = replacetext(replacetext("[I.item_path]", "/obj/item/", ""), "/", "-"), + "amount" = I.get_amount() + ))) + + data["products"] = listed_products + + if(coin) + data["coin"] = coin.name + else + data["coin"] = FALSE + + if(currently_vending) + data["actively_vending"] = currently_vending.item_name + else + data["actively_vending"] = null + + if(panel_open) + data["panel"] = 1 + data["speaker"] = shut_up ? 0 : 1 + else + data["panel"] = 0 + + var/mob/living/carbon/human/H + var/obj/item/weapon/card/id/C + + data["guestNotice"] = "No valid ID card detected. Wear your ID, or present cash."; + data["userMoney"] = 0 + data["user"] = null + if(ishuman(user)) + H = user + C = H.GetIdCard() + var/obj/item/weapon/spacecash/S = H.get_active_hand() + if(istype(S)) + data["userMoney"] = S.worth + data["guestNotice"] = "Accepting [S.initial_name]. You have: [S.worth]â‚®." + else if(istype(C)) + var/datum/money_account/A = get_account(C.associated_account_number) + if(istype(A)) + data["user"] = list() + data["user"]["name"] = A.owner_name + data["userMoney"] = A.money + data["user"]["job"] = (istype(C) && C.rank) ? C.rank : "No Job" + else + data["guestNotice"] = "Unlinked ID detected. Present cash to pay."; + + return data + +/obj/machinery/vending/tgui_act(action, params) + if(stat & (BROKEN|NOPOWER)) + return + if(usr.stat || usr.restrained()) + return + if(..()) + return TRUE + + . = TRUE + switch(action) + if("remove_coin") + if(issilicon(usr)) + return FALSE + + if(!coin) + to_chat(usr, "There is no coin in this machine.") + return + + coin.forceMove(src.loc) + if(!usr.get_active_hand()) + usr.put_in_hands(coin) + + to_chat(usr, "You remove \the [coin] from \the [src].") + coin = null + categories &= ~CAT_COIN + return TRUE + if("vend") + if(!vend_ready) + to_chat(usr, "[src] is busy!") + return + if(!allowed(usr) && !emagged && scan_id) + to_chat(usr, "Access denied.") //Unless emagged of course + flick("[icon_state]-deny",src) + playsound(src, 'sound/machines/deniedbeep.ogg', 50, 0) + return + if(panel_open) + to_chat(usr, "[src] cannot dispense products while its service panel is open!") + return + + var/key = text2num(params["vend"]) + var/datum/stored_item/vending_product/R = product_records[key] + + // This should not happen unless the request from NanoUI was bad + if(!(R.category & categories)) + return + + if(!can_buy(R, usr)) + return + + if(R.price <= 0) + vend(R, usr) + add_fingerprint(usr) + return TRUE + + if(issilicon(usr)) //If the item is not free, provide feedback if a synth is trying to buy something. + to_chat(usr, "Lawed unit recognized. Lawed units cannot complete this transaction. Purchase canceled.") + return + if(!ishuman(usr)) + return + + vend_ready = FALSE // From this point onwards, vendor is locked to performing this transaction only, until it is resolved. + + var/mob/living/carbon/human/H = usr + var/obj/item/weapon/card/id/C = H.GetIdCard() + + if(!vendor_account || vendor_account.suspended) + to_chat(usr, "Vendor account offline. Unable to process transaction.") + flick("[icon_state]-deny",src) + vend_ready = TRUE + return + + currently_vending = R + + var/paid = FALSE + + if(istype(usr.get_active_hand(), /obj/item/weapon/spacecash)) + var/obj/item/weapon/spacecash/cash = usr.get_active_hand() + paid = pay_with_cash(cash, usr) + else if(istype(usr.get_active_hand(), /obj/item/weapon/spacecash/ewallet)) + var/obj/item/weapon/spacecash/ewallet/wallet = usr.get_active_hand() + paid = pay_with_ewallet(wallet) + else if(istype(C, /obj/item/weapon/card)) + paid = pay_with_card(C, usr) + /*else if(usr.can_advanced_admin_interact()) + to_chat(usr, "Vending object due to admin interaction.") + paid = TRUE*/ + else + to_chat(usr, "Payment failure: you have no ID or other method of payment.") + vend_ready = TRUE + flick("[icon_state]-deny",src) + return TRUE // we set this because they shouldn't even be able to get this far, and we want the UI to update. + if(paid) + vend(currently_vending, usr) // vend will handle vend_ready + . = TRUE + else + to_chat(usr, "Payment failure: unable to process payment.") + vend_ready = TRUE + + if("togglevoice") + if(!panel_open) + return FALSE + shut_up = !shut_up + +/obj/machinery/vending/proc/can_buy(datum/stored_item/vending_product/R, mob/user) + if(!allowed(user) && !emagged && scan_id) + to_chat(user, "Access denied.") //Unless emagged of course + flick("[icon_state]-deny",src) + playsound(src, 'sound/machines/deniedbeep.ogg', 50, 0) + return FALSE + return TRUE + +/obj/machinery/vending/proc/vend(datum/stored_item/vending_product/R, mob/user) + if(!can_buy(R, user)) + return + + if(!R.amount) + to_chat(user, "[src] has ran out of that product.") + vend_ready = TRUE + return + + vend_ready = FALSE //One thing at a time!! + SStgui.update_uis(src) + + if(R.category & CAT_COIN) + if(!coin) + to_chat(user, "You need to insert a coin to get this item.") + return + if(coin.string_attached) + if(prob(50)) + to_chat(user, "You successfully pull the coin out before \the [src] could swallow it.") + else + to_chat(user, "You weren't able to pull the coin out fast enough, the machine ate it, string and all.") + qdel(coin) + coin = null + categories &= ~CAT_COIN + else + qdel(coin) + coin = null + categories &= ~CAT_COIN + + if(((last_reply + (vend_delay + 200)) <= world.time) && vend_reply) + spawn(0) + speak(vend_reply) + last_reply = world.time + + use_power(vend_power_usage) //actuators and stuff + flick("[icon_state]-vend",src) + addtimer(CALLBACK(src, .proc/delayed_vend, R, user), vend_delay) + +/obj/machinery/vending/proc/delayed_vend(datum/stored_item/vending_product/R, mob/user) + R.get_product(get_turf(src)) + if(has_logs) + do_logging(R, user, 1) + if(prob(1)) + sleep(3) + if(R.get_product(get_turf(src))) + visible_message("\The [src] clunks as it vends an additional item.") + playsound(src, "sound/[vending_sound]", 100, 1, 1) + + GLOB.items_sold_shift_roundstat++ + + vend_ready = 1 + currently_vending = null + SStgui.update_uis(src) + + +/obj/machinery/vending/proc/do_logging(datum/stored_item/vending_product/R, mob/user, var/vending = 0) + if(user.GetIdCard()) + var/obj/item/weapon/card/id/tempid = user.GetIdCard() + var/list/list_item = list() + if(vending) + list_item += "vend" + else + list_item += "stock" + list_item += tempid.registered_name + list_item += stationtime2text() + list_item += R.item_name + log[++log.len] = list_item + +/obj/machinery/vending/proc/show_log(mob/user as mob) + if(user.GetIdCard()) + var/obj/item/weapon/card/id/tempid = user.GetIdCard() + if(req_log_access in tempid.GetAccess()) + var/datum/browser/popup = new(user, "vending_log", "Vending Log", 700, 500) + var/dat = "" + dat += "
[name] Vending Log
" + dat += "
Welcome [user.name]!

" + dat += "Below are the recent vending logs for your vending machine.
" + for(var/i in log) + dat += json_encode(i) + dat += ";
" + popup.set_content(dat) + popup.open() + else + to_chat(user,"You do not have the required access to view the vending logs for this machine.") + + +/obj/machinery/vending/verb/rotate_clockwise() + set name = "Rotate Vending Machine Clockwise" + set category = "Object" + set src in oview(1) + + if (src.can_rotate == 0) + to_chat(usr, "\The [src] cannot be rotated.") + return 0 + + if (src.anchored || usr:stat) + to_chat(usr, "It is bolted down!") + return 0 + src.set_dir(turn(src.dir, 270)) + return 1 + +/obj/machinery/vending/verb/check_logs() + set name = "Check Vending Logs" + set category = "Object" + set src in oview(1) + + show_log(usr) + +/** + * Add item to the machine + * + * Checks if item is vendable in this machine should be performed before + * calling. W is the item being inserted, R is the associated vending_product entry. + */ +/obj/machinery/vending/proc/stock(obj/item/weapon/W, var/datum/stored_item/vending_product/R, var/mob/user) + if(!user.unEquip(W)) + return + + to_chat(user, "You insert \the [W] in the product receptor.") + R.add_product(W) + if(has_logs) + do_logging(R, user) + + SStgui.update_uis(src) + +/obj/machinery/vending/process() + if(stat & (BROKEN|NOPOWER)) + return + + if(!active) + return + + if(seconds_electrified > 0) + seconds_electrified-- + + //Pitch to the people! Really sell it! + if(((last_slogan + slogan_delay) <= world.time) && (slogan_list.len > 0) && (!shut_up) && prob(5)) + var/slogan = pick(slogan_list) + speak(slogan) + last_slogan = world.time + + if(shoot_inventory && prob(2)) + throw_item() + + return + +/obj/machinery/vending/proc/speak(var/message) + if(stat & NOPOWER) + return + + if(!message) + return + + for(var/mob/O in hearers(src, null)) + O.show_message("\The [src] beeps, \"[message]\"",2) + return + +/obj/machinery/vending/power_change() + ..() + if(stat & BROKEN) + icon_state = "[initial(icon_state)]-broken" + else + if(!(stat & NOPOWER)) + icon_state = initial(icon_state) + else + spawn(rand(0, 15)) + icon_state = "[initial(icon_state)]-off" + +//Oh no we're malfunctioning! Dump out some product and break. +/obj/machinery/vending/proc/malfunction() + for(var/datum/stored_item/vending_product/R in product_records) + while(R.get_amount()>0) + R.get_product(loc) + break + + stat |= BROKEN + icon_state = "[initial(icon_state)]-broken" + return + +//Somebody cut an important wire and now we're following a new definition of "pitch." +/obj/machinery/vending/proc/throw_item() + var/obj/throw_item = null + var/mob/living/target = locate() in view(7,src) + if(!target) + return 0 + + for(var/datum/stored_item/vending_product/R in product_records) + throw_item = R.get_product(loc) + if(!throw_item) + continue + break + if(!throw_item) + return 0 + spawn(0) + throw_item.throw_at(target, 16, 3, src) + visible_message("\The [src] launches \a [throw_item] at \the [target]!") + return 1 + +//Actual machines are in vending_machines.dm diff --git a/code/game/machinery/vending_machines.dm b/code/modules/economy/vending_machines.dm similarity index 100% rename from code/game/machinery/vending_machines.dm rename to code/modules/economy/vending_machines.dm diff --git a/code/modules/emotes/definitions/_mob.dm b/code/modules/emotes/definitions/_mob.dm new file mode 100644 index 00000000000..8c10b4cde2f --- /dev/null +++ b/code/modules/emotes/definitions/_mob.dm @@ -0,0 +1,41 @@ +var/list/_default_mob_emotes = list( + /decl/emote/visible, + /decl/emote/visible/scratch, + /decl/emote/visible/drool, + /decl/emote/visible/nod, + /decl/emote/visible/sway, + /decl/emote/visible/sulk, + /decl/emote/visible/twitch, + /decl/emote/visible/twitch_v, + /decl/emote/visible/dance, + /decl/emote/visible/roll, + /decl/emote/visible/shake, + /decl/emote/visible/jump, + /decl/emote/visible/shiver, + /decl/emote/visible/collapse, + /decl/emote/visible/spin, + /decl/emote/visible/sidestep, + /decl/emote/audible, + /decl/emote/audible/hiss, + /decl/emote/audible/whimper, + /decl/emote/audible/gasp, + /decl/emote/audible/scretch, + /decl/emote/audible/choke, + /decl/emote/audible/moan, + /decl/emote/audible/gnarl, +) + +/mob + var/list/usable_emotes + +/mob/proc/update_emotes(var/skip_sort) + usable_emotes = list() + for(var/emote in get_default_emotes()) + var/decl/emote/emote_datum = decls_repository.get_decl(emote) + if(emote_datum.check_user(src)) + usable_emotes[emote_datum.key] = emote_datum + if(!skip_sort) + usable_emotes = sortAssoc(usable_emotes) + +/mob/proc/get_default_emotes() + return global._default_mob_emotes diff --git a/code/modules/emotes/definitions/_species.dm b/code/modules/emotes/definitions/_species.dm new file mode 100644 index 00000000000..ff15df2fae5 --- /dev/null +++ b/code/modules/emotes/definitions/_species.dm @@ -0,0 +1,11 @@ +/datum/species + var/list/default_emotes = list() + +/mob/living/carbon/update_emotes(var/skip_sort) + . = ..(skip_sort = TRUE) + if(species) + for(var/emote in species.default_emotes) + var/decl/emote/emote_datum = decls_repository.get_decl(emote) + if(emote_datum.check_user(src)) + usable_emotes[emote_datum.key] = emote_datum + usable_emotes = sortAssoc(usable_emotes) diff --git a/code/modules/emotes/definitions/audible.dm b/code/modules/emotes/definitions/audible.dm new file mode 100644 index 00000000000..15f547b9e85 --- /dev/null +++ b/code/modules/emotes/definitions/audible.dm @@ -0,0 +1,229 @@ +/decl/emote/audible + key = "burp" + emote_message_3p = "burps." + message_type = AUDIBLE_MESSAGE + +/decl/emote/audible/New() + . = ..() + // Snips the 'USER' from 3p emote messages for radio. + if(!emote_message_radio && emote_message_3p) + emote_message_radio = emote_message_3p + if(!emote_message_radio_synthetic && emote_message_synthetic_3p) + emote_message_radio_synthetic = emote_message_synthetic_3p + +/decl/emote/audible/deathgasp_alien + key = "deathgasp" + emote_message_3p = "lets out a waning guttural screech, green blood bubbling from its maw." + +/decl/emote/audible/whimper + key = "whimper" + emote_message_3p = "whimpers." + +/decl/emote/audible/gasp + key = "gasp" + emote_message_3p = "gasps." + conscious = FALSE + +/decl/emote/audible/scretch + key = "scretch" + emote_message_3p = "scretches." + +/decl/emote/audible/choke + key ="choke" + emote_message_3p = "chokes." + conscious = FALSE + +/decl/emote/audible/gnarl + key = "gnarl" + emote_message_3p = "gnarls and shows USER_THEIR teeth." + +/decl/emote/audible/multichirp + key = "mchirp" + emote_message_3p = "chirps a chorus of notes!" + emote_sound = 'sound/voice/multichirp.ogg' + +/decl/emote/audible/alarm + key = "alarm" + emote_message_1p = "You sound an alarm." + emote_message_3p = "sounds an alarm." + +/decl/emote/audible/alert + key = "alert" + emote_message_1p = "You let out a distressed noise." + emote_message_3p = "lets out a distressed noise." + +/decl/emote/audible/notice + key = "notice" + emote_message_1p = "You play a loud tone." + emote_message_3p = "plays a loud tone." + +/decl/emote/audible/boop + key = "boop" + emote_message_1p = "You boop." + emote_message_3p = "boops." + +/decl/emote/audible/beep + key = "beep" + emote_message_3p = "You beep." + emote_message_3p = "beeps." + emote_sound = 'sound/machines/twobeep.ogg' + +/decl/emote/audible/sniff + key = "sniff" + emote_message_3p = "sniffs." + +/decl/emote/audible/snore + key = "snore" + emote_message_3p = "snores." + conscious = FALSE + +/decl/emote/audible/whimper + key = "whimper" + emote_message_3p = "whimpers." + +/decl/emote/audible/yawn + key = "yawn" + emote_message_3p = "yawns." + +/decl/emote/audible/clap + key = "clap" + emote_message_3p = "claps." + +/decl/emote/audible/chuckle + key = "chuckle" + emote_message_3p = "chuckles." + +/decl/emote/audible/cry + key = "cry" + emote_message_3p = "cries." + +/decl/emote/audible/sigh + key = "sigh" + emote_message_3p = "sighs." + +/decl/emote/audible/laugh + key = "laugh" + emote_message_3p_target = "laughs at TARGET." + emote_message_3p = "laughs." + +/decl/emote/audible/mumble + key = "mumble" + emote_message_3p = "mumbles!" + +/decl/emote/audible/grumble + key = "grumble" + emote_message_3p = "grumbles!" + +/decl/emote/audible/groan + key = "groan" + emote_message_3p = "groans!" + conscious = FALSE + +/decl/emote/audible/moan + key = "moan" + emote_message_3p = "moans!" + conscious = FALSE + +/decl/emote/audible/giggle + key = "giggle" + emote_message_3p = "giggles." + +/decl/emote/audible/grunt + key = "grunt" + emote_message_3p = "grunts." + +/decl/emote/audible/bug_hiss + key ="hiss" + emote_message_3p_target = "hisses at TARGET." + emote_message_3p = "hisses." + emote_sound = 'sound/voice/BugHiss.ogg' + +/decl/emote/audible/bug_buzz + key ="buzz" + emote_message_3p = "buzzes its wings." + emote_sound = 'sound/voice/BugBuzz.ogg' + +/decl/emote/audible/bug_chitter + key ="chitter" + emote_message_3p = "chitters." + emote_sound = 'sound/voice/Bug.ogg' + +/decl/emote/audible/roar + key = "roar" + emote_message_3p = "roars!" + +/decl/emote/audible/bellow + key = "bellow" + emote_message_3p = "bellows!" + +/decl/emote/audible/howl + key = "howl" + emote_message_3p = "howls!" + +/decl/emote/audible/wheeze + key = "wheeze" + emote_message_3p = "wheezes." + +/decl/emote/audible/hiss + key = "hiss" + emote_message_3p_target = "hisses softly at TARGET." + emote_message_3p = "hisses softly." + +/decl/emote/audible/chirp + key = "chirp" + emote_message_3p = "chirps!" + emote_sound = 'sound/misc/nymphchirp.ogg' + +/decl/emote/audible/crack + key = "crack" + emote_message_3p = "cracks USER_THEIR knuckles." + emote_sound = 'sound/voice/knuckles.ogg' + +/decl/emote/audible/squish + key = "squish" + emote_sound = 'sound/effects/slime_squish.ogg' //Credit to DrMinky (freesound.org) for the sound. + emote_message_3p = "squishes." + +/decl/emote/audible/warble + key = "warble" + emote_sound = 'sound/effects/warble.ogg' // Copyright CC BY 3.0 alienistcog (freesound.org) for the sound. + emote_message_3p = "warbles." + +/decl/emote/audible/vox_shriek + key = "shriek" + emote_message_3p = "SHRIEKS!" + emote_sound = 'sound/voice/shriek1.ogg' + +/decl/emote/audible/purr + key = "purr" + emote_message_3p = "purrs." + emote_sound = 'sound/voice/cat_purr.ogg' + +/decl/emote/audible/purrlong + key = "purrl" + emote_message_3p = "purrs." + emote_sound = 'sound/voice/cat_purr_long.ogg' + +/decl/emote/audible/teshsqueak + key = "surprised" + emote_message_1p = "You chirp in surprise!" + emote_message_3p = "chirps in surprise!" + emote_message_1p_target = "You chirp in surprise at TARGET!" + emote_message_3p_target = "chirps in surprise at TARGET!" + emote_sound = 'sound/voice/teshsqueak.ogg' // Copyright CC BY 3.0 InspectorJ (freesound.org) for the source audio. + +/decl/emote/audible/teshchirp + key = "chirp" + emote_message_1p = "You chirp!" + emote_message_3p = "chirps!" + emote_message_1p_target = "You chirp at TARGET!" + emote_message_3p_target = "chirps at TARGET!" + emote_sound = 'sound/voice/teshchirp.ogg' // Copyright Sampling+ 1.0 Incarnidine (freesound.org) for the source audio. + +/decl/emote/audible/teshtrill + key = "trill" + emote_message_1p = "You trill." + emote_message_3p = "trills." + emote_message_1p_target = "You trill at TARGET." + emote_message_3p_target = "trills at TARGET." + emote_sound = 'sound/voice/teshtrill.ogg' // Copyright CC BY-NC 3.0 Arnaud Coutancier (freesound.org) for the source audio. diff --git a/code/modules/emotes/definitions/audible_cough.dm b/code/modules/emotes/definitions/audible_cough.dm new file mode 100644 index 00000000000..4e28d1db918 --- /dev/null +++ b/code/modules/emotes/definitions/audible_cough.dm @@ -0,0 +1,52 @@ +/decl/emote/audible/cough + key = "cough" + emote_message_1p = "You cough!" + emote_message_1p_target = "You cough on TARGET!" + emote_message_3p = "coughs!" + emote_message_3p_target = "coughs on TARGET!" + emote_message_synthetic_1p_target = "You emit a robotic cough towards TARGET." + emote_message_synthetic_1p = "You emit a robotic cough." + emote_message_synthetic_3p_target = "emits a robotic cough towards TARGET." + emote_message_synthetic_3p = "emits a robotic cough." + emote_volume = 120 + emote_volume_synthetic = 50 + + conscious = FALSE + emote_sound_synthetic = list( + FEMALE = list( + 'sound/effects/mob_effects/f_machine_cougha.ogg', + 'sound/effects/mob_effects/f_machine_coughb.ogg' + ), + MALE = list( + 'sound/effects/mob_effects/m_machine_cougha.ogg', + 'sound/effects/mob_effects/m_machine_coughb.ogg', + 'sound/effects/mob_effects/m_machine_coughc.ogg' + ), + NEUTER = list( + 'sound/effects/mob_effects/m_machine_cougha.ogg', + 'sound/effects/mob_effects/m_machine_coughb.ogg', + 'sound/effects/mob_effects/m_machine_coughc.ogg' + ), + PLURAL = list( + 'sound/effects/mob_effects/m_machine_cougha.ogg', + 'sound/effects/mob_effects/m_machine_coughb.ogg', + 'sound/effects/mob_effects/m_machine_coughc.ogg' + ) + ) + +/decl/emote/audible/cough/get_emote_sound(var/atom/user) + if(ishuman(user) && !check_synthetic(user)) + var/mob/living/carbon/human/H = user + if(H.get_gender() == FEMALE) + if(length(H.species.female_cough_sounds)) + return list( + "sound" = H.species.female_cough_sounds, + "vol" = emote_volume + ) + else + if(length(H.species.male_cough_sounds)) + return list( + "sound" = H.species.male_cough_sounds, + "vol" = emote_volume + ) + return ..() diff --git a/code/modules/emotes/definitions/audible_furry_vr.dm b/code/modules/emotes/definitions/audible_furry_vr.dm new file mode 100644 index 00000000000..681e9101a29 --- /dev/null +++ b/code/modules/emotes/definitions/audible_furry_vr.dm @@ -0,0 +1,129 @@ +/decl/emote/audible/awoo + key = "awoo" + emote_message_3p = "lets out an awoo." + emote_sound = 'sound/voice/awoo.ogg' +/decl/emote/audible/awoo2 + key = "awoo2" + emote_message_3p = "lets out an awoo." + emote_sound = 'sound/voice/long_awoo.ogg' +/decl/emote/audible/growl + key = "growl" + emote_message_3p = "lets out a growl." + emote_sound = 'sound/voice/growl.ogg' +/decl/emote/audible/woof + key = "woof" + emote_message_3p = "lets out a woof." + emote_sound = 'sound/voice/woof.ogg' +/decl/emote/audible/woof2 + key = "woof2" + emote_message_3p = "lets out a woof." + emote_sound = 'sound/voice/woof2.ogg' +/decl/emote/audible/nya + key = "nya" + emote_message_3p = "lets out a nya." + emote_sound = 'sound/voice/nya.ogg' +/decl/emote/audible/mrowl + key = "mrowl" + emote_message_3p = "mrowls." + emote_sound = 'sound/voice/mrow.ogg' +/decl/emote/audible/peep + key = "peep" + emote_message_3p = "peeps like a bird." + emote_sound = 'sound/voice/peep.ogg' +/decl/emote/audible/chirp + key = "chirp" + emote_message_3p = "chirps!" + emote_sound = 'sound/misc/nymphchirp.ogg' +/decl/emote/audible/hoot + key = "hoot" + emote_message_3p = "hoots!" + emote_sound = 'sound/voice/hoot.ogg' +/decl/emote/audible/weh + key = "weh" + emote_message_3p = "lets out a weh." + emote_sound = 'sound/voice/weh.ogg' +/decl/emote/audible/merp + key = "merp" + emote_message_3p = "lets out a merp." + emote_sound = 'sound/voice/merp.ogg' +/decl/emote/audible/myarp + key = "myarp" + emote_message_3p = "lets out a myarp." + emote_sound = 'sound/voice/myarp.ogg' +/decl/emote/audible/bark + key = "bark" + emote_message_3p = "lets out a bark." + emote_sound = 'sound/voice/bark2.ogg' +/decl/emote/audible/bork + key = "bork" + emote_message_3p = "lets out a bork." + emote_sound = 'sound/voice/bork.ogg' +/decl/emote/audible/mrow + emote_message_3p = "lets out a mrow." + emote_sound = 'sound/voice/mrow.ogg' +/decl/emote/audible/hypno + emote_message_3p = "lets out a mystifying tone." + emote_sound = 'sound/voice/hypno.ogg' +/decl/emote/audible/hiss + key = "hiss" + emote_message_3p = "lets out a hiss." + emote_sound = 'sound/voice/hiss.ogg' +/decl/emote/audible/rattle + key = "rattle" + emote_message_3p = "rattles!" + emote_sound = 'sound/voice/rattle.ogg' +/decl/emote/audible/squeak + key = "squeak" + emote_message_3p = "lets out a squeak." + emote_sound = 'sound/effects/mouse_squeak.ogg' +/decl/emote/audible/geck + key = "geck" + emote_message_3p = "geckers!" + emote_sound = 'sound/voice/geck.ogg' +/decl/emote/audible/baa + key = "baa" + emote_message_3p = "lets out a baa." + emote_sound = 'sound/voice/baa.ogg' +/decl/emote/audible/baa2 + key = "baa2" + emote_message_3p = "bleats." + emote_sound = 'sound/voice/baa2.ogg' +/* +/decl/emote/audible/deathgasp2 + key = "deathgasp2" + emote_message_3p = "[species.get_death_message()]" + m_type = 1 + emote_sound = 'sound/voice/deathgasp2.ogg' +*/ +/decl/emote/audible/mar + key = "mar" + emote_message_3p = "lets out a mar." + emote_sound = 'sound/voice/mar.ogg' +/decl/emote/audible/wurble + key = "wurble" + emote_message_3p = "lets out a wurble." + emote_sound = 'sound/voice/wurble.ogg' +/decl/emote/audible/snort + key = "snort" + emote_message_3p = "snorts!" + emote_sound = 'sound/voice/Snort.ogg' +/decl/emote/audible/meow + key = "meow" + emote_message_3p = "gently meows!" + emote_sound = 'sound/voice/Meow.ogg' +/decl/emote/audible/moo + key = "moo" + emote_message_3p = "takes a breath and lets out a moo." + emote_sound = 'sound/voice/Moo.ogg' +/decl/emote/audible/croak + key = "croak" + emote_message_3p = "rumbles their throat, puffs their cheeks and croaks." + emote_sound = 'sound/voice/Croak.ogg' +/decl/emote/audible/gao + key = "gao" + emote_message_3p = "lets out a gao." + emote_sound = 'sound/voice/gao.ogg' +/decl/emote/audible/cackle + key = "cackle" + emote_message_3p = "cackles hysterically!" + emote_sound = 'sound/voice/YeenCackle.ogg' diff --git a/code/modules/emotes/definitions/audible_scream.dm b/code/modules/emotes/definitions/audible_scream.dm new file mode 100644 index 00000000000..00ed9c29fc3 --- /dev/null +++ b/code/modules/emotes/definitions/audible_scream.dm @@ -0,0 +1,16 @@ +/decl/emote/audible/scream + key = "scream" + emote_message_1p = "You scream!" + emote_message_3p = "screams!" + +/decl/emote/audible/scream/get_emote_message_1p(var/atom/user, var/atom/target, var/extra_params) + if(ishuman(user)) + var/mob/living/carbon/human/H = user + return "You [H.species.scream_verb_1p]!" + . = ..() + +/decl/emote/audible/cough/get_emote_message_3p(var/atom/user, var/atom/target, var/extra_params) + if(ishuman(user)) + var/mob/living/carbon/human/H = user + return "[H.species.scream_verb_3p]!" + . = ..() diff --git a/code/modules/emotes/definitions/audible_slap.dm b/code/modules/emotes/definitions/audible_slap.dm new file mode 100644 index 00000000000..d0b5466c30c --- /dev/null +++ b/code/modules/emotes/definitions/audible_slap.dm @@ -0,0 +1,24 @@ +/decl/emote/audible/slap + key = "slap" + emote_message_1p_target = "You slap TARGET across the face. Ouch!" + emote_message_1p = "You slap yourself across the face!" + emote_message_3p_target = "slaps TARGET across the face. Ouch!" + emote_message_3p = "slaps USER_SELF across the face!" + emote_sound = 'sound/effects/snap.ogg' + check_restraints = TRUE + check_range = 1 + +/decl/emote/audible/slap/New() + ..() + emote_message_1p_target = SPAN_DANGER(emote_message_1p_target) + emote_message_1p = SPAN_DANGER(emote_message_1p) + emote_message_3p_target = SPAN_DANGER(emote_message_3p_target) + emote_message_3p = SPAN_DANGER(emote_message_3p) + +/decl/emote/audible/slap/do_extra(var/atom/user, var/atom/target) + . = ..() + if(ishuman(target)) + var/mob/living/carbon/human/H = target + var/obj/item/clothing/mask/smokable/mask = H.wear_mask + if(istype(mask) && H.unEquip(mask)) + mask.forceMove(get_turf(H)) diff --git a/code/modules/emotes/definitions/audible_snap.dm b/code/modules/emotes/definitions/audible_snap.dm new file mode 100644 index 00000000000..d098839f5b8 --- /dev/null +++ b/code/modules/emotes/definitions/audible_snap.dm @@ -0,0 +1,22 @@ +/decl/emote/audible/snap + key = "snap" + emote_message_1p = "You snap your fingers." + emote_message_3p = "snaps USER_THEIR fingers." + emote_message_1p_target = "You snap your fingers at TARGET." + emote_message_3p_target = "snaps USER_THEIR fingers at TARGET." + emote_sound = 'sound/effects/fingersnap.ogg' + +/decl/emote/audible/snap/proc/can_snap(var/atom/user) + if(ishuman(user)) + var/mob/living/carbon/human/H = user + for(var/limb in list(BP_L_HAND, BP_R_HAND)) + var/obj/item/organ/external/L = H.get_organ(limb) + if(istype(L) && L.is_usable() && !L.splinted) + return TRUE + return FALSE + +/decl/emote/audible/snap/do_emote(var/atom/user, var/extra_params) + if(!can_snap(user)) + to_chat(user, SPAN_WARNING("You need at least one working hand to snap your fingers.")) + return FALSE + . = ..() diff --git a/code/modules/emotes/definitions/audible_sneeze.dm b/code/modules/emotes/definitions/audible_sneeze.dm new file mode 100644 index 00000000000..a15cbaf46db --- /dev/null +++ b/code/modules/emotes/definitions/audible_sneeze.dm @@ -0,0 +1,29 @@ +/decl/emote/audible/sneeze + key = "sneeze" + emote_message_1p = "You sneeze." + emote_message_3p = "sneezes." + emote_sound_synthetic = list( + FEMALE = 'sound/effects/mob_effects/machine_sneeze.ogg', + MALE = 'sound/effects/mob_effects/f_machine_sneeze.ogg', + NEUTER = 'sound/effects/mob_effects/f_machine_sneeze.ogg', + PLURAL = 'sound/effects/mob_effects/f_machine_sneeze.ogg' + ) + emote_message_synthetic_1p = "You emit a robotic sneeze." + emote_message_synthetic_1p_target = "You emit a robotic sneeze towards TARGET." + emote_message_synthetic_3p = "emits a robotic sneeze." + emote_message_synthetic_3p_target = "emits a robotic sneeze towards TARGET." + +/decl/emote/audible/sneeze/get_emote_sound(var/atom/user) + if(ishuman(user) && !check_synthetic(user)) + var/mob/living/carbon/human/H = user + if(H.get_gender() == FEMALE) + return list( + "sound" = H.species.female_sneeze_sound, + "vol" = emote_volume + ) + else + return list( + "sound" = H.species.male_sneeze_sound, + "vol" = emote_volume + ) + return ..() diff --git a/code/modules/emotes/definitions/audible_whistle.dm b/code/modules/emotes/definitions/audible_whistle.dm new file mode 100644 index 00000000000..dabd64af59d --- /dev/null +++ b/code/modules/emotes/definitions/audible_whistle.dm @@ -0,0 +1,36 @@ +/decl/emote/audible/whistle + key = "whistle" + emote_message_1p = "You whistle a tune." + emote_message_3p = "whistles a tune." + emote_sound = 'sound/voice/longwhistle.ogg' + emote_message_muffled = "makes a light spitting noise, a poor attempt at a whistle." + emote_sound_synthetic = 'sound/voice/longwhistle_robot.ogg' + emote_message_synthetic_1p = "You whistle a robotic tune." + emote_message_synthetic_3p = "whistles a robotic tune." + +/decl/emote/audible/whistle/quiet + key = "qwhistle" + emote_message_1p = "You whistle quietly." + emote_message_3p = "whistles quietly." + emote_sound = 'sound/voice/shortwhistle.ogg' + emote_message_synthetic_1p = "You whistle robotically." + emote_message_synthetic_3p = "whistles robotically." + emote_sound_synthetic = 'sound/voice/shortwhistle_robot.ogg' + +/decl/emote/audible/whistle/wolf + key = "wwhistle" + emote_message_1p = "You whistle inappropriately." + emote_message_3p = "whistles inappropriately." + emote_sound = 'sound/voice/wolfwhistle.ogg' + emote_message_synthetic_1p = "You beep inappropriately." + emote_message_synthetic_3p = "beeps inappropriately." + emote_sound_synthetic = 'sound/voice/wolfwhistle_robot.ogg' + +/decl/emote/audible/whistle/summon + key = "swhistle" + emote_message_1p = "You whistle a tune." + emote_message_3p = "whistles a tune." + emote_sound = 'sound/voice/summon_whistle.ogg' + emote_message_synthetic_1p = "You whistle a robotic tune." + emote_message_synthetic_3p = "whistles a robotic tune." + emote_sound_synthetic = 'sound/voice/summon_whistle_robot.ogg' diff --git a/code/modules/emotes/definitions/exertion.dm b/code/modules/emotes/definitions/exertion.dm new file mode 100644 index 00000000000..ac0061cca32 --- /dev/null +++ b/code/modules/emotes/definitions/exertion.dm @@ -0,0 +1,40 @@ +/decl/emote/exertion/biological + key = "esweat" + emote_range = 4 + emote_message_1p = "You are sweating heavily." + emote_message_3p = "is sweating heavily." + +/decl/emote/exertion/biological/check_user(mob/living/user) + if(istype(user) && !user.isSynthetic()) + return ..() + return FALSE + +/decl/emote/exertion/biological/breath + key = "ebreath" + emote_message_1p = "You feel out of breath." + emote_message_3p = "looks out of breath." + +/decl/emote/exertion/biological/pant + key = "epant" + emote_range = 3 + message_type = AUDIBLE_MESSAGE + emote_message_1p = "You pant to catch your breath." + emote_message_3p = "pants for air." + emote_message_impaired = "You can see USER breathing heavily." + +/decl/emote/exertion/synthetic + key = "ewhine" + emote_range = 3 + message_type = AUDIBLE_MESSAGE + emote_message_1p = "You overstress your actuators." + emote_message_3p = "USER's actuators whine with strain." + +/decl/emote/exertion/synthetic/check_user(mob/living/user) + if(istype(user) && user.isSynthetic()) + return ..() + return FALSE + +/decl/emote/exertion/synthetic/creak + key = "ecreak" + emote_message_1p = "Your chassis stress indicators spike." + emote_message_3p = "USER's joints creak with stress." diff --git a/code/modules/emotes/definitions/helpers_vr.dm b/code/modules/emotes/definitions/helpers_vr.dm new file mode 100644 index 00000000000..6dc3a79bddc --- /dev/null +++ b/code/modules/emotes/definitions/helpers_vr.dm @@ -0,0 +1,33 @@ +// Not specifically /human type because those won't allow FBPs to use them +/decl/emote/helper/vwag + key = "vwag" + emote_message_3p = "" + +/decl/emote/helper/vwag/check_user(mob/living/carbon/human/user) + if(!istype(user) || (!user.tail_style || !user.tail_style.ani_state)) + return FALSE + return ..() + +/decl/emote/helper/vwag/do_emote(var/mob/living/carbon/human/user, var/extra_params) + if(user.toggle_tail(message = 1)) + return ..() + +/decl/emote/helper/vwag/get_emote_message_3p(var/mob/living/carbon/human/user, var/atom/target, var/extra_params) + return "[user.wagging ? "starts" : "stops"] wagging USER_THEIR tail." + + +/decl/emote/helper/vflap + key = "vflap" + emote_message_3p = "" + +/decl/emote/helper/vflap/check_user(mob/living/carbon/human/user) + if(!istype(user) || (!user.wing_style || !user.wing_style.ani_state)) + return FALSE + return ..() + +/decl/emote/helper/vflap/do_emote(var/mob/living/carbon/human/user, var/extra_params) + if(user.toggle_wing(message = 1)) + return ..() + +/decl/emote/helper/vflap/get_emote_message_3p(var/mob/living/carbon/human/user, var/atom/target, var/extra_params) + return "[user.flapping ? "starts" : "stops"] flapping USER_THEIR wings." diff --git a/code/modules/emotes/definitions/human.dm b/code/modules/emotes/definitions/human.dm new file mode 100644 index 00000000000..982e472c5f2 --- /dev/null +++ b/code/modules/emotes/definitions/human.dm @@ -0,0 +1,62 @@ +/decl/emote/human + key = "vomit" + +/decl/emote/human/check_user(var/mob/living/carbon/human/user) + return (istype(user))//VOREStation Edit - What does a mouth have to do with wagging?? && user.check_has_mouth() && !user.isSynthetic()) + +/decl/emote/human/do_emote(var/mob/living/carbon/human/user) + user.vomit() + +/decl/emote/human/deathgasp + key = "deathgasp" + +/decl/emote/human/deathgasp/do_emote(mob/living/carbon/human/user) + if(istype(user) && user.species.get_death_message(user) == DEATHGASP_NO_MESSAGE) + to_chat(user, SPAN_WARNING("Your species has no deathgasp.")) + return + . = ..() + +/decl/emote/human/deathgasp/get_emote_message_3p(var/mob/living/carbon/human/user) + return "USER [user.species.get_death_message(user)]" + +/decl/emote/human/swish + key = "swish" + +/decl/emote/human/swish/do_emote(var/mob/living/carbon/human/user) + user.animate_tail_once() + +/decl/emote/human/wag + key = "wag" + +/decl/emote/human/wag/do_emote(var/mob/living/carbon/human/user) + user.animate_tail_start() + +/decl/emote/human/sway + key = "sway" + +/decl/emote/human/sway/do_emote(var/mob/living/carbon/human/user) + user.animate_tail_start() + +/decl/emote/human/qwag + key = "qwag" + +/decl/emote/human/qwag/do_emote(var/mob/living/carbon/human/user) + user.animate_tail_fast() + +/decl/emote/human/fastsway + key = "fastsway" + +/decl/emote/human/fastsway/do_emote(var/mob/living/carbon/human/user) + user.animate_tail_fast() + +/decl/emote/human/swag + key = "swag" + +/decl/emote/human/swag/do_emote(var/mob/living/carbon/human/user) + user.animate_tail_stop() + +/decl/emote/human/stopsway + key = "stopsway" + +/decl/emote/human/stopsway/do_emote(var/mob/living/carbon/human/user) + user.animate_tail_stop() diff --git a/code/modules/emotes/definitions/slimes.dm b/code/modules/emotes/definitions/slimes.dm new file mode 100644 index 00000000000..877422825ba --- /dev/null +++ b/code/modules/emotes/definitions/slimes.dm @@ -0,0 +1,32 @@ +/decl/emote/slime + key = "nomood" + var/mood + +/decl/emote/slime/do_extra(var/mob/living/simple_mob/slime/user) + . = ..() + if(istype(user)) + user.mood = mood + user.update_icon() + +/decl/emote/slime/check_user(var/atom/user) + return isslime(user) + +/decl/emote/slime/pout + key = "pout" + mood = "pout" + +/decl/emote/slime/sad + key = "sad" + mood = "sad" + +/decl/emote/slime/angry + key = "angry" + mood = "angry" + +/decl/emote/slime/frown + key = "frown" + mood = "mischevous" + +/decl/emote/slime/smile + key = "smile" + mood = ":3" diff --git a/code/modules/emotes/definitions/synthetics.dm b/code/modules/emotes/definitions/synthetics.dm new file mode 100644 index 00000000000..2e31a07f8fd --- /dev/null +++ b/code/modules/emotes/definitions/synthetics.dm @@ -0,0 +1,51 @@ +/decl/emote/audible/synth + key = "beep" + emote_message_3p = "beeps." + emote_sound = 'sound/machines/twobeep.ogg' + +/decl/emote/audible/synth/check_user(var/mob/living/user) + if(istype(user) && user.isSynthetic()) + return ..() + return FALSE + +/decl/emote/audible/synth/ping + key = "ping" + emote_message_3p = "pings." + emote_sound = 'sound/machines/ping.ogg' + +/decl/emote/audible/synth/buzz + key = "buzz" + emote_message_3p = "buzzes." + emote_sound = 'sound/machines/buzz-sigh.ogg' + +/decl/emote/audible/synth/confirm + key = "confirm" + emote_message_3p = "emits an affirmative blip." + emote_sound = 'sound/machines/synth_yes.ogg' + +/decl/emote/audible/synth/deny + key = "deny" + emote_message_3p = "emits a negative blip." + emote_sound = 'sound/machines/synth_no.ogg' + +/decl/emote/audible/synth/security + key = "law" + emote_message_3p = "shows USER_THEIR legal authorization barcode." + emote_message_3p_target = "shows TARGET USER_THEIR legal authorization barcode." + emote_sound = 'sound/voice/biamthelaw.ogg' + +/decl/emote/audible/synth/security/check_user(var/mob/living/silicon/robot/user) + return (istype(user) && (istype(user.module, /obj/item/weapon/robot_module/robot/security) || istype(user.module, /obj/item/weapon/robot_module/robot/knine))) //VOREStation Add - knine module + +/decl/emote/audible/synth/security/halt + key = "halt" + emote_message_3p = "USER's speakers skreech, \"Halt! Security!\"." + emote_sound = 'sound/voice/halt.ogg' + +/decl/emote/audible/synth/dwoop + key = "dwoop" + emote_message_1p_target = "You chirp happily at TARGET!" + emote_message_1p = "You chirp happily." + emote_message_3p_target = "chirps happily at TARGET!" + emote_message_3p = "chirps happily." + emote_sound = 'sound/machines/dwoop.ogg' diff --git a/code/modules/emotes/definitions/visible.dm b/code/modules/emotes/definitions/visible.dm new file mode 100644 index 00000000000..986839fff1a --- /dev/null +++ b/code/modules/emotes/definitions/visible.dm @@ -0,0 +1,336 @@ +/decl/emote/visible + key ="tail" + emote_message_3p = "waves USER_THEIR tail." + message_type = VISIBLE_MESSAGE + +/decl/emote/visible/scratch + key = "scratch" + check_restraints = TRUE + emote_message_3p = "scratches." + +/decl/emote/visible/drool + key ="drool" + emote_message_3p = "drools." + conscious = FALSE + +/decl/emote/visible/nod + key ="nod" + emote_message_3p_target = "nods USER_THEIR head at TARGET." + emote_message_3p = "nods USER_THEIR head." + +/decl/emote/visible/sway + key ="sway" + emote_message_3p = "sways around dizzily." + +/decl/emote/visible/sulk + key ="sulk" + emote_message_3p = "sulks down sadly." + +/decl/emote/visible/dance + key ="dance" + check_restraints = TRUE + emote_message_3p = "dances around happily." + +/decl/emote/visible/roll + key ="roll" + check_restraints = TRUE + emote_message_3p = "rolls." + +/decl/emote/visible/shake + key ="shake" + emote_message_3p = "shakes USER_THEIR head." + +/decl/emote/visible/jump + key ="jump" + emote_message_3p = "jumps!" + +/decl/emote/visible/shiver + key ="shiver" + emote_message_3p = "shivers." + conscious = FALSE + +/decl/emote/visible/collapse + key ="collapse" + emote_message_3p = "collapses!" + +/decl/emote/visible/collapse/do_extra(var/mob/user) + ..() + if(istype(user)) + user.Paralyse(2) + +/decl/emote/visible/flash + key = "flash" + emote_message_3p = "flash USER_THEIR lights quickly." + +/decl/emote/visible/blink + key = "blink" + emote_message_3p = "blinks." + +/decl/emote/visible/airguitar + key = "airguitar" + check_restraints = TRUE + emote_message_3p = "is strumming the air and headbanging like a safari chimp." + +/decl/emote/visible/blink_r + key = "blink_r" + emote_message_3p = "blinks rapidly." + +/decl/emote/visible/bow + key = "bow" + emote_message_3p_target = "bows to TARGET." + emote_message_3p = "bows." + +/decl/emote/visible/salute + key = "salute" + emote_message_3p_target = "salutes TARGET." + emote_message_3p = "salutes." + check_restraints = TRUE + +/decl/emote/visible/flap + key = "flap" + check_restraints = TRUE + emote_message_3p = "flaps USER_THEIR wings." + +/decl/emote/visible/aflap + key = "aflap" + check_restraints = TRUE + emote_message_3p = "flaps USER_THEIR wings ANGRILY!" + +/decl/emote/visible/eyebrow + key = "eyebrow" + emote_message_3p = "raises an eyebrow." + +/decl/emote/visible/twitch + key = "twitch" + emote_message_3p = "twitches." + conscious = FALSE + +/decl/emote/visible/twitch_v + key = "twitch_v" + emote_message_3p = "twitches violently." + conscious = FALSE + +/decl/emote/visible/faint + key = "faint" + emote_message_3p = "faints." + +/decl/emote/visible/faint/do_extra(var/mob/user) + . = ..() + if(istype(user) && !user.sleeping) + user.Sleeping(10) + +/decl/emote/visible/frown + key = "frown" + emote_message_3p = "frowns." + +/decl/emote/visible/blush + key = "blush" + emote_message_3p = "blushes." + +/decl/emote/visible/wave + key = "wave" + emote_message_3p_target = "waves at TARGET." + emote_message_3p = "waves." + check_restraints = TRUE + +/decl/emote/visible/glare + key = "glare" + emote_message_3p_target = "glares at TARGET." + emote_message_3p = "glares." + +/decl/emote/visible/stare + key = "stare" + emote_message_3p_target = "stares at TARGET." + emote_message_3p = "stares." + +/decl/emote/visible/look + key = "look" + emote_message_3p_target = "looks at TARGET." + emote_message_3p = "looks." + +/decl/emote/visible/point + key = "point" + check_restraints = TRUE + emote_message_3p_target = "points to TARGET." + emote_message_3p = "points." + +/decl/emote/visible/raise + key = "raise" + check_restraints = TRUE + emote_message_3p = "raises a hand." + +/decl/emote/visible/grin + key = "grin" + emote_message_3p_target = "grins at TARGET." + emote_message_3p = "grins." + +/decl/emote/visible/shrug + key = "shrug" + emote_message_3p = "shrugs." + +/decl/emote/visible/smile + key = "smile" + emote_message_3p_target = "smiles at TARGET." + emote_message_3p = "smiles." + +/decl/emote/visible/pale + key = "pale" + emote_message_3p = "goes pale for a second." + +/decl/emote/visible/tremble + key = "tremble" + emote_message_3p = "trembles in fear!" + +/decl/emote/visible/wink + key = "wink" + emote_message_3p_target = "winks at TARGET." + emote_message_3p = "winks." + +/decl/emote/visible/hug + key = "hug" + check_restraints = TRUE + emote_message_3p_target = "hugs TARGET." + emote_message_3p = "hugs USER_SELF." + check_range = 1 + +/decl/emote/visible/dap + key = "dap" + check_restraints = TRUE + emote_message_3p_target = "gives daps to TARGET." + emote_message_3p = "sadly can't find anybody to give daps to, and daps USER_SELF." + +/decl/emote/visible/bounce + key = "bounce" + emote_message_3p = "bounces in place." + +/decl/emote/visible/jiggle + key = "jiggle" + emote_message_3p = "jiggles!" + +/decl/emote/visible/lightup + key = "light" + emote_message_3p = "lights up for a bit, then stops." + +/decl/emote/visible/vibrate + key = "vibrate" + emote_message_3p = "vibrates!" + +/decl/emote/visible/deathgasp_robot + key = "deathgasp" + emote_message_3p = "shudders violently for a moment, then becomes motionless, USER_THEIR eyes slowly darkening." + +/decl/emote/visible/handshake + key = "handshake" + check_restraints = TRUE + emote_message_3p_target = "shakes hands with TARGET." + emote_message_3p = "shakes hands with USER_SELF." + check_range = 1 + +/decl/emote/visible/handshake/get_emote_message_3p(var/atom/user, var/atom/target, var/extra_params) + if(target && !user.Adjacent(target)) + return "holds out USER_THEIR hand out to TARGET." + return ..() + +/decl/emote/visible/signal + key = "signal" + emote_message_3p_target = "signals at TARGET." + emote_message_3p = "signals." + check_restraints = TRUE + +/decl/emote/visible/signal/check_user(atom/user) + return ismob(user) + +/decl/emote/visible/signal/get_emote_message_3p(var/mob/living/user, var/atom/target, var/extra_params) + if(istype(user) && (!user.get_active_hand() || !user.get_inactive_hand())) + var/t1 = round(text2num(extra_params)) + if(isnum(t1) && t1 <= 5) + return "raises [t1] finger\s." + return .. () + +/decl/emote/visible/afold + key = "afold" + check_restraints = TRUE + emote_message_3p = "folds USER_THEIR arms." + +/decl/emote/visible/alook + key = "alook" + emote_message_3p = "looks away." + +/decl/emote/visible/hbow + key = "hbow" + emote_message_3p = "bows USER_THEIR head." + +/decl/emote/visible/hip + key = "hip" + check_restraints = TRUE + emote_message_3p = "puts USER_THEIR hands on USER_THEIR hips." + +/decl/emote/visible/holdup + key = "holdup" + check_restraints = TRUE + emote_message_3p = "holds up USER_THEIR palms." + +/decl/emote/visible/hshrug + key = "hshrug" + emote_message_3p = "gives a half shrug." + +/decl/emote/visible/crub + key = "crub" + check_restraints = TRUE + emote_message_3p = "rubs USER_THEIR chin." + +/decl/emote/visible/eroll + key = "eroll" + emote_message_3p = "rolls USER_THEIR eyes." + emote_message_3p_target = "rolls USER_THEIR eyes at TARGET." + +/decl/emote/visible/erub + key = "erub" + check_restraints = TRUE + emote_message_3p = "rubs USER_THEIR eyes." + +/decl/emote/visible/fslap + key = "fslap" + check_restraints = TRUE + emote_message_3p = "slaps USER_THEIR forehead." + +/decl/emote/visible/ftap + key = "ftap" + emote_message_3p = "taps USER_THEIR foot." + +/decl/emote/visible/hrub + key = "hrub" + check_restraints = TRUE + emote_message_3p = "rubs USER_THEIR hands together." + +/decl/emote/visible/hspread + key = "hspread" + check_restraints = TRUE + emote_message_3p = "spreads USER_THEIR hands." + +/decl/emote/visible/pocket + key = "pocket" + check_restraints = TRUE + emote_message_3p = "shoves USER_THEIR hands in USER_THEIR pockets." + +/decl/emote/visible/rsalute + key = "rsalute" + check_restraints = TRUE + emote_message_3p = "returns the salute." + +/decl/emote/visible/rshoulder + key = "rshoulder" + emote_message_3p = "rolls USER_THEIR shoulders." + +/decl/emote/visible/squint + key = "squint" + emote_message_3p = "squints." + emote_message_3p_target = "squints at TARGET." + +/decl/emote/visible/tfist + key = "tfist" + emote_message_3p = "tightens USER_THEIR hands into fists." + +/decl/emote/visible/tilt + key = "tilt" + emote_message_3p = "tilts USER_THEIR head." diff --git a/code/modules/emotes/definitions/visible_animated.dm b/code/modules/emotes/definitions/visible_animated.dm new file mode 100644 index 00000000000..2e035d289c7 --- /dev/null +++ b/code/modules/emotes/definitions/visible_animated.dm @@ -0,0 +1,76 @@ +/decl/emote/visible/spin + key = "spin" + check_restraints = TRUE + emote_message_3p = "spins!" + +/decl/emote/visible/spin/do_extra(mob/user) + if(istype(user)) + user.spin(20, 1) + +/decl/emote/visible/sidestep + key = "sidestep" + check_restraints = TRUE + emote_message_3p = "steps rhythmically and moves side to side." + +/decl/emote/visible/sidestep/do_extra(mob/user) + if(istype(user)) + animate(user, pixel_x = 5, time = 5) + sleep(3) + animate(user, pixel_x = -5, time = 5) + animate(pixel_x = user.default_pixel_x, pixel_y = user.default_pixel_x, time = 2) + +/decl/emote/visible/flip + key = "flip" + emote_message_1p = "You do a flip!" + emote_message_3p = "does a flip!" + emote_sound = 'sound/effects/bodyfall4.ogg' + +/decl/emote/visible/flip/do_extra(mob/user) + . = ..() + if(istype(user)) + user.SpinAnimation(7,1) + +/decl/emote/visible/floorspin + key = "floorspin" + emote_message_1p = "You spin around on the floor!" + emote_message_3p = "spins around on the floor!" + var/static/list/spin_dirs = list( + NORTH, + SOUTH, + EAST, + WEST, + EAST, + SOUTH, + NORTH, + SOUTH, + EAST, + WEST, + EAST, + SOUTH, + NORTH, + SOUTH, + EAST, + WEST, + EAST, + SOUTH + ) + +/decl/emote/visible/floorspin/proc/spin_dir(var/mob/user) + set waitfor = FALSE + for(var/i in spin_dirs) + user.set_dir(i) + sleep(1) + if(QDELETED(user)) + return + +/decl/emote/visible/floorspin/proc/spin_anim(var/mob/user) + set waitfor = FALSE + sleep(1) + if(!QDELETED(user)) + user.SpinAnimation(10,1) + +/decl/emote/visible/floorspin/do_extra(mob/user) + . = ..() + if(istype(user)) + spin_dir(user) + spin_anim(user) diff --git a/code/modules/emotes/definitions/visible_vomit.dm b/code/modules/emotes/definitions/visible_vomit.dm new file mode 100644 index 00000000000..1ec79dea6a9 --- /dev/null +++ b/code/modules/emotes/definitions/visible_vomit.dm @@ -0,0 +1,10 @@ +/decl/emote/visible/vomit + key = "vomit" + +/decl/emote/visible/vomit/do_emote(var/atom/user, var/extra_params) + if(isliving(user)) + var/mob/living/M = user + if(!M.isSynthetic()) + M.vomit() + return + to_chat(src, SPAN_WARNING("You are unable to vomit.")) diff --git a/code/modules/emotes/definitions/visible_vr.dm b/code/modules/emotes/definitions/visible_vr.dm new file mode 100644 index 00000000000..69252cf43be --- /dev/null +++ b/code/modules/emotes/definitions/visible_vr.dm @@ -0,0 +1,7 @@ +/decl/emote/visible/mlem + key = "mlem" + emote_message_3p = "mlems USER_THEIR tongue up over USER_THEIR nose. Mlem." + +/decl/emote/visible/blep + key = "blep" + emote_message_3p = "bleps USER_THEIR tongue out. Blep." diff --git a/code/modules/emotes/emote_define.dm b/code/modules/emotes/emote_define.dm new file mode 100644 index 00000000000..845a5202d31 --- /dev/null +++ b/code/modules/emotes/emote_define.dm @@ -0,0 +1,181 @@ +// Note about emote messages: +// - USER / TARGET will be replaced with the relevant name, in bold. +// - USER_THEM / TARGET_THEM / USER_THEIR / TARGET_THEIR will be replaced with a +// gender-appropriate version of the same. +// - Impaired messages do not do any substitutions. + +/decl/emote + var/key // Command to use emote ie. '*[key]' + var/emote_message_1p // First person message ('You do a flip!') + var/emote_message_3p // Third person message ('Urist McBackflip does a flip!') + var/emote_message_synthetic_1p // First person message for robits. + var/emote_message_synthetic_3p // Third person message for robits. + + var/emote_message_impaired // Deaf/blind message ('You hear someone flipping out.', 'You see someone opening and closing their mouth') + + var/emote_message_1p_target // 'You do a flip at Urist McTarget!' + var/emote_message_3p_target // 'Urist McShitter does a flip at Urist McTarget!' + var/emote_message_synthetic_1p_target // First person targeted message for robits. + var/emote_message_synthetic_3p_target // Third person targeted message for robits. + + var/emote_message_radio // A message to send over the radio if one picks up this emote. + var/emote_message_radio_synthetic // As above, but for synthetics. + var/emote_message_muffled // A message to show if the emote is audible and the user is muzzled. + + var/list/emote_sound // A sound for the emote to play. + // Can either be a single sound, a list of sounds to pick from, or an + // associative array of gender to single sounds/a list of sounds. + var/list/emote_sound_synthetic // As above, but used when check_synthetic() is true. + var/emote_volume = 50 // Volume of sound to play. + var/emote_volume_synthetic = 50 // As above, but used when check_synthetic() is true. + + var/message_type = VISIBLE_MESSAGE // Audible/visual flag + var/check_restraints // Can this emote be used while restrained? + var/check_range // falsy, or a range outside which the emote will not work + var/conscious = TRUE // Do we need to be awake to emote this? + var/emote_range = 0 // If >0, restricts emote visibility to viewers within range. + +/decl/emote/proc/get_emote_message_1p(var/atom/user, var/atom/target, var/extra_params) + if(target) + if(emote_message_synthetic_1p_target && check_synthetic(user)) + return emote_message_synthetic_1p_target + return emote_message_1p_target + if(emote_message_synthetic_1p && check_synthetic(user)) + return emote_message_synthetic_1p + return emote_message_1p + +/decl/emote/proc/get_emote_message_3p(var/atom/user, var/atom/target, var/extra_params) + if(target) + if(emote_message_synthetic_3p_target && check_synthetic(user)) + return emote_message_synthetic_3p_target + return emote_message_3p_target + if(emote_message_synthetic_3p && check_synthetic(user)) + return emote_message_synthetic_3p + return emote_message_3p + +/decl/emote/proc/get_emote_sound(var/atom/user) + if(check_synthetic(user) && emote_sound_synthetic) + return list( + "sound" = emote_sound_synthetic, + "vol" = emote_volume_synthetic + ) + if(emote_sound) + return list( + "sound" = emote_sound, + "vol" = emote_volume + ) + +/decl/emote/proc/do_emote(var/atom/user, var/extra_params) + if(ismob(user) && check_restraints) + var/mob/M = user + if(M.restrained()) + to_chat(user, SPAN_WARNING("You are restrained and cannot do that.")) + return + + var/atom/target + if(can_target() && extra_params) + extra_params = lowertext(extra_params) + for(var/atom/thing in view(user)) + if(extra_params == lowertext(thing.name)) + target = thing + break + + if(target && target != user && check_range) + if (get_dist(user, target) > check_range) + to_chat(user, SPAN_WARNING("\The [target] is too far away.")) + return + + var/use_1p = get_emote_message_1p(user, target, extra_params) + if(use_1p) + if(target) + use_1p = replace_target_tokens(use_1p, target) + use_1p = "[capitalize(replace_user_tokens(use_1p, user))]" + var/use_3p = get_emote_message_3p(user, target, extra_params) + if(use_3p) + if(target) + use_3p = replace_target_tokens(use_3p, target) + use_3p = "\The [user] [replace_user_tokens(use_3p, user)]" + var/use_radio = get_radio_message(user) + if(use_radio) + if(target) + use_radio = replace_target_tokens(use_radio, target) + use_radio = replace_user_tokens(use_radio, user) + + var/use_range = emote_range + if (!use_range) + use_range = world.view + + if(ismob(user)) + var/mob/M = user + if(message_type == AUDIBLE_MESSAGE) + if(isliving(user)) + var/mob/living/L = user + if(L.silent) + M.visible_message(message = "[user] opens their mouth silently!", self_message = "You cannot say anything!", blind_message = emote_message_impaired) + return + else + M.audible_message(message = use_3p, self_message = use_1p, deaf_message = emote_message_impaired, hearing_distance = use_range, radio_message = use_radio) + else + M.visible_message(message = use_3p, self_message = use_1p, blind_message = emote_message_impaired, range = use_range) + + do_extra(user, target) + do_sound(user) + +/decl/emote/proc/replace_target_tokens(var/msg, var/atom/target) + . = msg + if(istype(target)) + var/datum/gender/target_gender = gender_datums[target.get_visible_gender()] + . = replacetext(., "TARGET_THEM", target_gender.him) + . = replacetext(., "TARGET_THEIR", target_gender.his) + . = replacetext(., "TARGET_SELF", target_gender.himself) + . = replacetext(., "TARGET", "\the [target]") + +/decl/emote/proc/replace_user_tokens(var/msg, var/atom/user) + . = msg + if(istype(user)) + var/datum/gender/user_gender = gender_datums[user.get_visible_gender()] + . = replacetext(., "USER_THEM", user_gender.him) + . = replacetext(., "USER_THEIR", user_gender.his) + . = replacetext(., "USER_SELF", user_gender.himself) + . = replacetext(., "USER", "\the [user]") + +/decl/emote/proc/get_radio_message(var/atom/user) + if(emote_message_radio_synthetic && check_synthetic(user)) + return emote_message_radio_synthetic + return emote_message_radio + +/decl/emote/proc/do_extra(var/atom/user, var/atom/target) + return + +/decl/emote/proc/do_sound(var/atom/user) + var/list/use_sound = get_emote_sound(user) + if(!islist(use_sound) || length(use_sound) < 2) + return + var/sound_to_play = use_sound["sound"] + if(!sound_to_play) + return + if(islist(sound_to_play)) + if(sound_to_play[user.gender]) + sound_to_play = sound_to_play[user.gender] + if(islist(sound_to_play) && length(sound_to_play)) + sound_to_play = pick(sound_to_play) + if(sound_to_play) + playsound(user.loc, sound_to_play, use_sound["vol"], 0, preference = /datum/client_preference/emote_noises) //VOREStation Add - Preference + +/decl/emote/proc/check_user(var/atom/user) + return TRUE + +/decl/emote/proc/can_target() + return (emote_message_1p_target || emote_message_3p_target) + +/decl/emote/dd_SortValue() + return key + +/decl/emote/proc/check_synthetic(var/mob/living/user) + . = istype(user) && user.isSynthetic() + if(!. && ishuman(user) && message_type == AUDIBLE_MESSAGE) + var/mob/living/carbon/human/H = user + if(H.should_have_organ(O_LUNGS)) + var/obj/item/organ/internal/lungs/L = H.internal_organs_by_name[O_LUNGS] + if(L && L.robotic == 2) //Hard-coded to 2, incase we add lifelike robotic lungs + . = TRUE diff --git a/code/modules/emotes/emote_mob.dm b/code/modules/emotes/emote_mob.dm new file mode 100644 index 00000000000..3e45f05091e --- /dev/null +++ b/code/modules/emotes/emote_mob.dm @@ -0,0 +1,183 @@ +/mob/proc/can_emote(var/emote_type) + return (stat == CONSCIOUS) + +/mob/living/can_emote(var/emote_type) + return (..() && !(silent && emote_type == AUDIBLE_MESSAGE)) + +/mob/proc/emote(var/act, var/m_type, var/message) + set waitfor = FALSE + // s-s-snowflake + if(src.stat == DEAD && act != "deathgasp") + return + + if(usr == src) //client-called emote + if (client && (client.prefs.muted & MUTE_IC)) + to_chat(src, "You cannot send IC messages (muted).") + return + + if(act == "help") + to_chat(src,"Usable emotes: [english_list(usable_emotes)].") + return + + if(!can_emote(m_type)) + to_chat(src, SPAN_WARNING("You cannot currently [m_type == AUDIBLE_MESSAGE ? "audibly" : "visually"] emote!")) + return + + if(act == "me") + return custom_emote(m_type, message) + + if(act == "custom") + if(!message) + message = sanitize_or_reflect(input(src,"Choose an emote to display.") as text|null, src) //VOREStation Edit - Reflect too long messages, within reason + if(!message) + return + if (!m_type) + if(alert(src, "Is this an audible emote?", "Emote", "Yes", "No") == "No") + m_type = VISIBLE_MESSAGE + else + m_type = AUDIBLE_MESSAGE + return custom_emote(m_type, message) + + var/splitpoint = findtext(act, " ") + if(splitpoint > 0) + var/tempstr = act + act = copytext(tempstr,1,splitpoint) + message = copytext(tempstr,splitpoint+1,0) + + //VOREStation Add - NIF soulcatcher shortcuts + if(act == "nsay") + return nsay(message) + + if(act == "nme") + return nme(message) + //VOREStation Add End + + var/decl/emote/use_emote = usable_emotes[act] + if(!use_emote) + to_chat(src, SPAN_WARNING("Unknown emote '[act]'. Type say *help for a list of usable emotes.")) + return + + if(m_type != use_emote.message_type && use_emote.conscious && stat != CONSCIOUS) + return + + if(use_emote.message_type == AUDIBLE_MESSAGE && is_muzzled()) + audible_message("\The [src] [use_emote.emote_message_muffled || "makes a muffled sound."]") + return + else + use_emote.do_emote(src, message) + + for (var/obj/item/weapon/implant/I in src) + if (I.implanted) + I.trigger(act, src) + +/mob/proc/format_emote(var/emoter = null, var/message = null) + var/pretext + var/subtext + var/nametext + var/end_char + var/start_char + var/name_anchor + + if(!message || !emoter) + return + + message = html_decode(message) + + name_anchor = findtext(message, "*") + if(name_anchor > 0) // User supplied emote with visible_emote token (default ^) + pretext = copytext(message, 1, name_anchor) + subtext = copytext(message, name_anchor + 1, length(message) + 1) + else + // No token. Just the emote as usual. + subtext = message + + // Oh shit, we got this far! Let's see... did the user attempt to use more than one token? + if(findtext(subtext, "*")) + // abort abort! + to_chat(emoter, SPAN_WARNING("You may use only one \"["*"]\" symbol in your emote.")) + return + + if(pretext) + // Add a space at the end if we didn't already supply one. + end_char = copytext(pretext, length(pretext), length(pretext) + 1) + if(end_char != " ") + pretext += " " + + // Grab the last character of the emote message. + end_char = copytext(subtext, length(subtext), length(subtext) + 1) + if(!(end_char in list(".", "?", "!", "\"", "-", "~"))) // gotta include ~ for all you fucking weebs + // No punctuation supplied. Tack a period on the end. + subtext += "." + + // Add a space to the subtext, unless it begins with an apostrophe or comma. + if(subtext != ".") + // First, let's get rid of any existing space, to account for sloppy emoters ("X, ^ , Y") + subtext = trim_left(subtext) + start_char = copytext(subtext, 1, 2) + if(start_char != "," && start_char != "'") + subtext = " " + subtext + + pretext = capitalize(html_encode(pretext)) + nametext = html_encode(nametext) + subtext = html_encode(subtext) + // Store the player's name in a nice bold, naturalement + nametext = "[emoter]" + return pretext + nametext + subtext + +/mob/proc/custom_emote(var/m_type = VISIBLE_MESSAGE, var/message, var/range = world.view) + + if((usr && stat) || (!use_me && usr == src)) + to_chat(src, "You are unable to emote.") + return + + var/input + if(!message) + input = sanitize(input(src,"Choose an emote to display.") as text|null) + else + input = message + + if(input) + message = format_emote(src, message) + else + return + + if(input) + log_emote(message,src) //Log before we add junk + message = "[src] [input]" + else + return + + if(message) + message = encode_html_emphasis(message) + + // Hearing gasp and such every five seconds is not good emotes were not global for a reason. + // Maybe some people are okay with that. + var/turf/T = get_turf(src) + if(!T) return + var/list/in_range = get_mobs_and_objs_in_view_fast(T,range,2,remote_ghosts = client ? TRUE : FALSE) + var/list/m_viewers = in_range["mobs"] + var/list/o_viewers = in_range["objs"] + + for(var/mob in m_viewers) + var/mob/M = mob + spawn(0) // It's possible that it could be deleted in the meantime, or that it runtimes. + if(M) + if(isobserver(M)) + message = "[src] ([ghost_follow_link(src, M)]) [input]" + M.show_message(message, m_type) + + for(var/obj in o_viewers) + var/obj/O = obj + spawn(0) + if(O) + O.see_emote(src, message, m_type) + + + +// Specific mob type exceptions below. +/mob/living/silicon/ai/emote(var/act, var/type, var/message) + var/obj/machinery/hologram/holopad/T = src.holo + if(T && T.masters[src]) //Is the AI using a holopad? + src.holopad_emote(message) + else //Emote normally, then. + ..() diff --git a/code/modules/events/meteor_strike_vr.dm b/code/modules/events/meteor_strike_vr.dm index 8868c577cd6..83b1f8ac2d9 100644 --- a/code/modules/events/meteor_strike_vr.dm +++ b/code/modules/events/meteor_strike_vr.dm @@ -61,10 +61,6 @@ var/turf/mob_turf = get_turf(L) if(!mob_turf || !(mob_turf.z in impacted.expected_z_levels)) continue - if(!L.buckled && !issilicon(L)) - if(!L.Check_Shoegrip()) - L.throw_at(get_step_rand(L),1,5) - L.Weaken(5) if(L.client) to_chat(L, "The ground lurches beneath you!") shake_camera(L, 6, 1) diff --git a/code/modules/events/supply_demand_vr.dm b/code/modules/events/supply_demand_vr.dm index 6447630c9e5..64d402c443e 100644 --- a/code/modules/events/supply_demand_vr.dm +++ b/code/modules/events/supply_demand_vr.dm @@ -274,8 +274,7 @@ /datum/event/supply_demand/proc/choose_chemistry_items(var/differentTypes) // Checking if they show up in health analyzer is good huristic for it being a drug var/list/medicineReagents = list() - for(var/path in typesof(/datum/chemical_reaction) - /datum/chemical_reaction) - var/datum/chemical_reaction/CR = path // Stupid casting required for reading + for(var/decl/chemical_reaction/instant/CR in SSchemistry.chemical_reactions) var/datum/reagent/R = SSchemistry.chemical_reagents[initial(CR.result)] if(R && R.scannable) medicineReagents += R @@ -288,8 +287,7 @@ /datum/event/supply_demand/proc/choose_bar_items(var/differentTypes) var/list/drinkReagents = list() - for(var/path in typesof(/datum/chemical_reaction) - /datum/chemical_reaction) - var/datum/chemical_reaction/CR = path // Stupid casting required for reading + for(var/decl/chemical_reaction/instant/drinks/CR in SSchemistry.chemical_reactions) var/datum/reagent/R = SSchemistry.chemical_reagents[initial(CR.result)] if(istype(R, /datum/reagent/drink) || istype(R, /datum/reagent/ethanol)) drinkReagents += R diff --git a/code/modules/examine/descriptions/weapons.dm b/code/modules/examine/descriptions/weapons.dm index 8acb089a4c6..747fa0f75f6 100644 --- a/code/modules/examine/descriptions/weapons.dm +++ b/code/modules/examine/descriptions/weapons.dm @@ -30,7 +30,7 @@ description_info = "This is an energy weapon. To fire the weapon, ensure your intent is *not* set to 'help', have your gun mode set to 'fire', \ then click where you want to fire. Most energy weapons can fire through windows harmlessly. To recharge this weapon, use a weapon recharger." -/obj/item/weapon/gun/energy/gun/stunrevolver +/obj/item/weapon/gun/energy/stunrevolver description_info = "This is an energy weapon. To fire the weapon, ensure your intent is *not* set to 'help', have your gun mode set to 'fire', \ then click where you want to fire. Most energy weapons can fire through windows harmlessly. To recharge this weapon, use a weapon recharger." diff --git a/code/modules/food/food/cans_vr.dm b/code/modules/food/food/cans_vr.dm new file mode 100644 index 00000000000..4807d021ef5 --- /dev/null +++ b/code/modules/food/food/cans_vr.dm @@ -0,0 +1,75 @@ +//////////////////////Bepis Drinks (04/29/2021)////////////////////// + +/obj/item/weapon/reagent_containers/food/drinks/cans/bepis + name = "\improper Bepis" + desc = "It has a smell of 'off-brand' whenever you open it..." + description_fluff = "Puts the 'B' in Best Soda! Bepis is the number one competitor to \ + Space Cola and has vendors scattered across the frontier. While the drink is not as \ + popular as Space Cola, many people across known space enjoy the sweet beverage." + icon = 'icons/obj/drinks_vr.dmi' + icon_state = "bepis" + center_of_mass = list("x"=16, "y"=10) + +/obj/item/weapon/reagent_containers/food/drinks/cans/bepis/Initialize() + . = ..() + reagents.add_reagent("bepis", 30) + +/obj/item/weapon/reagent_containers/food/drinks/cans/astrodew + name = "\improper Astro Dew Spring Water" + desc = "A can of refreshing 'spring' water! Or so the can claims." + icon = 'icons/obj/drinks_vr.dmi' + icon_state = "watercan" + center_of_mass = list("x"=16, "y"=10) + +/obj/item/weapon/reagent_containers/food/drinks/cans/astrodew/Initialize() + . = ..() + reagents.add_reagent("water", 30) + +/obj/item/weapon/reagent_containers/food/drinks/cans/icecoffee + name = "\improper Café Del Consumir" + desc = "A can of deliciously sweet iced coffee that originates from Earth." + description_fluff = "Café Del Consumir originates from a small coffee brewery in México \ + that still opperates to this day. Café Del Consumir prides itself on being true to form \ + and retaining its original recipe. They've been producing and selling thier product across \ + the galaxy for decades without fail. NanoTrasen has attempted to by out the small company for \ + years now, howerver all attempts they've made have failed." + icon = 'icons/obj/drinks_vr.dmi' + icon_state = "coffeecan" + center_of_mass = list("x"=16, "y"=10) + +/obj/item/weapon/reagent_containers/food/drinks/cans/icecoffee/Initialize() + . = ..() + reagents.add_reagent("icecoffee", 30) + +/obj/item/weapon/reagent_containers/food/drinks/cans/buzz + name = "\improper Buzz Fuzz" + desc = "Uses real honey, making it a sweet tooth's dream drink." + icon = 'icons/obj/drinks_vr.dmi' + icon_state = "buzzfuzz" + center_of_mass = list("x"=16, "y"=10) + +/obj/item/weapon/reagent_containers/food/drinks/cans/buzz/Initialize() + . = ..() + reagents.add_reagent("buzz_fuzz", 30) + +/obj/item/weapon/reagent_containers/food/drinks/cans/shambler + name = "\improper Shambler's Juice" + desc = "~Shake me up some of that Shambler's Juice!~" + icon = 'icons/obj/drinks_vr.dmi' + icon_state = "shambler" + center_of_mass = list("x"=16, "y"=10) + +/obj/item/weapon/reagent_containers/food/drinks/cans/shambler/Initialize() + . = ..() + reagents.add_reagent("shamblers", 30) + +/obj/item/weapon/reagent_containers/food/drinks/cans/cranberry + name = "\improper Sprited Cranberry" + desc = "A delicious blend of fresh cranberry juice and various spices, the perfect drink." + icon = 'icons/obj/drinks_vr.dmi' + icon_state = "cranberry" + center_of_mass = list("x"=16, "y"=10) + +/obj/item/weapon/reagent_containers/food/drinks/cans/cranberry/Initialize() + . = ..() + reagents.add_reagent("sprited_cranberry", 30) \ No newline at end of file diff --git a/code/modules/food/food/drinks/bottle.dm b/code/modules/food/food/drinks/bottle.dm index 56d303371a7..1f7beec6b9e 100644 --- a/code/modules/food/food/drinks/bottle.dm +++ b/code/modules/food/food/drinks/bottle.dm @@ -341,20 +341,20 @@ . = ..() reagents.add_reagent("absinthe", 100) -/obj/item/weapon/reagent_containers/food/drinks/bottle/melonliquor - name = "Emeraldine Melon Liquor" +/obj/item/weapon/reagent_containers/food/drinks/bottle/melonliquor //MODIFIED ON 04/21/2021 + name = "Emeraldine Melon Liqueur" desc = "A bottle of 46 proof Emeraldine Melon Liquor. Sweet and light." - icon_state = "alco-green" //Placeholder. + icon_state = "melon_liqueur" center_of_mass = list("x"=16, "y"=6) /obj/item/weapon/reagent_containers/food/drinks/bottle/melonliquor/Initialize() . = ..() reagents.add_reagent("melonliquor", 100) -/obj/item/weapon/reagent_containers/food/drinks/bottle/bluecuracao +/obj/item/weapon/reagent_containers/food/drinks/bottle/bluecuracao //MODIFIED ON 04/21/2021 name = "Miss Blue Curacao" desc = "A fruity, exceptionally azure drink. Does not allow the imbiber to use the fifth magic." - icon_state = "alco-blue" //Placeholder. + icon_state = "blue_curacao" center_of_mass = list("x"=16, "y"=6) /obj/item/weapon/reagent_containers/food/drinks/bottle/bluecuracao/Initialize() @@ -371,36 +371,6 @@ . = ..() reagents.add_reagent("grenadine", 100) -/obj/item/weapon/reagent_containers/food/drinks/bottle/cola - name = "\improper Space Cola" - desc = "Cola. in space" - icon_state = "colabottle" - center_of_mass = list("x"=16, "y"=6) - -/obj/item/weapon/reagent_containers/food/drinks/bottle/cola/Initialize() - . = ..() - reagents.add_reagent("cola", 100) - -/obj/item/weapon/reagent_containers/food/drinks/bottle/space_up - name = "\improper Space-Up" - desc = "Tastes like a hull breach in your mouth." - icon_state = "space-up_bottle" - center_of_mass = list("x"=16, "y"=6) - -/obj/item/weapon/reagent_containers/food/drinks/bottle/space_up/Initialize() - . = ..() - reagents.add_reagent("space_up", 100) - -/obj/item/weapon/reagent_containers/food/drinks/bottle/space_mountain_wind - name = "\improper Space Mountain Wind" - desc = "Blows right through you like a space wind." - icon_state = "space_mountain_wind_bottle" - center_of_mass = list("x"=16, "y"=6) - -/obj/item/weapon/reagent_containers/food/drinks/bottle/space_mountain_wind/Initialize() - . = ..() - reagents.add_reagent("spacemountainwind", 100) - /obj/item/weapon/reagent_containers/food/drinks/bottle/pwine name = "Warlock's Velvet" desc = "What a delightful packaging for a surely high quality wine! The vintage must be amazing!" @@ -421,7 +391,107 @@ . = ..() reagents.add_reagent("unathiliquor", 100) -//////////////////////////JUICES AND STUFF /////////////////////// +/obj/item/weapon/reagent_containers/food/drinks/bottle/sake + name = "Mono-No-Aware Luxury Sake" + desc = "Dry alcohol made from rice, a favorite of businessmen." + icon_state = "sakebottle" + center_of_mass = list("x"=16, "y"=3) + +/obj/item/weapon/reagent_containers/food/drinks/bottle/sake/Initialize() + . = ..() + reagents.add_reagent("sake", 100) + +/obj/item/weapon/reagent_containers/food/drinks/bottle/champagne + name = "Gilthari Luxury Champagne" + desc = "For those special occassions." + icon_state = "champagne" + center_of_mass = list("x"=16, "y"=3) + +/obj/item/weapon/reagent_containers/food/drinks/bottle/champagne/Initialize() + . = ..() + reagents.add_reagent("champagne", 100) + +/obj/item/weapon/reagent_containers/food/drinks/bottle/peppermintschnapps + name = "Dr. Bone's Peppermint Schnapps" + desc = "A flavoured grain liqueur with a fresh, minty taste." + icon_state = "schnapps_pep" + center_of_mass = list("x"=16, "y"=3) + +/obj/item/weapon/reagent_containers/food/drinks/bottle/peppermintschnapps/Initialize() + . = ..() + reagents.add_reagent("schnapps_pep", 100) + +/obj/item/weapon/reagent_containers/food/drinks/bottle/peachschnapps + name = "Dr. Bone's Peach Schnapps" + desc = "A flavoured grain liqueur with a fruity peach taste." + icon_state = "schnapps_pea" + center_of_mass = list("x"=16, "y"=3) + +/obj/item/weapon/reagent_containers/food/drinks/bottle/peachschnapps/Initialize() + . = ..() + reagents.add_reagent("schnapps_pea", 100) + +/obj/item/weapon/reagent_containers/food/drinks/bottle/lemonadeschnapps + name = "Dr. Bone's Lemonade Schnapps" + desc = "A flavoured grain liqueur with a sweetish, lemon taste." + icon_state = "schnapps_lem" + center_of_mass = list("x"=16, "y"=3) + +/obj/item/weapon/reagent_containers/food/drinks/bottle/lemonadeschnapps/Initialize() + . = ..() + reagents.add_reagent("schnapps_lem", 100) + +/obj/item/weapon/reagent_containers/food/drinks/bottle/jager + name = "Schusskonig" + desc = "A complex tasting digestif. Thank god the original's trademark lapsed." + icon_state = "jager_bottle" + center_of_mass = list("x"=16, "y"=3) + +/obj/item/weapon/reagent_containers/food/drinks/bottle/jager/Initialize() + . = ..() + reagents.add_reagent("jager", 100) + +//////////////////////////JUICES AND STUFF/////////////////////// + +/obj/item/weapon/reagent_containers/food/drinks/bottle/cola //MODIFIED ON 04/21/2021 + name = "\improper two-liter Space Cola" + desc = "Cola. In space." + icon_state = "colabottle" + center_of_mass = list("x"=16, "y"=6) + +/obj/item/weapon/reagent_containers/food/drinks/bottle/cola/Initialize() + . = ..() + reagents.add_reagent("cola", 100) + +/obj/item/weapon/reagent_containers/food/drinks/bottle/space_up //MODIFIED ON 04/21/2021 + name = "\improper two-liter Space-Up" + desc = "Tastes like a hull breach in your mouth." + icon_state = "space-up_bottle" + center_of_mass = list("x"=16, "y"=6) + +/obj/item/weapon/reagent_containers/food/drinks/bottle/space_up/Initialize() + . = ..() + reagents.add_reagent("space_up", 100) + +/obj/item/weapon/reagent_containers/food/drinks/bottle/space_mountain_wind //MODIFIED ON 04/21/2021 + name = "\improper two-liter Space Mountain Wind" + desc = "Blows right through you like a space wind." + icon_state = "space_mountain_wind_bottle" + center_of_mass = list("x"=16, "y"=6) + +/obj/item/weapon/reagent_containers/food/drinks/bottle/space_mountain_wind/Initialize() + . = ..() + reagents.add_reagent("spacemountainwind", 100) + +/obj/item/weapon/reagent_containers/food/drinks/bottle/dr_gibb //ADDED ON 04/21/2021 + name = "\improper two-liter Dr. Gibb" + desc = "A delicious mixture of 42 different flavors." + icon_state = "dr_gibb_bottle" + center_of_mass = list("x"=16, "y"=6) + +/obj/item/weapon/reagent_containers/food/drinks/bottle/dr_gibb/Initialize() + . = ..() + reagents.add_reagent("dr_gibb", 100) /obj/item/weapon/reagent_containers/food/drinks/bottle/orangejuice name = "Orange Juice" @@ -507,7 +577,8 @@ . = ..() reagents.add_reagent("lemonjuice", 100) -//Small bottles +//////////////////////////SMALL BOTTLES/////////////////////// + /obj/item/weapon/reagent_containers/food/drinks/bottle/small volume = 50 smash_duration = 1 @@ -578,63 +649,3 @@ /obj/item/weapon/reagent_containers/food/drinks/bottle/small/ale/hushedwhisper/Initialize() . = ..() reagents.add_reagent("ale", 50) - -/obj/item/weapon/reagent_containers/food/drinks/bottle/sake - name = "Mono-No-Aware Luxury Sake" - desc = "Dry alcohol made from rice, a favorite of businessmen." - icon_state = "sakebottle" - center_of_mass = list("x"=16, "y"=3) - -/obj/item/weapon/reagent_containers/food/drinks/bottle/sake/Initialize() - . = ..() - reagents.add_reagent("sake", 100) - -/obj/item/weapon/reagent_containers/food/drinks/bottle/champagne - name = "Gilthari Luxury Champagne" - desc = "For those special occassions." - icon_state = "champagne" - center_of_mass = list("x"=16, "y"=3) - -/obj/item/weapon/reagent_containers/food/drinks/bottle/champagne/Initialize() - . = ..() - reagents.add_reagent("champagne", 100) - -/obj/item/weapon/reagent_containers/food/drinks/bottle/peppermintschnapps - name = "Dr. Bone's Peppermint Schnapps" - desc = "A flavoured grain liqueur with a fresh, minty taste." - icon_state = "schnapps_pep" - center_of_mass = list("x"=16, "y"=3) - -/obj/item/weapon/reagent_containers/food/drinks/bottle/peppermintschnapps/Initialize() - . = ..() - reagents.add_reagent("schnapps_pep", 100) - -/obj/item/weapon/reagent_containers/food/drinks/bottle/peachschnapps - name = "Dr. Bone's Peach Schnapps" - desc = "A flavoured grain liqueur with a fruity peach taste." - icon_state = "schnapps_pea" - center_of_mass = list("x"=16, "y"=3) - -/obj/item/weapon/reagent_containers/food/drinks/bottle/peachschnapps/Initialize() - . = ..() - reagents.add_reagent("schnapps_pea", 100) - -/obj/item/weapon/reagent_containers/food/drinks/bottle/lemonadeschnapps - name = "Dr. Bone's Lemonade Schnapps" - desc = "A flavoured grain liqueur with a sweetish, lemon taste." - icon_state = "schnapps_lem" - center_of_mass = list("x"=16, "y"=3) - -/obj/item/weapon/reagent_containers/food/drinks/bottle/lemonadeschnapps/Initialize() - . = ..() - reagents.add_reagent("schnapps_lem", 100) - -/obj/item/weapon/reagent_containers/food/drinks/bottle/jager - name = "Schusskonig" - desc = "A complex tasting digestif. Thank god the original's trademark lapsed." - icon_state = "jager_bottle" - center_of_mass = list("x"=16, "y"=3) - -/obj/item/weapon/reagent_containers/food/drinks/bottle/jager/Initialize() - . = ..() - reagents.add_reagent("jager", 100) diff --git a/code/modules/food/recipe_dump.dm b/code/modules/food/recipe_dump.dm index df0e6874aa6..63dc510eb94 100644 --- a/code/modules/food/recipe_dump.dm +++ b/code/modules/food/recipe_dump.dm @@ -8,13 +8,11 @@ //////////////////////// DRINK var/list/drink_recipes = list() - for(var/path in typesof(/datum/chemical_reaction/drinks) - /datum/chemical_reaction/drinks) - var/datum/chemical_reaction/drinks/CR = new path() - drink_recipes[path] = list("Result" = CR.name, + for(var/decl/chemical_reaction/instant/drinks/CR in SSchemistry.chemical_reactions) + drink_recipes[CR.type] = list("Result" = CR.name, "ResAmt" = CR.result_amount, "Reagents" = CR.required_reagents, "Catalysts" = CR.catalysts) - qdel(CR) //////////////////////// FOOD var/list/food_recipes = typesof(/datum/recipe) - /datum/recipe @@ -43,16 +41,14 @@ qdel(R) //////////////////////// FOOD+ (basically condiments, tofu, cheese, soysauce, etc) - for(var/path in typesof(/datum/chemical_reaction/food) - /datum/chemical_reaction/food) - var/datum/chemical_reaction/food/CR = new path() - food_recipes[path] = list("Result" = CR.name, + for(var/decl/chemical_reaction/instant/food/CR in SSchemistry.chemical_reactions) + food_recipes[CR.type] = list("Result" = CR.name, "ResAmt" = CR.result_amount, "Reagents" = CR.required_reagents, "Catalysts" = CR.catalysts, "Fruit" = list(), "Ingredients" = list(), "Image" = null) - qdel(CR) //////////////////////// PROCESSING //Items needs further processing into human-readability. diff --git a/code/modules/genetics/side_effects.dm b/code/modules/genetics/side_effects.dm index fbbce61398e..25d8ba32e6f 100644 --- a/code/modules/genetics/side_effects.dm +++ b/code/modules/genetics/side_effects.dm @@ -21,7 +21,7 @@ duration = 10*30 start(mob/living/carbon/human/H) - H.emote("me", 1, "starts turning very red..") + H.custom_emote(VISIBLE_MESSAGE, "starts turning very red..") finish(mob/living/carbon/human/H) if(!H.reagents.has_reagent("dexalin")) @@ -37,7 +37,7 @@ duration = 10*60 start(mob/living/carbon/human/H) - H.emote("me", 1, "'s limbs start shivering uncontrollably.") + H.custom_emote(VISIBLE_MESSAGE, "'s limbs start shivering uncontrollably.") finish(mob/living/carbon/human/H) if(!H.reagents.has_reagent("bicaridine")) @@ -54,7 +54,7 @@ duration = 10*90 start(mob/living/carbon/human/H) - H.emote("me", 1, "has drool running down from [H.gender == MALE ? "his" : H.gender == FEMALE ? "her" : "their"] mouth.") + H.custom_emote(VISIBLE_MESSAGE, "has drool running down from [H.gender == MALE ? "his" : H.gender == FEMALE ? "her" : "their"] mouth.") finish(mob/living/carbon/human/H) if(!H.reagents.has_reagent("anti_toxin")) @@ -69,7 +69,7 @@ start(mob/living/carbon/human/H) var/datum/gender/T = gender_datums[H.get_visible_gender()] - H.emote("me", 1, "has drool running down from [T.his] mouth.") + H.custom_emote(VISIBLE_MESSAGE, "has drool running down from [T.his] mouth.") finish(mob/living/carbon/human/H) if(!H.reagents.has_reagent("anti_toxin")) diff --git a/code/modules/library/lib_machines.dm b/code/modules/library/lib_machines.dm index e68425111f5..4454ea3a1a9 100644 --- a/code/modules/library/lib_machines.dm +++ b/code/modules/library/lib_machines.dm @@ -286,12 +286,17 @@ datum/borrowbook // Datum used to keep track of who has borrowed what when and f var/DBQuery/query = dbcon_old.NewQuery("SELECT id, author, title, category FROM library ORDER BY [sortby]") query.Execute() + var/show_admin_options = check_rights(R_ADMIN, show_msg = FALSE) + while(query.NextRow()) var/id = query.item[1] var/author = query.item[2] var/title = query.item[3] var/category = query.item[4] - dat += "" + dat += "" dat += "
[author][title][category]\[Order\]
[author][title][category]\[Order\]" + if(show_admin_options) // This isn't the only check, since you can just href-spoof press this button. Just to tidy things up. + dat += "\[Del\]" + dat += "
" dat += "
(Return to main menu)
" @@ -451,6 +456,18 @@ datum/borrowbook // Datum used to keep track of who has borrowed what when and f B.item_state = B.icon_state src.visible_message("[src]'s printer hums as it produces a completely bound book. How did it do that?") break + + if(href_list["delid"]) + if(!check_rights(R_ADMIN)) + return + var/sqlid = sanitizeSQL(href_list["delid"]) + establish_old_db_connection() + if(!dbcon_old.IsConnected()) + alert("Connection to Archive has been severed. Aborting.") + else + var/DBQuery/query = dbcon_old.NewQuery("DELETE FROM library WHERE id=[sqlid]") + query.Execute() + if(href_list["orderbyid"]) var/orderid = input("Enter your order:") as num|null if(orderid) diff --git a/code/game/objects/items/stacks/fifty_spawner.dm b/code/modules/materials/fifty_spawner.dm similarity index 100% rename from code/game/objects/items/stacks/fifty_spawner.dm rename to code/modules/materials/fifty_spawner.dm diff --git a/code/modules/materials/fifty_spawner_mats_vr.dm b/code/modules/materials/fifty_spawner_mats_vr.dm new file mode 100644 index 00000000000..0b6e29ffa0a --- /dev/null +++ b/code/modules/materials/fifty_spawner_mats_vr.dm @@ -0,0 +1,19 @@ +/obj/fiftyspawner/titanium + name = "stack of titanium" + type_to_spawn = /obj/item/stack/material/titanium + +/obj/fiftyspawner/titanium_glass + name = "stack of ti-glass" + type_to_spawn = /obj/item/stack/material/glass/titanium + +/obj/fiftyspawner/plastitanium + name = "stack of plastitanium" + type_to_spawn = /obj/item/stack/material/plastitanium + +/obj/fiftyspawner/plastitanium_hull + name = "stack of plastitanium" + type_to_spawn = /obj/item/stack/material/plastitanium/hull + +/obj/fiftyspawner/plastitanium_glass + name = "stack of plastitanium glass" + type_to_spawn = /obj/item/stack/material/glass/plastitanium diff --git a/code/modules/materials/material_recipes.dm b/code/modules/materials/material_recipes.dm deleted file mode 100644 index c1239b234c9..00000000000 --- a/code/modules/materials/material_recipes.dm +++ /dev/null @@ -1,278 +0,0 @@ -/datum/material/proc/get_recipes() - if(!recipes) - generate_recipes() - return recipes - -/datum/material/proc/generate_recipes() - recipes = list() - - // If is_brittle() returns true, these are only good for a single strike. - recipes += new/datum/stack_recipe("[display_name] baseball bat", /obj/item/weapon/material/twohanded/baseballbat, 10, time = 20, one_per_turf = 0, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE) - recipes += new/datum/stack_recipe("[display_name] ashtray", /obj/item/weapon/material/ashtray, 2, one_per_turf = 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE) - recipes += new/datum/stack_recipe("[display_name] spoon", /obj/item/weapon/material/kitchen/utensil/spoon/plastic, 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE) - recipes += new/datum/stack_recipe("[display_name] armor plate", /obj/item/weapon/material/armor_plating, 1, time = 20, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE) - recipes += new/datum/stack_recipe("[display_name] armor plate insert", /obj/item/weapon/material/armor_plating/insert, 2, time = 40, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE) - recipes += new/datum/stack_recipe("[display_name] grave marker", /obj/item/weapon/material/gravemarker, 5, time = 50, supplied_material = "[name]", pass_stack_color = TRUE) - recipes += new/datum/stack_recipe("[display_name] ring", /obj/item/clothing/gloves/ring/material, 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE) - recipes += new/datum/stack_recipe("[display_name] bracelet", /obj/item/clothing/accessory/bracelet/material, 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE) - - if(integrity>=50) - recipes += new/datum/stack_recipe("[display_name] door", /obj/structure/simple_door, 10, one_per_turf = 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE) - recipes += new/datum/stack_recipe("[display_name] barricade", /obj/structure/barricade, 5, time = 50, one_per_turf = 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE) - recipes += new/datum/stack_recipe("[display_name] stool", /obj/item/weapon/stool, one_per_turf = 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE) - recipes += new/datum/stack_recipe("[display_name] chair", /obj/structure/bed/chair, one_per_turf = 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE) - recipes += new/datum/stack_recipe("[display_name] bed", /obj/structure/bed, 2, one_per_turf = 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE) - recipes += new/datum/stack_recipe("[display_name] double bed", /obj/structure/bed/double, 4, one_per_turf = 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE) - recipes += new/datum/stack_recipe("[display_name] wall girders", /obj/structure/girder, 2, time = 50, one_per_turf = 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE) - - if(hardness>50) - recipes += new/datum/stack_recipe("[display_name] fork", /obj/item/weapon/material/kitchen/utensil/fork/plastic, 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE) - recipes += new/datum/stack_recipe("[display_name] knife", /obj/item/weapon/material/knife/plastic, 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE) - recipes += new/datum/stack_recipe("[display_name] blade", /obj/item/weapon/material/butterflyblade, 6, time = 20, one_per_turf = 0, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE) - recipes += new/datum/stack_recipe("[display_name] defense wire", /obj/item/weapon/material/barbedwire, 10, time = 1 MINUTE, one_per_turf = 0, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE) - -/datum/material/steel/generate_recipes() - ..() - recipes += new/datum/stack_recipe_list("office chairs",list( \ - new/datum/stack_recipe("dark office chair", /obj/structure/bed/chair/office/dark, 5, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), \ - new/datum/stack_recipe("light office chair", /obj/structure/bed/chair/office/light, 5, one_per_turf = 1, on_floor = 1, recycle_material = "[name]") \ - )) - recipes += new/datum/stack_recipe_list("comfy chairs", list( \ - new/datum/stack_recipe("beige comfy chair", /obj/structure/bed/chair/comfy/beige, 2, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), \ - new/datum/stack_recipe("black comfy chair", /obj/structure/bed/chair/comfy/black, 2, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), \ - new/datum/stack_recipe("brown comfy chair", /obj/structure/bed/chair/comfy/brown, 2, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), \ - new/datum/stack_recipe("lime comfy chair", /obj/structure/bed/chair/comfy/lime, 2, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), \ - new/datum/stack_recipe("teal comfy chair", /obj/structure/bed/chair/comfy/teal, 2, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), \ - new/datum/stack_recipe("red comfy chair", /obj/structure/bed/chair/comfy/red, 2, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), \ - new/datum/stack_recipe("blue comfy chair", /obj/structure/bed/chair/comfy/blue, 2, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), \ - new/datum/stack_recipe("purple comfy chair", /obj/structure/bed/chair/comfy/purp, 2, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), \ - new/datum/stack_recipe("green comfy chair", /obj/structure/bed/chair/comfy/green, 2, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), \ - new/datum/stack_recipe("yellow comfy chair", /obj/structure/bed/chair/comfy/yellow, 2, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), \ - new/datum/stack_recipe("orange comfy chair", /obj/structure/bed/chair/comfy/orange, 2, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), \ - )) - recipes += new/datum/stack_recipe("table frame", /obj/structure/table, 1, time = 10, one_per_turf = 1, on_floor = 1, recycle_material = "[name]") - recipes += new/datum/stack_recipe("bench frame", /obj/structure/table/bench, 1, time = 10, one_per_turf = 1, on_floor = 1, recycle_material = "[name]") - recipes += new/datum/stack_recipe("rack", /obj/structure/table/rack, 1, time = 5, one_per_turf = 1, on_floor = 1, recycle_material = "[name]") - recipes += new/datum/stack_recipe("closet", /obj/structure/closet, 2, time = 15, one_per_turf = 1, on_floor = 1, recycle_material = "[name]") - recipes += new/datum/stack_recipe("canister", /obj/machinery/portable_atmospherics/canister, 10, time = 15, one_per_turf = 1, on_floor = 1, recycle_material = "[name]") - recipes += new/datum/stack_recipe("cannon frame", /obj/item/weapon/cannonframe, 10, time = 15, one_per_turf = 0, on_floor = 0, recycle_material = "[name]") - recipes += new/datum/stack_recipe("regular floor tile", /obj/item/stack/tile/floor, 1, 4, 20, recycle_material = "[name]") - recipes += new/datum/stack_recipe("roofing tile", /obj/item/stack/tile/roofing, 3, 4, 20, recycle_material = "[name]") - recipes += new/datum/stack_recipe("metal rod", /obj/item/stack/rods, 1, 2, 60, recycle_material = "[name]") - recipes += new/datum/stack_recipe("frame", /obj/item/frame, 5, time = 25, one_per_turf = 1, on_floor = 1, recycle_material = "[name]") - recipes += new/datum/stack_recipe("mirror frame", /obj/item/frame/mirror, 1, time = 5, one_per_turf = 0, on_floor = 1, recycle_material = "[name]") - recipes += new/datum/stack_recipe("fire extinguisher cabinet frame", /obj/item/frame/extinguisher_cabinet, 4, time = 5, one_per_turf = 0, on_floor = 1, recycle_material = "[name]") - //recipes += new/datum/stack_recipe("fire axe cabinet frame", /obj/item/frame/fireaxe_cabinet, 4, time = 5, one_per_turf = 0, on_floor = 1) - recipes += new/datum/stack_recipe("railing", /obj/structure/railing, 2, time = 50, one_per_turf = 0, on_floor = 1, recycle_material = "[name]") - recipes += new/datum/stack_recipe("turret frame", /obj/machinery/porta_turret_construct, 5, time = 25, one_per_turf = 1, on_floor = 1, recycle_material = "[name]") - recipes += new/datum/stack_recipe_list("airlock assemblies", list( \ - new/datum/stack_recipe("standard airlock assembly", /obj/structure/door_assembly, 4, time = 50, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), \ - new/datum/stack_recipe("command airlock assembly", /obj/structure/door_assembly/door_assembly_com, 4, time = 50, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), \ - new/datum/stack_recipe("security airlock assembly", /obj/structure/door_assembly/door_assembly_sec, 4, time = 50, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), \ - new/datum/stack_recipe("eng atmos airlock assembly", /obj/structure/door_assembly/door_assembly_eat, 4, time = 50, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), \ - new/datum/stack_recipe("engineering airlock assembly", /obj/structure/door_assembly/door_assembly_eng, 4, time = 50, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), \ - new/datum/stack_recipe("mining airlock assembly", /obj/structure/door_assembly/door_assembly_min, 4, time = 50, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), \ - new/datum/stack_recipe("atmospherics airlock assembly", /obj/structure/door_assembly/door_assembly_atmo, 4, time = 50, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), \ - new/datum/stack_recipe("research airlock assembly", /obj/structure/door_assembly/door_assembly_research, 4, time = 50, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), \ - new/datum/stack_recipe("medical airlock assembly", /obj/structure/door_assembly/door_assembly_med, 4, time = 50, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), \ - new/datum/stack_recipe("maintenance airlock assembly", /obj/structure/door_assembly/door_assembly_mai, 4, time = 50, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), \ - new/datum/stack_recipe("external airlock assembly", /obj/structure/door_assembly/door_assembly_ext, 4, time = 50, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), \ - new/datum/stack_recipe("freezer airlock assembly", /obj/structure/door_assembly/door_assembly_fre, 4, time = 50, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), \ - new/datum/stack_recipe("airtight hatch assembly", /obj/structure/door_assembly/door_assembly_hatch, 4, time = 50, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), \ - new/datum/stack_recipe("maintenance hatch assembly", /obj/structure/door_assembly/door_assembly_mhatch, 4, time = 50, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), \ - new/datum/stack_recipe("high security airlock assembly", /obj/structure/door_assembly/door_assembly_highsecurity, 4, time = 50, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), \ - new/datum/stack_recipe("voidcraft airlock assembly horizontal", /obj/structure/door_assembly/door_assembly_voidcraft, 4, time = 50, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), \ - new/datum/stack_recipe("voidcraft airlock assembly vertical", /obj/structure/door_assembly/door_assembly_voidcraft/vertical, 4, time = 50, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), \ - new/datum/stack_recipe("emergency shutter", /obj/structure/firedoor_assembly, 4, time = 50, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), \ - new/datum/stack_recipe("multi-tile airlock assembly", /obj/structure/door_assembly/multi_tile, 4, time = 50, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), \ - )) - //recipes += new/datum/stack_recipe("IV drip", /obj/machinery/iv_drip, 4, time = 20, one_per_turf = 1, on_floor = 1, recycle_material = "[name]")//VOREStation Removal - recipes += new/datum/stack_recipe("medical stand", /obj/structure/medical_stand, 4, time = 20, one_per_turf = 1, on_floor = 1, recycle_material = "[name]")//VOREStation Replacement - recipes += new/datum/stack_recipe("conveyor switch", /obj/machinery/conveyor_switch, 2, time = 20, one_per_turf = 1, on_floor = 1, recycle_material = "[name]") - recipes += new/datum/stack_recipe("grenade casing", /obj/item/weapon/grenade/chem_grenade, recycle_material = "[name]") - recipes += new/datum/stack_recipe("light fixture frame", /obj/item/frame/light, 2, recycle_material = "[name]") - recipes += new/datum/stack_recipe("small light fixture frame", /obj/item/frame/light/small, 1, recycle_material = "[name]") - recipes += new/datum/stack_recipe("floor lamp fixture frame", /obj/machinery/light_construct/flamp, 2, recycle_material = "[name]") - recipes += new/datum/stack_recipe("apc frame", /obj/item/frame/apc, 2, recycle_material = "[name]") - recipes += new/datum/stack_recipe_list("modular computer frames", list( \ - new/datum/stack_recipe("modular console frame", /obj/item/modular_computer/console, 20, recycle_material = "[name]"),\ - new/datum/stack_recipe("modular telescreen frame", /obj/item/modular_computer/telescreen, 10, recycle_material = "[name]"),\ - new/datum/stack_recipe("modular laptop frame", /obj/item/modular_computer/laptop, 10, recycle_material = "[name]"),\ - new/datum/stack_recipe("modular tablet frame", /obj/item/modular_computer/tablet, 5, recycle_material = "[name]"),\ - )) - recipes += new/datum/stack_recipe_list("filing cabinets", list( \ - new/datum/stack_recipe("filing cabinet", /obj/structure/filingcabinet, 4, time = 20, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), \ - new/datum/stack_recipe("tall filing cabinet", /obj/structure/filingcabinet/filingcabinet, 4, time = 20, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), \ - new/datum/stack_recipe("chest drawer", /obj/structure/filingcabinet/chestdrawer, 4, time = 20, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), \ - )) - recipes += new/datum/stack_recipe("desk bell", /obj/item/weapon/deskbell, 1, on_floor = 1, supplied_material = "[name]") - recipes += new/datum/stack_recipe("tanning rack", /obj/structure/tanning_rack, 3, one_per_turf = TRUE, time = 20, on_floor = TRUE, supplied_material = "[name]") - -/datum/material/plasteel/generate_recipes() - ..() - recipes += new/datum/stack_recipe("AI core", /obj/structure/AIcore, 4, time = 50, one_per_turf = 1, recycle_material = "[name]") - recipes += new/datum/stack_recipe("Metal crate", /obj/structure/closet/crate, 10, time = 50, one_per_turf = 1, recycle_material = "[name]") - recipes += new/datum/stack_recipe("knife grip", /obj/item/weapon/material/butterflyhandle, 4, time = 20, one_per_turf = 0, on_floor = 1, supplied_material = "[name]") - recipes += new/datum/stack_recipe("dark floor tile", /obj/item/stack/tile/floor/dark, 1, 4, 20, recycle_material = "[name]") - recipes += new/datum/stack_recipe("roller bed", /obj/item/roller, 5, time = 30, on_floor = 1, recycle_material = "[name]") - recipes += new/datum/stack_recipe("whetstone", /obj/item/weapon/whetstone, 2, time = 10, recycle_material = "[name]") - -/datum/material/stone/generate_recipes() - ..() - recipes += new/datum/stack_recipe("planting bed", /obj/machinery/portable_atmospherics/hydroponics/soil, 3, time = 10, one_per_turf = 1, on_floor = 1, recycle_material = "[name]") - -/datum/material/stone/marble/generate_recipes() - ..() - recipes += new/datum/stack_recipe("light marble floor tile", /obj/item/stack/tile/wmarble, 1, 4, 20, recycle_material = "[name]") - recipes += new/datum/stack_recipe("dark marble floor tile", /obj/item/stack/tile/bmarble, 1, 4, 20, recycle_material = "[name]") - -/datum/material/plastic/generate_recipes() - ..() - recipes += new/datum/stack_recipe("plastic crate", /obj/structure/closet/crate/plastic, 10, one_per_turf = 1, on_floor = 1, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("plastic bag", /obj/item/weapon/storage/bag/plasticbag, 3, on_floor = 1, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("blood pack", /obj/item/weapon/reagent_containers/blood/empty, 4, on_floor = 0, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("reagent dispenser cartridge (large)", /obj/item/weapon/reagent_containers/chem_disp_cartridge, 5, on_floor=0, pass_stack_color = TRUE, recycle_material = "[name]") // 500u - recipes += new/datum/stack_recipe("reagent dispenser cartridge (med)", /obj/item/weapon/reagent_containers/chem_disp_cartridge/medium, 3, on_floor=0, pass_stack_color = TRUE, recycle_material = "[name]") // 250u - recipes += new/datum/stack_recipe("reagent dispenser cartridge (small)", /obj/item/weapon/reagent_containers/chem_disp_cartridge/small, 1, on_floor=0, pass_stack_color = TRUE, recycle_material = "[name]") // 100u - recipes += new/datum/stack_recipe("white floor tile", /obj/item/stack/tile/floor/white, 1, 4, 20, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("freezer floor tile", /obj/item/stack/tile/floor/freezer, 1, 4, 20, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("shower curtain", /obj/structure/curtain, 4, time = 15, one_per_turf = 1, on_floor = 1, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("plastic flaps", /obj/structure/plasticflaps, 4, time = 25, one_per_turf = 1, on_floor = 1, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("water-cooler", /obj/structure/reagent_dispensers/water_cooler, 4, time = 10, one_per_turf = 1, on_floor = 1, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("lampshade", /obj/item/weapon/lampshade, 1, time = 1, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("plastic net", /obj/item/weapon/material/fishing_net, 25, time = 1 MINUTE, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("plastic fishtank", /obj/item/glass_jar/fish/plastic, 2, time = 30 SECONDS, recycle_material = "[name]") - recipes += new/datum/stack_recipe("reagent tubing", /obj/item/stack/hose, 1, 4, 20, pass_stack_color = TRUE, recycle_material = "[name]") - -/datum/material/wood/generate_recipes() - ..() - recipes += new/datum/stack_recipe("oar", /obj/item/weapon/oar, 2, time = 30, supplied_material = "[name]", pass_stack_color = TRUE) - recipes += new/datum/stack_recipe("boat", /obj/vehicle/boat, 20, time = 10 SECONDS, supplied_material = "[name]", pass_stack_color = TRUE) - recipes += new/datum/stack_recipe("dragon boat", /obj/vehicle/boat/dragon, 50, time = 30 SECONDS, supplied_material = "[name]", pass_stack_color = TRUE) - recipes += new/datum/stack_recipe("wooden sandals", /obj/item/clothing/shoes/sandal, 1, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("wood circlet", /obj/item/clothing/head/woodcirclet, 1, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("clipboard", /obj/item/weapon/clipboard, 1, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("wood floor tile", /obj/item/stack/tile/wood, 1, 4, 20, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("wooden chair", /obj/structure/bed/chair/wood, 3, time = 10, one_per_turf = 1, on_floor = 1, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("crossbow frame", /obj/item/weapon/crossbowframe, 5, time = 25, one_per_turf = 0, on_floor = 0, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("coffin", /obj/structure/closet/coffin, 5, time = 15, one_per_turf = 1, on_floor = 1, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("beehive assembly", /obj/item/beehive_assembly, 4, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("beehive frame", /obj/item/honey_frame, 1, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("book shelf", /obj/structure/bookcase, 5, time = 15, one_per_turf = 1, on_floor = 1, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("noticeboard frame", /obj/item/frame/noticeboard, 4, time = 5, one_per_turf = 0, on_floor = 1, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("wooden bucket", /obj/item/weapon/reagent_containers/glass/bucket/wood, 2, time = 4, one_per_turf = 0, on_floor = 0, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("coilgun stock", /obj/item/weapon/coilgun_assembly, 5, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("crude fishing rod", /obj/item/weapon/material/fishing_rod/built, 8, time = 10 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("wooden standup figure", /obj/structure/barricade/cutout, 5, time = 10 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]") //VOREStation Add - recipes += new/datum/stack_recipe("noticeboard", /obj/structure/noticeboard, 1, recycle_material = "[name]") - recipes += new/datum/stack_recipe("tanning rack", /obj/structure/tanning_rack, 3, one_per_turf = TRUE, time = 20, on_floor = TRUE, supplied_material = "[name]") - -/datum/material/wood/log/generate_recipes() - recipes = list() - recipes += new/datum/stack_recipe("bonfire", /obj/structure/bonfire, 5, time = 50, supplied_material = "[name]", pass_stack_color = TRUE, recycle_material = "[name]") - -/datum/material/cardboard/generate_recipes() - ..() - recipes += new/datum/stack_recipe("box", /obj/item/weapon/storage/box, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("donut box", /obj/item/weapon/storage/box/donut/empty, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("egg box", /obj/item/weapon/storage/fancy/egg_box, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("light tubes box", /obj/item/weapon/storage/box/lights/tubes, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("light bulbs box", /obj/item/weapon/storage/box/lights/bulbs, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("mouse traps box", /obj/item/weapon/storage/box/mousetraps, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("cardborg suit", /obj/item/clothing/suit/cardborg, 3, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("cardborg helmet", /obj/item/clothing/head/cardborg, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("pizza box", /obj/item/pizzabox, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe_list("folders",list( \ - new/datum/stack_recipe("blue folder", /obj/item/weapon/folder/blue, recycle_material = "[name]"), \ - new/datum/stack_recipe("grey folder", /obj/item/weapon/folder, recycle_material = "[name]"), \ - new/datum/stack_recipe("red folder", /obj/item/weapon/folder/red, recycle_material = "[name]"), \ - new/datum/stack_recipe("white folder", /obj/item/weapon/folder/white, recycle_material = "[name]"), \ - new/datum/stack_recipe("yellow folder", /obj/item/weapon/folder/yellow, recycle_material = "[name]"), \ - )) - -/datum/material/snow/generate_recipes() - recipes = list() - recipes += new/datum/stack_recipe("snowball", /obj/item/weapon/material/snow/snowball, 1, time = 10, recycle_material = "[name]") - recipes += new/datum/stack_recipe("snow brick", /obj/item/stack/material/snowbrick, 2, time = 10, recycle_material = "[name]") - recipes += new/datum/stack_recipe("snowman", /obj/structure/snowman, 2, time = 15, recycle_material = "[name]") - recipes += new/datum/stack_recipe("snow robot", /obj/structure/snowman/borg, 2, time = 10, recycle_material = "[name]") - recipes += new/datum/stack_recipe("snow spider", /obj/structure/snowman/spider, 3, time = 20, recycle_material = "[name]") - -/datum/material/snowbrick/generate_recipes() - recipes = list() - recipes += new/datum/stack_recipe("[display_name] door", /obj/structure/simple_door, 10, one_per_turf = 1, on_floor = 1, supplied_material = "[name]") - recipes += new/datum/stack_recipe("[display_name] barricade", /obj/structure/barricade, 5, time = 50, one_per_turf = 1, on_floor = 1, supplied_material = "[name]") - recipes += new/datum/stack_recipe("[display_name] stool", /obj/item/weapon/stool, one_per_turf = 1, on_floor = 1, supplied_material = "[name]") - recipes += new/datum/stack_recipe("[display_name] chair", /obj/structure/bed/chair, one_per_turf = 1, on_floor = 1, supplied_material = "[name]") - recipes += new/datum/stack_recipe("[display_name] bed", /obj/structure/bed, 2, one_per_turf = 1, on_floor = 1, supplied_material = "[name]") - recipes += new/datum/stack_recipe("[display_name] double bed", /obj/structure/bed/double, 4, one_per_turf = 1, on_floor = 1, supplied_material = "[name]") - recipes += new/datum/stack_recipe("[display_name] wall girders", /obj/structure/girder, 2, time = 50, one_per_turf = 1, on_floor = 1, supplied_material = "[name]") - recipes += new/datum/stack_recipe("[display_name] ashtray", /obj/item/weapon/material/ashtray, 2, one_per_turf = 1, on_floor = 1, supplied_material = "[name]") - -/datum/material/wood/sif/generate_recipes() - ..() - recipes += new/datum/stack_recipe("alien wood floor tile", /obj/item/stack/tile/wood/sif, 1, 4, 20, pass_stack_color = TRUE) - for(var/datum/stack_recipe/r_recipe in recipes) - if(r_recipe.title == "wood floor tile") - recipes -= r_recipe - continue - if(r_recipe.title == "wooden chair") - recipes -= r_recipe - continue - -/datum/material/supermatter/generate_recipes() - recipes = list() - recipes += new/datum/stack_recipe("supermatter shard", /obj/machinery/power/supermatter/shard, 30 , one_per_turf = 1, time = 600, on_floor = 1, recycle_material = "[name]") - -/datum/material/cloth/generate_recipes() - recipes = list() - recipes += new/datum/stack_recipe("woven net", /obj/item/weapon/material/fishing_net, 10, time = 30 SECONDS, pass_stack_color = TRUE, supplied_material = "[name]") - recipes += new/datum/stack_recipe("bedsheet", /obj/item/weapon/bedsheet, 10, time = 30 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("uniform", /obj/item/clothing/under/color/white, 8, time = 15 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("foot wraps", /obj/item/clothing/shoes/footwraps, 2, time = 5 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("gloves", /obj/item/clothing/gloves/white, 2, time = 5 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("wig", /obj/item/clothing/head/powdered_wig, 4, time = 10 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("philosopher's wig", /obj/item/clothing/head/philosopher_wig, 50, time = 2 MINUTES, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("taqiyah", /obj/item/clothing/head/taqiyah, 3, time = 6 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("turban", /obj/item/clothing/head/turban, 3, time = 6 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("hijab", /obj/item/clothing/head/hijab, 3, time = 6 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("kippa", /obj/item/clothing/head/kippa, 3, time = 6 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("scarf", /obj/item/clothing/accessory/scarf/white, 4, time = 5 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("baggy pants", /obj/item/clothing/under/pants/baggy/white, 8, time = 10 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("belt pouch", /obj/item/weapon/storage/belt/fannypack/white, 25, time = 1 MINUTE, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("crude bandage", /obj/item/stack/medical/crude_pack, 1, time = 2 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("empty sandbag", /obj/item/stack/emptysandbag, 2, time = 2 SECONDS, pass_stack_color = TRUE, supplied_material = "[name]") - -/datum/material/resin/generate_recipes() - recipes = list() - recipes += new/datum/stack_recipe("[display_name] door", /obj/structure/simple_door/resin, 10, one_per_turf = 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE) - recipes += new/datum/stack_recipe("[display_name] barricade", /obj/effect/alien/resin/wall, 5, time = 5 SECONDS, one_per_turf = 1, on_floor = 1, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("[display_name] nest", /obj/structure/bed/nest, 2, one_per_turf = 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE) - recipes += new/datum/stack_recipe("[display_name] wall girders", /obj/structure/girder/resin, 2, time = 5 SECONDS, one_per_turf = 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE) - recipes += new/datum/stack_recipe("crude [display_name] bandage", /obj/item/stack/medical/crude_pack, 1, time = 2 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("[display_name] net", /obj/item/weapon/material/fishing_net, 10, time = 5 SECONDS, supplied_material = "[name]", pass_stack_color = TRUE) - recipes += new/datum/stack_recipe("[display_name] membrane", /obj/effect/alien/resin/membrane, 1, time = 2 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("[display_name] node", /obj/effect/alien/weeds/node, 1, time = 4 SECONDS, recycle_material = "[name]") - -/datum/material/leather/generate_recipes() - recipes = list() - recipes += new/datum/stack_recipe("bedsheet", /obj/item/weapon/bedsheet, 10, time = 30 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("uniform", /obj/item/clothing/under/color/white, 8, time = 15 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("foot wraps", /obj/item/clothing/shoes/footwraps, 2, time = 5 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("gloves", /obj/item/clothing/gloves/white, 2, time = 5 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("wig", /obj/item/clothing/head/powdered_wig, 4, time = 10 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("philosopher's wig", /obj/item/clothing/head/philosopher_wig, 50, time = 2 MINUTES, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("taqiyah", /obj/item/clothing/head/taqiyah, 3, time = 6 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("turban", /obj/item/clothing/head/turban, 3, time = 6 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("hijab", /obj/item/clothing/head/hijab, 3, time = 6 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("kippa", /obj/item/clothing/head/kippa, 3, time = 6 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("scarf", /obj/item/clothing/accessory/scarf/white, 4, time = 5 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("baggy pants", /obj/item/clothing/under/pants/baggy/white, 8, time = 10 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("belt pouch", /obj/item/weapon/storage/belt/fannypack/white, 25, time = 1 MINUTE, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("crude [display_name] bandage", /obj/item/stack/medical/crude_pack, 1, time = 2 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]") - recipes += new/datum/stack_recipe("[display_name] net", /obj/item/weapon/material/fishing_net, 10, time = 5 SECONDS, supplied_material = "[name]", pass_stack_color = TRUE) - recipes += new/datum/stack_recipe("[display_name] ring", /obj/item/clothing/gloves/ring/material, 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE) - recipes += new/datum/stack_recipe("[display_name] bracelet", /obj/item/clothing/accessory/bracelet/material, 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE) - recipes += new/datum/stack_recipe("[display_name] armor plate", /obj/item/weapon/material/armor_plating, 1, time = 20, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE) - recipes += new/datum/stack_recipe("empty sandbag", /obj/item/stack/emptysandbag, 2, time = 2 SECONDS, pass_stack_color = TRUE, supplied_material = "[name]") - recipes += new/datum/stack_recipe("whip", /obj/item/weapon/material/whip, 5, time = 15 SECONDS, pass_stack_color = TRUE, supplied_material = "[name]") diff --git a/code/modules/materials/material_recipes_vr.dm b/code/modules/materials/material_recipes_vr.dm deleted file mode 100644 index bf5b54d8535..00000000000 --- a/code/modules/materials/material_recipes_vr.dm +++ /dev/null @@ -1,90 +0,0 @@ - -/datum/material/steel/generate_recipes() - . = ..() - recipes += new/datum/stack_recipe_list("mounted chairs", list( - new/datum/stack_recipe("mounted chair", /obj/structure/bed/chair/bay/chair, 2, one_per_turf = 1, on_floor = 1, time = 10), - new/datum/stack_recipe("red mounted chair", /obj/structure/bed/chair/bay/chair/padded/red, 2, one_per_turf = 1, on_floor = 1, time = 10), - new/datum/stack_recipe("brown mounted chair", /obj/structure/bed/chair/bay/chair/padded/brown, 2, one_per_turf = 1, on_floor = 1, time = 10), - new/datum/stack_recipe("teal mounted chair", /obj/structure/bed/chair/bay/chair/padded/teal, 2, one_per_turf = 1, on_floor = 1, time = 10), - new/datum/stack_recipe("black mounted chair", /obj/structure/bed/chair/bay/chair/padded/black, 2, one_per_turf = 1, on_floor = 1, time = 10), - new/datum/stack_recipe("green mounted chair", /obj/structure/bed/chair/bay/chair/padded/green, 2, one_per_turf = 1, on_floor = 1, time = 10), - new/datum/stack_recipe("purple mounted chair", /obj/structure/bed/chair/bay/chair/padded/purple, 2, one_per_turf = 1, on_floor = 1, time = 10), - new/datum/stack_recipe("blue mounted chair", /obj/structure/bed/chair/bay/chair/padded/blue, 2, one_per_turf = 1, on_floor = 1, time = 10), - new/datum/stack_recipe("beige mounted chair", /obj/structure/bed/chair/bay/chair/padded/beige, 2, one_per_turf = 1, on_floor = 1, time = 10), - new/datum/stack_recipe("lime mounted chair", /obj/structure/bed/chair/bay/chair/padded/lime, 2, one_per_turf = 1, on_floor = 1, time = 10), - new/datum/stack_recipe("yellow mounted chair", /obj/structure/bed/chair/bay/chair/padded/yellow, 2, one_per_turf = 1, on_floor = 1, time = 10) - )) - recipes += new/datum/stack_recipe_list("mounted comfy chairs", list( - new/datum/stack_recipe("mounted comfy chair", /obj/structure/bed/chair/bay/comfy, 3, one_per_turf = 1, on_floor = 1, time = 20), - new/datum/stack_recipe("red mounted comfy chair", /obj/structure/bed/chair/bay/comfy/red, 3, one_per_turf = 1, on_floor = 1, time = 20), - new/datum/stack_recipe("brown mounted comfy chair", /obj/structure/bed/chair/bay/comfy/brown, 3, one_per_turf = 1, on_floor = 1, time = 20), - new/datum/stack_recipe("teal mounted comfy chair", /obj/structure/bed/chair/bay/comfy/teal, 3, one_per_turf = 1, on_floor = 1, time = 20), - new/datum/stack_recipe("black mounted comfy chair", /obj/structure/bed/chair/bay/comfy/black, 3, one_per_turf = 1, on_floor = 1, time = 20), - new/datum/stack_recipe("green mounted comfy chair", /obj/structure/bed/chair/bay/comfy/green, 3, one_per_turf = 1, on_floor = 1, time = 20), - new/datum/stack_recipe("purple mounted comfy chair", /obj/structure/bed/chair/bay/comfy/purple, 3, one_per_turf = 1, on_floor = 1, time = 20), - new/datum/stack_recipe("blue mounted comfy chair", /obj/structure/bed/chair/bay/comfy/blue, 3, one_per_turf = 1, on_floor = 1, time = 20), - new/datum/stack_recipe("beige mounted comfy chair", /obj/structure/bed/chair/bay/comfy/beige, 3, one_per_turf = 1, on_floor = 1, time = 20), - new/datum/stack_recipe("lime mounted comfy chair", /obj/structure/bed/chair/bay/comfy/lime, 3, one_per_turf = 1, on_floor = 1, time = 20), - new/datum/stack_recipe("yellow mounted comfy chair", /obj/structure/bed/chair/bay/comfy/yellow, 3, one_per_turf = 1, on_floor = 1, time = 20) - )) - recipes += new/datum/stack_recipe("mounted captain's chair", /obj/structure/bed/chair/bay/comfy/captain, 4, one_per_turf = 1, on_floor = 1, time = 20) - recipes += new/datum/stack_recipe("dropship seat", /obj/structure/bed/chair/bay/shuttle, 4, one_per_turf = 1, on_floor = 1, time = 20) - recipes += new/datum/stack_recipe("small teshari nest", /obj/structure/bed/chair/bay/chair/padded/red/smallnest, 2, one_per_turf = 1, on_floor = 1, time = 10) - recipes += new/datum/stack_recipe("large teshari nest", /obj/structure/bed/chair/bay/chair/padded/red/bignest, 4, one_per_turf = 1, on_floor = 1, time = 20) - recipes += new/datum/stack_recipe("dance pole", /obj/structure/dancepole, 2, one_per_turf = 1, on_floor = 1, time = 20) - recipes += new/datum/stack_recipe("light switch frame", /obj/item/frame/lightswitch, 2) - recipes += new/datum/stack_recipe_list("sofas", list( - new/datum/stack_recipe("red sofa middle", /obj/structure/bed/chair/sofa, 1, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("red sofa left", /obj/structure/bed/chair/sofa/left, 1, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("red sofa right", /obj/structure/bed/chair/sofa/right, 1, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("red sofa corner", /obj/structure/bed/chair/sofa/corner, 1, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("brown sofa middle", /obj/structure/bed/chair/sofa/brown, 1, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("brown sofa left", /obj/structure/bed/chair/sofa/brown/left, 1, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("brown sofa right", /obj/structure/bed/chair/sofa/brown/right, 1, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("brown sofa corner", /obj/structure/bed/chair/sofa/brown/corner, 1, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("teal sofa middle", /obj/structure/bed/chair/sofa/teal, 1, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("teal sofa left", /obj/structure/bed/chair/sofa/teal/left, 1, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("teal sofa right", /obj/structure/bed/chair/sofa/teal/right, 1, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("teal sofa corner", /obj/structure/bed/chair/sofa/teal/corner, 1, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("black sofa middle", /obj/structure/bed/chair/sofa/black, 1, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("black sofa left", /obj/structure/bed/chair/sofa/black/left, 1, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("black sofa right", /obj/structure/bed/chair/sofa/black/right, 1, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("black sofa corner", /obj/structure/bed/chair/sofa/black/corner, 1, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("green sofa middle", /obj/structure/bed/chair/sofa/green, 1, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("green sofa left", /obj/structure/bed/chair/sofa/green/left, 1, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("green sofa right", /obj/structure/bed/chair/sofa/green/right, 1, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("green sofa corner", /obj/structure/bed/chair/sofa/green/corner, 1, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("purple sofa middle", /obj/structure/bed/chair/sofa/purp, 1, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("purple sofa left", /obj/structure/bed/chair/sofa/purp/left, 1, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("purple sofa right", /obj/structure/bed/chair/sofa/purp/right, 1, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("purple sofa corner", /obj/structure/bed/chair/sofa/purp/corner, 1, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("blue sofa middle", /obj/structure/bed/chair/sofa/blue, 1, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("blue sofa left", /obj/structure/bed/chair/sofa/blue/left, 1, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("blue sofa right", /obj/structure/bed/chair/sofa/blue/right, 1, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("blue sofa corner", /obj/structure/bed/chair/sofa/blue/corner, 1, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("beige sofa middle", /obj/structure/bed/chair/sofa/beige, 1, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("beige sofa left", /obj/structure/bed/chair/sofa/beige/left, 1, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("beige sofa right", /obj/structure/bed/chair/sofa/beige/right, 1, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("beige sofa corner", /obj/structure/bed/chair/sofa/beige/corner, 1, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("lime sofa middle", /obj/structure/bed/chair/sofa/lime, 1, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("lime sofa left", /obj/structure/bed/chair/sofa/lime/left, 1, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("lime sofa right", /obj/structure/bed/chair/sofa/lime/right, 1, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("lime sofa corner", /obj/structure/bed/chair/sofa/lime/corner, 1, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("yellow sofa middle", /obj/structure/bed/chair/sofa/yellow, 1, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("yellow sofa left", /obj/structure/bed/chair/sofa/yellow/left, 1, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("yellow sofa right", /obj/structure/bed/chair/sofa/yellow/right, 1, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("yellow sofa corner", /obj/structure/bed/chair/sofa/yellow/corner, 1, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("orange sofa middle", /obj/structure/bed/chair/sofa/orange, 1, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("orange sofa left", /obj/structure/bed/chair/sofa/orange/left, 1, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("orange sofa right", /obj/structure/bed/chair/sofa/orange/right, 1, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("orange sofa corner", /obj/structure/bed/chair/sofa/orange/corner, 1, one_per_turf = 1, on_floor = 1), \ - )) - -/datum/material/durasteel/generate_recipes() - . = ..() - recipes += new/datum/stack_recipe("durasteel fishing rod", /obj/item/weapon/material/fishing_rod/modern/strong, 2) - recipes += new/datum/stack_recipe("whetstone", /obj/item/weapon/whetstone, 2, time = 30) - -/datum/material/plastitanium/generate_recipes() - . = ..() - recipes += new/datum/stack_recipe("whetstone", /obj/item/weapon/whetstone, 2, time = 20) diff --git a/code/modules/materials/material_sheets.dm b/code/modules/materials/material_sheets.dm deleted file mode 100644 index 3fd995378c5..00000000000 --- a/code/modules/materials/material_sheets.dm +++ /dev/null @@ -1,565 +0,0 @@ -// Stacked resources. They use a material datum for a lot of inherited values. -// If you're adding something here, make sure to add it to fifty_spawner_mats.dm as well -/obj/item/stack/material - force = 5.0 - throwforce = 5 - w_class = ITEMSIZE_NORMAL - throw_speed = 3 - throw_range = 3 - center_of_mass = null - max_amount = 50 - item_icons = list( - slot_l_hand_str = 'icons/mob/items/lefthand_material.dmi', - slot_r_hand_str = 'icons/mob/items/righthand_material.dmi', - ) - - var/default_type = DEFAULT_WALL_MATERIAL - var/datum/material/material - var/perunit = SHEET_MATERIAL_AMOUNT - var/apply_colour //temp pending icon rewrite - drop_sound = 'sound/items/drop/axe.ogg' - pickup_sound = 'sound/items/pickup/axe.ogg' - -/obj/item/stack/material/Initialize() - . = ..() - - randpixel_xy() - - if(!default_type) - default_type = DEFAULT_WALL_MATERIAL - material = get_material_by_name("[default_type]") - if(!material) - return INITIALIZE_HINT_QDEL - - recipes = material.get_recipes() - stacktype = material.stack_type - if(islist(material.stack_origin_tech)) - origin_tech = material.stack_origin_tech.Copy() - - if(apply_colour) - color = material.icon_colour - - if(!material.conductive) - flags |= NOCONDUCT - - matter = material.get_matter() - update_strings() - -/obj/item/stack/material/get_material() - return material - -/obj/item/stack/material/proc/update_strings() - // Update from material datum. - singular_name = material.sheet_singular_name - - if(amount>1) - name = "[material.use_name] [material.sheet_plural_name]" - desc = "A stack of [material.use_name] [material.sheet_plural_name]." - gender = PLURAL - else - name = "[material.use_name] [material.sheet_singular_name]" - desc = "A [material.sheet_singular_name] of [material.use_name]." - gender = NEUTER - -/obj/item/stack/material/use(var/used) - . = ..() - update_strings() - return - -/obj/item/stack/material/transfer_to(obj/item/stack/S, var/tamount=null, var/type_verified) - var/obj/item/stack/material/M = S - if(!istype(M) || material.name != M.material.name) - return 0 - var/transfer = ..(S,tamount,1) - if(src) update_strings() - if(M) M.update_strings() - return transfer - -/obj/item/stack/material/attack_self(var/mob/user) - if(!material.build_windows(user, src)) - ..() - -/obj/item/stack/material/attackby(var/obj/item/W, var/mob/user) - if(istype(W,/obj/item/stack/cable_coil)) - material.build_wired_product(user, W, src) - return - else if(istype(W, /obj/item/stack/rods)) - material.build_rod_product(user, W, src) - return - return ..() - -//VOREStation Add -/obj/item/stack/material/attack(mob/living/M as mob, mob/living/user as mob) - if(M.handle_eat_minerals(src, user)) - return - ..() - -/obj/item/stack/material/attack_generic(var/mob/living/user) //Allow adminbussed mobs to eat ore if they click it while NOT on help intent. - if(user.handle_eat_minerals(src)) - return - ..() -//VOREStation Add End - -/obj/item/stack/material/iron - name = "iron" - icon_state = "sheet-ingot" - default_type = "iron" - apply_colour = 1 - no_variants = FALSE - -/obj/item/stack/material/lead - name = "lead" - icon_state = "sheet-ingot" - default_type = "lead" - apply_colour = 1 - no_variants = FALSE - -/obj/item/stack/material/sandstone - name = "sandstone brick" - icon_state = "sheet-sandstone" - default_type = "sandstone" - no_variants = FALSE - drop_sound = 'sound/items/drop/boots.ogg' - pickup_sound = 'sound/items/pickup/boots.ogg' - -/obj/item/stack/material/marble - name = "marble brick" - icon_state = "sheet-marble" - default_type = "marble" - no_variants = FALSE - drop_sound = 'sound/items/drop/boots.ogg' - pickup_sound = 'sound/items/pickup/boots.ogg' - -/obj/item/stack/material/diamond - name = "diamond" - icon_state = "sheet-diamond" - default_type = "diamond" - drop_sound = 'sound/items/drop/glass.ogg' - pickup_sound = 'sound/items/pickup/glass.ogg' - -/obj/item/stack/material/uranium - name = "uranium" - icon_state = "sheet-uranium" - default_type = "uranium" - no_variants = FALSE - -/obj/item/stack/material/phoron - name = "solid phoron" - icon_state = "sheet-phoron" - default_type = "phoron" - no_variants = FALSE - drop_sound = 'sound/items/drop/glass.ogg' - pickup_sound = 'sound/items/pickup/glass.ogg' - -/obj/item/stack/material/plastic - name = "plastic" - icon_state = "sheet-plastic" - default_type = "plastic" - no_variants = FALSE - -/obj/item/stack/material/graphite - name = "graphite" - icon_state = "sheet-puck" - default_type = MAT_GRAPHITE - apply_colour = 1 - no_variants = FALSE - -/obj/item/stack/material/gold - name = "gold" - icon_state = "sheet-ingot" - default_type = "gold" - no_variants = FALSE - apply_colour = TRUE - -/obj/item/stack/material/silver - name = "silver" - icon_state = "sheet-ingot" - default_type = "silver" - no_variants = FALSE - apply_colour = TRUE - -//Valuable resource, cargo can sell it. -/obj/item/stack/material/platinum - name = "platinum" - icon_state = "sheet-adamantine" - default_type = "platinum" - no_variants = FALSE - apply_colour = TRUE - -//Extremely valuable to Research. -/obj/item/stack/material/mhydrogen - name = "metallic hydrogen" - icon_state = "sheet-mythril" - default_type = "mhydrogen" - no_variants = FALSE - -//Fuel for MRSPACMAN generator. -/obj/item/stack/material/tritium - name = "tritium" - icon_state = "sheet-puck" - default_type = "tritium" - apply_colour = TRUE - no_variants = FALSE - -/obj/item/stack/material/osmium - name = "osmium" - icon_state = "sheet-ingot" - default_type = "osmium" - apply_colour = 1 - no_variants = FALSE - -//R-UST port -// Fusion fuel. -/obj/item/stack/material/deuterium - name = "deuterium" - icon_state = "sheet-puck" - default_type = "deuterium" - apply_colour = 1 - no_variants = FALSE - -/obj/item/stack/material/steel - name = DEFAULT_WALL_MATERIAL - icon_state = "sheet-refined" - default_type = DEFAULT_WALL_MATERIAL - no_variants = FALSE - apply_colour = TRUE - -/obj/item/stack/material/steel/hull - name = MAT_STEELHULL - default_type = MAT_STEELHULL - -/obj/item/stack/material/plasteel - name = "plasteel" - icon_state = "sheet-reinforced" - default_type = "plasteel" - no_variants = FALSE - apply_colour = TRUE - -/obj/item/stack/material/plasteel/hull - name = MAT_PLASTEELHULL - default_type = MAT_PLASTEELHULL - -/obj/item/stack/material/durasteel - name = "durasteel" - icon_state = "sheet-reinforced" - item_state = "sheet-metal" - default_type = "durasteel" - no_variants = FALSE - apply_colour = TRUE - -/obj/item/stack/material/durasteel/hull - name = MAT_DURASTEELHULL - -/obj/item/stack/material/titanium - name = MAT_TITANIUM - icon_state = "sheet-refined" - apply_colour = TRUE - item_state = "sheet-silver" - default_type = MAT_TITANIUM - no_variants = FALSE - -/obj/item/stack/material/titanium/hull - name = MAT_TITANIUMHULL - default_type = MAT_TITANIUMHULL - -// Particle Smasher and Exotic material. -/obj/item/stack/material/verdantium - name = MAT_VERDANTIUM - icon_state = "sheet-wavy" - item_state = "mhydrogen" - default_type = MAT_VERDANTIUM - no_variants = FALSE - apply_colour = TRUE - -/obj/item/stack/material/morphium - name = MAT_MORPHIUM - icon_state = "sheet-wavy" - item_state = "mhydrogen" - default_type = MAT_MORPHIUM - no_variants = FALSE - apply_colour = TRUE - -/obj/item/stack/material/morphium/hull - name = MAT_MORPHIUMHULL - default_type = MAT_MORPHIUMHULL - -/obj/item/stack/material/valhollide - name = MAT_VALHOLLIDE - icon_state = "sheet-gem" - item_state = "diamond" - default_type = MAT_VALHOLLIDE - no_variants = FALSE - apply_colour = TRUE - -// Forged in the equivalent of Hell, one piece at a time. -/obj/item/stack/material/supermatter - name = MAT_SUPERMATTER - icon_state = "sheet-super" - item_state = "diamond" - default_type = MAT_SUPERMATTER - apply_colour = TRUE - -/obj/item/stack/material/supermatter/proc/update_mass() // Due to how dangerous they can be, the item will get heavier and larger the more are in the stack. - slowdown = amount / 10 - w_class = min(5, round(amount / 10) + 1) - throw_range = round(amount / 7) + 1 - -/obj/item/stack/material/supermatter/use(var/used) - . = ..() - update_mass() - return - -/obj/item/stack/material/supermatter/attack_hand(mob/user) - . = ..() - - update_mass() - SSradiation.radiate(src, 5 + amount) - var/mob/living/M = user - if(!istype(M)) - return - - var/burn_user = TRUE - if(istype(M, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = user - var/obj/item/clothing/gloves/G = H.gloves - if(istype(G) && ((G.flags & THICKMATERIAL && prob(70)) || istype(G, /obj/item/clothing/gloves/gauntlets))) - burn_user = FALSE - - if(burn_user) - H.visible_message("\The [src] flashes as it scorches [H]'s hands!") - H.apply_damage(amount / 2 + 5, BURN, "r_hand", used_weapon="Supermatter Chunk") - H.apply_damage(amount / 2 + 5, BURN, "l_hand", used_weapon="Supermatter Chunk") - H.drop_from_inventory(src, get_turf(H)) - return - - if(istype(user, /mob/living/silicon/robot)) - burn_user = FALSE - - if(burn_user) - M.apply_damage(amount, BURN, null, used_weapon="Supermatter Chunk") - -/obj/item/stack/material/supermatter/ex_act(severity) // An incredibly hard to manufacture material, SM chunks are unstable by their 'stabilized' nature. - if(prob((4 / severity) * 20)) - SSradiation.radiate(get_turf(src), amount * 4) - explosion(get_turf(src),round(amount / 12) , round(amount / 6), round(amount / 3), round(amount / 25)) - qdel(src) - return - SSradiation.radiate(get_turf(src), amount * 2) - ..() - -/obj/item/stack/material/wood - name = "wooden plank" - icon_state = "sheet-wood" - default_type = MAT_WOOD - strict_color_stacking = TRUE - apply_colour = 1 - drop_sound = 'sound/items/drop/wooden.ogg' - pickup_sound = 'sound/items/pickup/wooden.ogg' - no_variants = FALSE - -/obj/item/stack/material/wood/sif - name = "alien wooden plank" - color = "#0099cc" - default_type = MAT_SIFWOOD - -/obj/item/stack/material/log - name = "log" - icon_state = "sheet-log" - default_type = MAT_LOG - no_variants = FALSE - color = "#824B28" - max_amount = 25 - w_class = ITEMSIZE_HUGE - description_info = "Use inhand to craft things, or use a sharp and edged object on this to convert it into two wooden planks." - var/plank_type = /obj/item/stack/material/wood - drop_sound = 'sound/items/drop/wooden.ogg' - pickup_sound = 'sound/items/pickup/wooden.ogg' - -/obj/item/stack/material/log/sif - name = "alien log" - default_type = MAT_SIFLOG - color = "#0099cc" - plank_type = /obj/item/stack/material/wood/sif - -/obj/item/stack/material/log/attackby(var/obj/item/W, var/mob/user) - if(!istype(W) || W.force <= 0) - return ..() - if(W.sharp && W.edge) - var/time = (3 SECONDS / max(W.force / 10, 1)) * W.toolspeed - user.setClickCooldown(time) - if(do_after(user, time, src) && use(1)) - to_chat(user, "You cut up a log into planks.") - playsound(src, 'sound/effects/woodcutting.ogg', 50, 1) - var/obj/item/stack/material/wood/existing_wood = null - for(var/obj/item/stack/material/wood/M in user.loc) - if(M.material.name == src.material.name) - existing_wood = M - break - - var/obj/item/stack/material/wood/new_wood = new plank_type(user.loc) - new_wood.amount = 2 - if(existing_wood && new_wood.transfer_to(existing_wood)) - to_chat(user, "You add the newly-formed wood to the stack. It now contains [existing_wood.amount] planks.") - else - return ..() - - -/obj/item/stack/material/cloth - name = "cloth" - icon_state = "sheet-cloth" - default_type = "cloth" - no_variants = FALSE - pass_color = TRUE - strict_color_stacking = TRUE - drop_sound = 'sound/items/drop/clothing.ogg' - pickup_sound = 'sound/items/pickup/clothing.ogg' - -/obj/item/stack/material/cloth/diyaab - color = "#c6ccf0" - -/obj/item/stack/material/resin - name = "resin" - icon_state = "sheet-resin" - default_type = "resin" - no_variants = TRUE - apply_colour = TRUE - pass_color = TRUE - strict_color_stacking = TRUE - -/obj/item/stack/material/cardboard - name = "cardboard" - icon_state = "sheet-card" - default_type = "cardboard" - no_variants = FALSE - pass_color = TRUE - strict_color_stacking = TRUE - drop_sound = 'sound/items/drop/cardboardbox.ogg' - pickup_sound = 'sound/items/pickup/cardboardbox.ogg' - -/obj/item/stack/material/snow - name = "snow" - desc = "The temptation to build a snowman rises." - icon_state = "sheet-snow" - drop_sound = 'sound/items/drop/gloves.ogg' - pickup_sound = 'sound/items/pickup/clothing.ogg' - default_type = "snow" - -/obj/item/stack/material/snowbrick - name = "snow brick" - desc = "For all of your igloo building needs." - icon_state = "sheet-snowbrick" - default_type = "packed snow" - drop_sound = 'sound/items/drop/gloves.ogg' - pickup_sound = 'sound/items/pickup/clothing.ogg' - -/obj/item/stack/material/leather - name = "leather" - desc = "The by-product of mob grinding." - icon_state = "sheet-leather" - default_type = MAT_LEATHER - no_variants = FALSE - pass_color = TRUE - strict_color_stacking = TRUE - drop_sound = 'sound/items/drop/leather.ogg' - pickup_sound = 'sound/items/pickup/leather.ogg' - -/obj/item/stack/material/chitin - name = "chitin" - desc = "The by-product of mob grinding." - icon_state = "chitin" - default_type = MAT_CHITIN - no_variants = FALSE - pass_color = TRUE - strict_color_stacking = TRUE - drop_sound = 'sound/items/drop/leather.ogg' - pickup_sound = 'sound/items/pickup/leather.ogg' - -/obj/item/stack/material/glass - name = "glass" - icon_state = "sheet-transparent" - default_type = "glass" - no_variants = FALSE - drop_sound = 'sound/items/drop/glass.ogg' - pickup_sound = 'sound/items/pickup/glass.ogg' - apply_colour = TRUE - -/obj/item/stack/material/glass/reinforced - name = "reinforced glass" - icon_state = "sheet-rtransparent" - default_type = "rglass" - no_variants = FALSE - apply_colour = TRUE - -/obj/item/stack/material/glass/phoronglass - name = "borosilicate glass" - desc = "This sheet is special platinum-glass alloy designed to withstand large temperatures" - singular_name = "borosilicate glass sheet" - icon_state = "sheet-transparent" - default_type = "borosilicate glass" - no_variants = FALSE - apply_colour = TRUE - -/obj/item/stack/material/glass/phoronrglass - name = "reinforced borosilicate glass" - desc = "This sheet is special platinum-glass alloy designed to withstand large temperatures. It is reinforced with few rods." - singular_name = "reinforced borosilicate glass sheet" - icon_state = "sheet-rtransparent" - default_type = "reinforced borosilicate glass" - no_variants = FALSE - apply_colour = TRUE - -/obj/item/stack/material/bronze - name = "bronze" - icon_state = "sheet-ingot" - singular_name = "bronze ingot" - default_type = "bronze" - apply_colour = 1 - no_variants = FALSE - -/obj/item/stack/material/tin - name = "tin" - icon_state = "sheet-ingot" - singular_name = "tin ingot" - default_type = "tin" - apply_colour = 1 - no_variants = FALSE - -/obj/item/stack/material/copper - name = "copper" - icon_state = "sheet-ingot" - singular_name = "copper ingot" - default_type = "copper" - apply_colour = 1 - no_variants = FALSE - -/obj/item/stack/material/painite - name = "painite" - icon_state = "sheet-gem" - singular_name = "painite gem" - default_type = "painite" - apply_colour = 1 - no_variants = FALSE - -/obj/item/stack/material/void_opal - name = "void opal" - icon_state = "sheet-void_opal" - singular_name = "void opal" - default_type = "void opal" - apply_colour = 1 - no_variants = FALSE - -/obj/item/stack/material/quartz - name = "quartz" - icon_state = "sheet-gem" - singular_name = "quartz gem" - default_type = "quartz" - apply_colour = 1 - no_variants = FALSE - -/obj/item/stack/material/aluminium - name = "aluminium" - icon_state = "sheet-ingot" - singular_name = "aluminium ingot" - default_type = "aluminium" - apply_colour = 1 - no_variants = FALSE diff --git a/code/modules/materials/material_sheets_vr.dm b/code/modules/materials/material_sheets_vr.dm deleted file mode 100644 index 71d7e7d3ea8..00000000000 --- a/code/modules/materials/material_sheets_vr.dm +++ /dev/null @@ -1,66 +0,0 @@ -/obj/item/stack/material/titanium - icon = 'icons/obj/stacks_vr.dmi' - icon_state = "sheet-titanium" - no_variants = FALSE - -/obj/fiftyspawner/titanium - name = "stack of titanium" - type_to_spawn = /obj/item/stack/material/titanium - -/obj/item/stack/material/glass/titanium - name = "ti-glass sheets" - icon = 'icons/obj/stacks_vr.dmi' - icon_state = "sheet-titaniumglass" - item_state = "sheet-silver" - no_variants = FALSE - drop_sound = 'sound/items/drop/glass.ogg' - default_type = MAT_TITANIUMGLASS - -/obj/fiftyspawner/titanium_glass - name = "stack of ti-glass" - type_to_spawn = /obj/item/stack/material/glass/titanium - -/obj/item/stack/material/plastitanium - name = "plastitanium sheets" - icon = 'icons/obj/stacks_vr.dmi' - icon_state = "sheet-plastitanium" - item_state = "sheet-silver" - no_variants = FALSE - default_type = MAT_PLASTITANIUM - -/obj/fiftyspawner/plastitanium - name = "stack of plastitanium" - type_to_spawn = /obj/item/stack/material/plastitanium - -/obj/item/stack/material/plastitanium/hull - name = "plastitanium hull sheets" - icon = 'icons/obj/stacks_vr.dmi' - icon_state = "sheet-plastitanium" - item_state = "sheet-silver" - no_variants = FALSE - default_type = MAT_PLASTITANIUMHULL - -/obj/fiftyspawner/plastitanium_hull - name = "stack of plastitanium" - type_to_spawn = /obj/item/stack/material/plastitanium/hull - -/obj/item/stack/material/glass/plastitanium - name = "plastitanium glass sheets" - icon = 'icons/obj/stacks_vr.dmi' - icon_state = "sheet-plastitaniumglass" - item_state = "sheet-silver" - no_variants = FALSE - drop_sound = 'sound/items/drop/glass.ogg' - default_type = MAT_PLASTITANIUMGLASS - -/obj/fiftyspawner/plastitanium_glass - name = "stack of plastitanium glass" - type_to_spawn = /obj/item/stack/material/glass/plastitanium - -/obj/item/stack/material/gold/hull - name = "gold hull sheets" - icon = 'icons/obj/stacks_vr.dmi' - icon_state = "sheet-plastitanium" - item_state = "sheet-silver" - no_variants = FALSE - default_type = MAT_GOLDHULL \ No newline at end of file diff --git a/code/modules/materials/materials.dm b/code/modules/materials/materials.dm deleted file mode 100644 index b591ee26c54..00000000000 --- a/code/modules/materials/materials.dm +++ /dev/null @@ -1,1295 +0,0 @@ -/* - MATERIAL DATUMS - This data is used by various parts of the game for basic physical properties and behaviors - of the metals/materials used for constructing many objects. Each var is commented and should be pretty - self-explanatory but the various object types may have their own documentation. ~Z - - PATHS THAT USE DATUMS - turf/simulated/wall - obj/item/weapon/material - obj/structure/barricade - obj/item/stack/material - obj/structure/table - - VALID ICONS - WALLS - stone - metal - solid - resin - ONLY WALLS - cult - hull - curvy - jaggy - brick - REINFORCEMENT - reinf_over - reinf_mesh - reinf_cult - reinf_metal - DOORS - stone - metal - resin - wood -*/ - -// Assoc list containing all material datums indexed by name. -var/list/name_to_material - -//Returns the material the object is made of, if applicable. -//Will we ever need to return more than one value here? Or should we just return the "dominant" material. -/obj/proc/get_material() - return null - -//mostly for convenience -/obj/proc/get_material_name() - var/datum/material/material = get_material() - if(material) - return material.name - -// Builds the datum list above. -/proc/populate_material_list(force_remake=0) - if(name_to_material && !force_remake) return // Already set up! - name_to_material = list() - for(var/type in subtypesof(/datum/material)) - var/datum/material/new_mineral = new type - if(!new_mineral.name) - qdel(new_mineral) - continue - name_to_material[lowertext(new_mineral.name)] = new_mineral - return 1 - -// Safety proc to make sure the material list exists before trying to grab from it. -/proc/get_material_by_name(name) - if(!name_to_material) - populate_material_list() - return name_to_material[name] - -/proc/material_display_name(name) - var/datum/material/material = get_material_by_name(name) - if(material) - return material.display_name - return null - -// Material definition and procs follow. -/datum/material - var/name // Unique name for use in indexing the list. - var/display_name // Prettier name for display. - var/use_name - var/flags = 0 // Various status modifiers. - var/sheet_singular_name = "sheet" - var/sheet_plural_name = "sheets" - var/is_fusion_fuel - - // Shards/tables/structures - var/shard_type = SHARD_SHRAPNEL // Path of debris object. - var/shard_icon // Related to above. - var/shard_can_repair = 1 // Can shards be turned into sheets with a welder? - var/list/recipes // Holder for all recipes usable with a sheet of this material. - var/destruction_desc = "breaks apart" // Fancy string for barricades/tables/objects exploding. - - // Icons - var/icon_colour // Colour applied to products of this material. - var/icon_base = "metal" // Wall and table base icon tag. See header. - var/door_icon_base = "metal" // Door base icon tag. See header. - var/icon_reinf = "reinf_metal" // Overlay used - var/list/stack_origin_tech = list(TECH_MATERIAL = 1) // Research level for stacks. - var/pass_stack_colors = FALSE // Will stacks made from this material pass their colors onto objects? - - // Attributes - var/cut_delay = 0 // Delay in ticks when cutting through this wall. - var/radioactivity // Radiation var. Used in wall and object processing to irradiate surroundings. - var/ignition_point // K, point at which the material catches on fire. - var/melting_point = 1800 // K, walls will take damage if they're next to a fire hotter than this - var/integrity = 150 // General-use HP value for products. - var/protectiveness = 10 // How well this material works as armor. Higher numbers are better, diminishing returns applies. - var/opacity = 1 // Is the material transparent? 0.5< makes transparent walls/doors. - var/reflectivity = 0 // How reflective to light is the material? Currently used for laser reflection and defense. - var/explosion_resistance = 5 // Only used by walls currently. - var/negation = 0 // Objects that respect this will randomly absorb impacts with this var as the percent chance. - var/spatial_instability = 0 // Objects that have trouble staying in the same physical space by sheer laws of nature have this. Percent for respecting items to cause teleportation. - var/conductive = 1 // Objects without this var add NOCONDUCT to flags on spawn. - var/conductivity = null // How conductive the material is. Iron acts as the baseline, at 10. - var/list/composite_material // If set, object matter var will be a list containing these values. - var/luminescence - var/radiation_resistance = 0 // Radiation resistance, which is added on top of a material's weight for blocking radiation. Needed to make lead special without superrobust weapons. - var/supply_conversion_value // Supply points per sheet that this material sells for. - - // Placeholder vars for the time being, todo properly integrate windows/light tiles/rods. - var/created_window - var/created_fulltile_window - var/rod_product - var/wire_product - var/list/window_options = list() - - // Damage values. - var/hardness = 60 // Prob of wall destruction by hulk, used for edge damage in weapons. Also used for bullet protection in armor. - var/weight = 20 // Determines blunt damage/throwforce for weapons. - - // Noise when someone is faceplanted onto a table made of this material. - var/tableslam_noise = 'sound/weapons/tablehit1.ogg' - // Noise made when a simple door made of this material opens or closes. - var/dooropen_noise = 'sound/effects/stonedoor_openclose.ogg' - // Path to resulting stacktype. Todo remove need for this. - var/stack_type - // Wallrot crumble message. - var/rotting_touch_message = "crumbles under your touch" - -// Placeholders for light tiles and rglass. -/datum/material/proc/build_rod_product(var/mob/user, var/obj/item/stack/used_stack, var/obj/item/stack/target_stack) - if(!rod_product) - to_chat(user, "You cannot make anything out of \the [target_stack]") - return - if(used_stack.get_amount() < 1 || target_stack.get_amount() < 1) - to_chat(user, "You need one rod and one sheet of [display_name] to make anything useful.") - return - used_stack.use(1) - target_stack.use(1) - var/obj/item/stack/S = new rod_product(get_turf(user)) - S.add_fingerprint(user) - S.add_to_stacks(user) - -/datum/material/proc/build_wired_product(var/mob/living/user, var/obj/item/stack/used_stack, var/obj/item/stack/target_stack) - if(!wire_product) - to_chat(user, "You cannot make anything out of \the [target_stack]") - return - if(used_stack.get_amount() < 5 || target_stack.get_amount() < 1) - to_chat(user, "You need five wires and one sheet of [display_name] to make anything useful.") - return - - used_stack.use(5) - target_stack.use(1) - to_chat(user, "You attach wire to the [name].") - var/obj/item/product = new wire_product(get_turf(user)) - user.put_in_hands(product) - -// Make sure we have a display name and shard icon even if they aren't explicitly set. -/datum/material/New() - ..() - if(!display_name) - display_name = name - if(!use_name) - use_name = display_name - if(!shard_icon) - shard_icon = shard_type - -// This is a placeholder for proper integration of windows/windoors into the system. -/datum/material/proc/build_windows(var/mob/living/user, var/obj/item/stack/used_stack) - return 0 - -// Weapons handle applying a divisor for this value locally. -/datum/material/proc/get_blunt_damage() - return weight //todo - -// Return the matter comprising this material. -/datum/material/proc/get_matter() - var/list/temp_matter = list() - if(islist(composite_material)) - for(var/material_string in composite_material) - temp_matter[material_string] = composite_material[material_string] - else if(SHEET_MATERIAL_AMOUNT) - temp_matter[name] = SHEET_MATERIAL_AMOUNT - return temp_matter - -// As above. -/datum/material/proc/get_edge_damage() - return hardness //todo - -// Snowflakey, only checked for alien doors at the moment. -/datum/material/proc/can_open_material_door(var/mob/living/user) - return 1 - -// Currently used for weapons and objects made of uranium to irradiate things. -/datum/material/proc/products_need_process() - return (radioactivity>0) //todo - -// Used by walls when qdel()ing to avoid neighbor merging. -/datum/material/placeholder - name = "placeholder" - -// Places a girder object when a wall is dismantled, also applies reinforced material. -/datum/material/proc/place_dismantled_girder(var/turf/target, var/datum/material/reinf_material, var/datum/material/girder_material) - var/obj/structure/girder/G = new(target) - if(reinf_material) - G.reinf_material = reinf_material - G.reinforce_girder() - if(girder_material) - if(istype(girder_material, /datum/material)) - girder_material = girder_material.name - G.set_material(girder_material) - - -// General wall debris product placement. -// Not particularly necessary aside from snowflakey cult girders. -/datum/material/proc/place_dismantled_product(var/turf/target) - place_sheet(target) - -// Debris product. Used ALL THE TIME. -/datum/material/proc/place_sheet(var/turf/target) - if(stack_type) - return new stack_type(target) - -// As above. -/datum/material/proc/place_shard(var/turf/target) - if(shard_type) - return new /obj/item/weapon/material/shard(target, src.name) - -// Used by walls and weapons to determine if they break or not. -/datum/material/proc/is_brittle() - return !!(flags & MATERIAL_BRITTLE) - -/datum/material/proc/combustion_effect(var/turf/T, var/temperature) - return - -// Used by walls to do on-touch things, after checking for crumbling and open-ability. -/datum/material/proc/wall_touch_special(var/turf/simulated/wall/W, var/mob/living/L) - return - -// Datum definitions follow. -/datum/material/uranium - name = "uranium" - stack_type = /obj/item/stack/material/uranium - radioactivity = 12 - icon_base = "stone" - icon_reinf = "reinf_stone" - icon_colour = "#007A00" - weight = 22 - stack_origin_tech = list(TECH_MATERIAL = 5) - door_icon_base = "stone" - supply_conversion_value = 2 - -/datum/material/diamond - name = "diamond" - stack_type = /obj/item/stack/material/diamond - flags = MATERIAL_UNMELTABLE - cut_delay = 60 - icon_colour = "#00FFE1" - opacity = 0.4 - reflectivity = 0.6 - conductive = 0 - conductivity = 1 - shard_type = SHARD_SHARD - tableslam_noise = 'sound/effects/Glasshit.ogg' - hardness = 100 - stack_origin_tech = list(TECH_MATERIAL = 6) - supply_conversion_value = 8 - -/datum/material/gold - name = "gold" - stack_type = /obj/item/stack/material/gold - icon_colour = "#EDD12F" - weight = 24 - hardness = 40 - conductivity = 41 - stack_origin_tech = list(TECH_MATERIAL = 4) - sheet_singular_name = "ingot" - sheet_plural_name = "ingots" - supply_conversion_value = 2 - -/datum/material/gold/bronze //placeholder for ashtrays - name = "bronze" - icon_colour = "#EDD12F" - -/datum/material/silver - name = "silver" - stack_type = /obj/item/stack/material/silver - icon_colour = "#D1E6E3" - weight = 22 - hardness = 50 - conductivity = 63 - stack_origin_tech = list(TECH_MATERIAL = 3) - sheet_singular_name = "ingot" - sheet_plural_name = "ingots" - supply_conversion_value = 2 - -//R-UST port -/datum/material/supermatter - name = "supermatter" - icon_colour = "#FFFF00" - stack_type = /obj/item/stack/material/supermatter - shard_type = SHARD_SHARD - radioactivity = 20 - stack_type = null - luminescence = 3 - ignition_point = PHORON_MINIMUM_BURN_TEMPERATURE - icon_base = "stone" - shard_type = SHARD_SHARD - hardness = 30 - door_icon_base = "stone" - sheet_singular_name = "crystal" - sheet_plural_name = "crystals" - is_fusion_fuel = 1 - stack_origin_tech = list(TECH_MATERIAL = 8, TECH_PHORON = 5, TECH_BLUESPACE = 4) - -/datum/material/phoron - name = "phoron" - stack_type = /obj/item/stack/material/phoron - ignition_point = PHORON_MINIMUM_BURN_TEMPERATURE - icon_base = "stone" - icon_colour = "#FC2BC5" - shard_type = SHARD_SHARD - hardness = 30 - stack_origin_tech = list(TECH_MATERIAL = 2, TECH_PHORON = 2) - door_icon_base = "stone" - sheet_singular_name = "crystal" - sheet_plural_name = "crystals" - supply_conversion_value = 5 - -/* -// Commenting this out while fires are so spectacularly lethal, as I can't seem to get this balanced appropriately. -/datum/material/phoron/combustion_effect(var/turf/T, var/temperature, var/effect_multiplier) - if(isnull(ignition_point)) - return 0 - if(temperature < ignition_point) - return 0 - var/totalPhoron = 0 - for(var/turf/simulated/floor/target_tile in range(2,T)) - var/phoronToDeduce = (temperature/30) * effect_multiplier - totalPhoron += phoronToDeduce - target_tile.assume_gas("phoron", phoronToDeduce, 200+T0C) - spawn (0) - target_tile.hotspot_expose(temperature, 400) - return round(totalPhoron/100) -*/ - -/datum/material/stone - name = "sandstone" - stack_type = /obj/item/stack/material/sandstone - icon_base = "stone" - icon_reinf = "reinf_stone" - icon_colour = "#D9C179" - shard_type = SHARD_STONE_PIECE - weight = 22 - hardness = 55 - protectiveness = 5 // 20% - conductive = 0 - conductivity = 5 - door_icon_base = "stone" - sheet_singular_name = "brick" - sheet_plural_name = "bricks" - -/datum/material/stone/marble - name = "marble" - icon_colour = "#AAAAAA" - weight = 26 - hardness = 30 //VOREStation Edit - Please. - integrity = 201 //hack to stop kitchen benches being flippable, todo: refactor into weight system - stack_type = /obj/item/stack/material/marble - supply_conversion_value = 2 - -/datum/material/steel - name = DEFAULT_WALL_MATERIAL - stack_type = /obj/item/stack/material/steel - integrity = 150 - conductivity = 11 // Assuming this is carbon steel, it would actually be slightly less conductive than iron, but lets ignore that. - protectiveness = 10 // 33% - icon_base = "solid" - icon_reinf = "reinf_over" - icon_colour = "#666666" - -/datum/material/steel/hull - name = MAT_STEELHULL - stack_type = /obj/item/stack/material/steel/hull - integrity = 250 - explosion_resistance = 10 - icon_base = "hull" - icon_reinf = "reinf_mesh" - icon_colour = "#666677" - -/datum/material/steel/hull/place_sheet(var/turf/target) //Deconstructed into normal steel sheets. - new /obj/item/stack/material/steel(target) - -/datum/material/diona - name = "biomass" - icon_colour = null - stack_type = null - integrity = 600 - icon_base = "diona" - icon_reinf = "noreinf" - -/datum/material/diona/place_dismantled_product() - return - -/datum/material/diona/place_dismantled_girder(var/turf/target) - spawn_diona_nymph(target) - -/datum/material/steel/holographic - name = "holo" + DEFAULT_WALL_MATERIAL - display_name = DEFAULT_WALL_MATERIAL - stack_type = null - shard_type = SHARD_NONE - -/datum/material/plasteel - name = "plasteel" - stack_type = /obj/item/stack/material/plasteel - integrity = 400 - melting_point = 6000 - icon_base = "solid" - icon_reinf = "reinf_over" - icon_colour = "#777777" - explosion_resistance = 25 - hardness = 80 - weight = 23 - protectiveness = 20 // 50% - conductivity = 13 // For the purposes of balance. - stack_origin_tech = list(TECH_MATERIAL = 2) - composite_material = list(DEFAULT_WALL_MATERIAL = SHEET_MATERIAL_AMOUNT, "platinum" = SHEET_MATERIAL_AMOUNT) //todo - supply_conversion_value = 6 - -/datum/material/plasteel/hull - name = MAT_PLASTEELHULL - stack_type = /obj/item/stack/material/plasteel/hull - integrity = 600 - icon_base = "hull" - icon_reinf = "reinf_mesh" - icon_colour = "#777788" - explosion_resistance = 40 - -/datum/material/plasteel/hull/place_sheet(var/turf/target) //Deconstructed into normal plasteel sheets. - new /obj/item/stack/material/plasteel(target) - -// Very rare alloy that is reflective, should be used sparingly. -/datum/material/durasteel - name = "durasteel" - stack_type = /obj/item/stack/material/durasteel/hull - integrity = 600 - melting_point = 7000 - icon_base = "metal" - icon_reinf = "reinf_metal" - icon_colour = "#6EA7BE" - explosion_resistance = 75 - hardness = 100 - weight = 28 - protectiveness = 60 // 75% - reflectivity = 0.7 // Not a perfect mirror, but close. - stack_origin_tech = list(TECH_MATERIAL = 8) - composite_material = list("plasteel" = SHEET_MATERIAL_AMOUNT, "diamond" = SHEET_MATERIAL_AMOUNT) //shrug - supply_conversion_value = 9 - -/datum/material/durasteel/hull //The 'Hardball' of starship hulls. - name = MAT_DURASTEELHULL - icon_base = "hull" - icon_reinf = "reinf_mesh" - icon_colour = "#45829a" - explosion_resistance = 90 - reflectivity = 0.9 - -/datum/material/durasteel/hull/place_sheet(var/turf/target) //Deconstructed into normal durasteel sheets. - new /obj/item/stack/material/durasteel(target) - -/datum/material/plasteel/titanium - name = MAT_TITANIUM - stack_type = /obj/item/stack/material/titanium - conductivity = 2.38 - icon_base = "metal" - door_icon_base = "metal" - icon_colour = "#D1E6E3" - icon_reinf = "reinf_metal" - composite_material = null - -/datum/material/plasteel/titanium/hull - name = MAT_TITANIUMHULL - stack_type = /obj/item/stack/material/titanium/hull - icon_base = "hull" - icon_reinf = "reinf_mesh" - -/datum/material/plasteel/titanium/hull/place_sheet(var/turf/target) //Deconstructed into normal titanium sheets. - new /obj/item/stack/material/titanium(target) - -/datum/material/glass - name = "glass" - stack_type = /obj/item/stack/material/glass - flags = MATERIAL_BRITTLE - icon_colour = "#00E1FF" - opacity = 0.3 - integrity = 100 - shard_type = SHARD_SHARD - tableslam_noise = 'sound/effects/Glasshit.ogg' - hardness = 30 - weight = 15 - protectiveness = 0 // 0% - conductive = 0 - conductivity = 1 // Glass shards don't conduct. - door_icon_base = "stone" - destruction_desc = "shatters" - window_options = list("One Direction" = 1, "Full Window" = 4, "Windoor" = 2) - created_window = /obj/structure/window/basic - created_fulltile_window = /obj/structure/window/basic/full - rod_product = /obj/item/stack/material/glass/reinforced - -/datum/material/glass/build_windows(var/mob/living/user, var/obj/item/stack/used_stack) - - if(!user || !used_stack || !created_window || !created_fulltile_window || !window_options.len) - return 0 - - if(!user.IsAdvancedToolUser()) - to_chat(user, "This task is too complex for your clumsy hands.") - return 1 - - var/turf/T = user.loc - if(!istype(T)) - to_chat(user, "You must be standing on open flooring to build a window.") - return 1 - - var/title = "Sheet-[used_stack.name] ([used_stack.get_amount()] sheet\s left)" - var/choice = input(title, "What would you like to construct?") as null|anything in window_options - - if(!choice || !used_stack || !user || used_stack.loc != user || user.stat || user.loc != T) - return 1 - - // Get data for building windows here. - var/list/possible_directions = cardinal.Copy() - var/window_count = 0 - for (var/obj/structure/window/check_window in user.loc) - window_count++ - possible_directions -= check_window.dir - for (var/obj/structure/windoor_assembly/check_assembly in user.loc) - window_count++ - possible_directions -= check_assembly.dir - for (var/obj/machinery/door/window/check_windoor in user.loc) - window_count++ - possible_directions -= check_windoor.dir - - // Get the closest available dir to the user's current facing. - var/build_dir = SOUTHWEST //Default to southwest for fulltile windows. - var/failed_to_build - - if(window_count >= 4) - failed_to_build = 1 - else - if(choice in list("One Direction","Windoor")) - if(possible_directions.len) - for(var/direction in list(user.dir, turn(user.dir,90), turn(user.dir,270), turn(user.dir,180))) - if(direction in possible_directions) - build_dir = direction - break - else - failed_to_build = 1 - if(failed_to_build) - to_chat(user, "There is no room in this location.") - return 1 - - var/build_path = /obj/structure/windoor_assembly - var/sheets_needed = window_options[choice] - if(choice == "Windoor") - if(is_reinforced()) - build_path = /obj/structure/windoor_assembly/secure - else if(choice == "Full Window") - build_path = created_fulltile_window - else - build_path = created_window - - if(used_stack.get_amount() < sheets_needed) - to_chat(user, "You need at least [sheets_needed] sheets to build this.") - return 1 - - // Build the structure and update sheet count etc. - used_stack.use(sheets_needed) - new build_path(T, build_dir, 1) - return 1 - -/datum/material/glass/proc/is_reinforced() - return (hardness > 35) //todo - -/datum/material/glass/reinforced - name = "rglass" - display_name = "reinforced glass" - stack_type = /obj/item/stack/material/glass/reinforced - flags = MATERIAL_BRITTLE - icon_colour = "#00E1FF" - opacity = 0.3 - integrity = 100 - shard_type = SHARD_SHARD - tableslam_noise = 'sound/effects/Glasshit.ogg' - hardness = 40 - weight = 30 - stack_origin_tech = list(TECH_MATERIAL = 2) - composite_material = list(DEFAULT_WALL_MATERIAL = SHEET_MATERIAL_AMOUNT / 2, "glass" = SHEET_MATERIAL_AMOUNT) - window_options = list("One Direction" = 1, "Full Window" = 4, "Windoor" = 2) - created_window = /obj/structure/window/reinforced - created_fulltile_window = /obj/structure/window/reinforced/full - wire_product = null - rod_product = null - -/datum/material/glass/phoron - name = "borosilicate glass" - display_name = "borosilicate glass" - stack_type = /obj/item/stack/material/glass/phoronglass - flags = MATERIAL_BRITTLE - integrity = 100 - icon_colour = "#FC2BC5" - stack_origin_tech = list(TECH_MATERIAL = 4) - window_options = list("One Direction" = 1, "Full Window" = 4) - created_window = /obj/structure/window/phoronbasic - created_fulltile_window = /obj/structure/window/phoronbasic/full - wire_product = null - rod_product = /obj/item/stack/material/glass/phoronrglass - -/datum/material/glass/phoron/reinforced - name = "reinforced borosilicate glass" - display_name = "reinforced borosilicate glass" - stack_type = /obj/item/stack/material/glass/phoronrglass - stack_origin_tech = list(TECH_MATERIAL = 5) - composite_material = list() //todo - window_options = list("One Direction" = 1, "Full Window" = 4) - created_window = /obj/structure/window/phoronreinforced - created_fulltile_window = /obj/structure/window/phoronreinforced/full - hardness = 40 - weight = 30 - stack_origin_tech = list(TECH_MATERIAL = 2) - composite_material = list(DEFAULT_WALL_MATERIAL = SHEET_MATERIAL_AMOUNT / 2, "borosilicate glass" = SHEET_MATERIAL_AMOUNT) - rod_product = null - -/datum/material/plastic - name = "plastic" - stack_type = /obj/item/stack/material/plastic - flags = MATERIAL_BRITTLE - icon_base = "solid" - icon_reinf = "reinf_over" - icon_colour = "#CCCCCC" - hardness = 10 - weight = 12 - protectiveness = 5 // 20% - conductive = 0 - conductivity = 2 // For the sake of material armor diversity, we're gonna pretend this plastic is a good insulator. - melting_point = T0C+371 //assuming heat resistant plastic - stack_origin_tech = list(TECH_MATERIAL = 3) - -/datum/material/plastic/holographic - name = "holoplastic" - display_name = "plastic" - stack_type = null - shard_type = SHARD_NONE - -/datum/material/graphite - name = MAT_GRAPHITE - stack_type = /obj/item/stack/material/graphite - flags = MATERIAL_BRITTLE - icon_base = "solid" - icon_reinf = "reinf_mesh" - icon_colour = "#333333" - hardness = 75 - weight = 15 - integrity = 175 - protectiveness = 15 - conductivity = 18 - melting_point = T0C+3600 - radiation_resistance = 15 - stack_origin_tech = list(TECH_MATERIAL = 2, TECH_MAGNET = 2) - -/datum/material/osmium - name = "osmium" - stack_type = /obj/item/stack/material/osmium - icon_colour = "#9999FF" - stack_origin_tech = list(TECH_MATERIAL = 5) - sheet_singular_name = "ingot" - sheet_plural_name = "ingots" - conductivity = 100 - supply_conversion_value = 6 - -/datum/material/tritium - name = "tritium" - stack_type = /obj/item/stack/material/tritium - icon_colour = "#777777" - stack_origin_tech = list(TECH_MATERIAL = 5) - sheet_singular_name = "ingot" - sheet_plural_name = "ingots" - is_fusion_fuel = 1 - conductive = 0 - -/datum/material/deuterium - name = "deuterium" - stack_type = /obj/item/stack/material/deuterium - icon_colour = "#999999" - stack_origin_tech = list(TECH_MATERIAL = 3) - sheet_singular_name = "ingot" - sheet_plural_name = "ingots" - is_fusion_fuel = 1 - conductive = 0 - -/datum/material/mhydrogen - name = "mhydrogen" - stack_type = /obj/item/stack/material/mhydrogen - icon_colour = "#E6C5DE" - stack_origin_tech = list(TECH_MATERIAL = 6, TECH_POWER = 6, TECH_MAGNET = 5) - conductivity = 100 - is_fusion_fuel = 1 - supply_conversion_value = 6 - -/datum/material/platinum - name = "platinum" - stack_type = /obj/item/stack/material/platinum - icon_colour = "#9999FF" - weight = 27 - conductivity = 9.43 - stack_origin_tech = list(TECH_MATERIAL = 2) - sheet_singular_name = "ingot" - sheet_plural_name = "ingots" - supply_conversion_value = 5 - -/datum/material/iron - name = "iron" - stack_type = /obj/item/stack/material/iron - icon_colour = "#5C5454" - weight = 22 - conductivity = 10 - sheet_singular_name = "ingot" - sheet_plural_name = "ingots" - -/datum/material/lead - name = MAT_LEAD - stack_type = /obj/item/stack/material/lead - icon_colour = "#273956" - weight = 23 // Lead is a bit more dense than silver IRL, and silver has 22 ingame. - conductivity = 10 - sheet_singular_name = "ingot" - sheet_plural_name = "ingots" - radiation_resistance = 25 // Lead is Special and so gets to block more radiation than it normally would with just weight, totalling in 48 protection. - supply_conversion_value = 2 - -// Particle Smasher and other exotic materials. - -/datum/material/verdantium - name = MAT_VERDANTIUM - stack_type = /obj/item/stack/material/verdantium - icon_base = "metal" - door_icon_base = "metal" - icon_reinf = "reinf_metal" - icon_colour = "#4FE95A" - integrity = 80 - protectiveness = 15 - weight = 15 - hardness = 30 - shard_type = SHARD_SHARD - negation = 15 - conductivity = 60 - reflectivity = 0.3 - radiation_resistance = 5 - stack_origin_tech = list(TECH_MATERIAL = 6, TECH_POWER = 5, TECH_BIO = 4) - sheet_singular_name = "sheet" - sheet_plural_name = "sheets" - supply_conversion_value = 8 - -/datum/material/morphium - name = MAT_MORPHIUM - stack_type = /obj/item/stack/material/morphium - icon_base = "metal" - door_icon_base = "metal" - icon_colour = "#37115A" - icon_reinf = "reinf_metal" - protectiveness = 60 - integrity = 300 - conductive = 0 - conductivity = 1.5 - hardness = 90 - shard_type = SHARD_SHARD - weight = 30 - negation = 25 - explosion_resistance = 85 - reflectivity = 0.2 - radiation_resistance = 10 - stack_origin_tech = list(TECH_MATERIAL = 8, TECH_ILLEGAL = 1, TECH_PHORON = 4, TECH_BLUESPACE = 4, TECH_ARCANE = 1) - supply_conversion_value = 13 - -/datum/material/morphium/hull - name = MAT_MORPHIUMHULL - stack_type = /obj/item/stack/material/morphium/hull - icon_base = "hull" - icon_reinf = "reinf_mesh" - -/datum/material/valhollide - name = MAT_VALHOLLIDE - stack_type = /obj/item/stack/material/valhollide - icon_base = "stone" - door_icon_base = "stone" - icon_reinf = "reinf_mesh" - icon_colour = "##FFF3B2" - protectiveness = 30 - integrity = 240 - weight = 30 - hardness = 45 - negation = 2 - conductive = 0 - conductivity = 5 - reflectivity = 0.5 - radiation_resistance = 20 - spatial_instability = 30 - stack_origin_tech = list(TECH_MATERIAL = 7, TECH_PHORON = 5, TECH_BLUESPACE = 5) - sheet_singular_name = "gem" - sheet_plural_name = "gems" - - -// Adminspawn only, do not let anyone get this. -/datum/material/alienalloy - name = "alienalloy" - display_name = "durable alloy" - stack_type = null - flags = MATERIAL_UNMELTABLE - icon_colour = "#6C7364" - integrity = 1200 - melting_point = 6000 // Hull plating. - explosion_resistance = 200 // Hull plating. - hardness = 500 - weight = 500 - protectiveness = 80 // 80% - -// Likewise. -/datum/material/alienalloy/elevatorium - name = "elevatorium" - display_name = "elevator panelling" - icon_colour = "#666666" - -// Ditto. -/datum/material/alienalloy/dungeonium - name = "dungeonium" - display_name = "ultra-durable" - icon_base = "dungeon" - icon_colour = "#FFFFFF" - -/datum/material/alienalloy/bedrock - name = "bedrock" - display_name = "impassable rock" - icon_base = "rock" - icon_colour = "#FFFFFF" - -/datum/material/alienalloy/alium - name = "alium" - display_name = "alien" - icon_base = "alien" - icon_colour = "#FFFFFF" - -/datum/material/resin - name = "resin" - icon_colour = "#35343a" - icon_base = "resin" - dooropen_noise = 'sound/effects/attackblob.ogg' - door_icon_base = "resin" - icon_reinf = "reinf_mesh" - melting_point = T0C+300 - sheet_singular_name = "blob" - sheet_plural_name = "blobs" - conductive = 0 - explosion_resistance = 60 - radiation_resistance = 10 - stack_origin_tech = list(TECH_MATERIAL = 8, TECH_PHORON = 4, TECH_BLUESPACE = 4, TECH_BIO = 7) - stack_type = /obj/item/stack/material/resin - -/datum/material/resin/can_open_material_door(var/mob/living/user) - var/mob/living/carbon/M = user - if(istype(M) && locate(/obj/item/organ/internal/xenos/hivenode) in M.internal_organs) - return 1 - return 0 - -/datum/material/resin/wall_touch_special(var/turf/simulated/wall/W, var/mob/living/L) - var/mob/living/carbon/M = L - if(istype(M) && locate(/obj/item/organ/internal/xenos/hivenode) in M.internal_organs) - to_chat(M, "\The [W] shudders under your touch, starting to become porous.") - playsound(W, 'sound/effects/attackblob.ogg', 50, 1) - if(do_after(L, 5 SECONDS)) - spawn(2) - playsound(W, 'sound/effects/attackblob.ogg', 100, 1) - W.dismantle_wall() - return 1 - return 0 - -/datum/material/wood - name = MAT_WOOD - stack_type = /obj/item/stack/material/wood - icon_colour = "#9c5930" - integrity = 50 - icon_base = "wood" - explosion_resistance = 2 - shard_type = SHARD_SPLINTER - shard_can_repair = 0 // you can't weld splinters back into planks - hardness = 15 - weight = 18 - protectiveness = 8 // 28% - conductive = 0 - conductivity = 1 - melting_point = T0C+300 //okay, not melting in this case, but hot enough to destroy wood - ignition_point = T0C+288 - stack_origin_tech = list(TECH_MATERIAL = 1, TECH_BIO = 1) - dooropen_noise = 'sound/effects/doorcreaky.ogg' - door_icon_base = "wood" - destruction_desc = "splinters" - sheet_singular_name = "plank" - sheet_plural_name = "planks" - -/datum/material/wood/log - name = MAT_LOG - icon_base = "log" - stack_type = /obj/item/stack/material/log - sheet_singular_name = null - sheet_plural_name = "pile" - pass_stack_colors = TRUE - supply_conversion_value = 1 - -/datum/material/wood/log/sif - name = MAT_SIFLOG - icon_colour = "#0099cc" // Cyan-ish - stack_origin_tech = list(TECH_MATERIAL = 2, TECH_BIO = 2) - stack_type = /obj/item/stack/material/log/sif - -/datum/material/wood/holographic - name = "holowood" - display_name = "wood" - stack_type = null - shard_type = SHARD_NONE - -/datum/material/wood/sif - name = MAT_SIFWOOD - stack_type = /obj/item/stack/material/wood/sif - icon_colour = "#0099cc" // Cyan-ish - stack_origin_tech = list(TECH_MATERIAL = 2, TECH_BIO = 2) // Alien wood would presumably be more interesting to the analyzer. - -/datum/material/cardboard - name = "cardboard" - stack_type = /obj/item/stack/material/cardboard - flags = MATERIAL_BRITTLE - integrity = 10 - icon_base = "solid" - icon_reinf = "reinf_over" - icon_colour = "#AAAAAA" - hardness = 1 - weight = 1 - protectiveness = 0 // 0% - conductive = 0 - ignition_point = T0C+232 //"the temperature at which book-paper catches fire, and burns." close enough - melting_point = T0C+232 //temperature at which cardboard walls would be destroyed - stack_origin_tech = list(TECH_MATERIAL = 1) - door_icon_base = "wood" - destruction_desc = "crumples" - radiation_resistance = 1 - pass_stack_colors = TRUE - -/datum/material/snow - name = MAT_SNOW - stack_type = /obj/item/stack/material/snow - flags = MATERIAL_BRITTLE - icon_base = "solid" - icon_reinf = "reinf_over" - icon_colour = "#FFFFFF" - integrity = 1 - hardness = 1 - weight = 1 - protectiveness = 0 // 0% - stack_origin_tech = list(TECH_MATERIAL = 1) - melting_point = T0C+1 - destruction_desc = "crumples" - sheet_singular_name = "pile" - sheet_plural_name = "pile" //Just a bigger pile - radiation_resistance = 1 - -/datum/material/snowbrick //only slightly stronger than snow, used to make igloos mostly - name = "packed snow" - flags = MATERIAL_BRITTLE - stack_type = /obj/item/stack/material/snowbrick - icon_base = "stone" - icon_reinf = "reinf_stone" - icon_colour = "#D8FDFF" - integrity = 50 - weight = 2 - hardness = 2 - protectiveness = 0 // 0% - stack_origin_tech = list(TECH_MATERIAL = 1) - melting_point = T0C+1 - destruction_desc = "crumbles" - sheet_singular_name = "brick" - sheet_plural_name = "bricks" - radiation_resistance = 1 - -/datum/material/cloth //todo - name = "cloth" - stack_origin_tech = list(TECH_MATERIAL = 2) - door_icon_base = "wood" - ignition_point = T0C+232 - melting_point = T0C+300 - protectiveness = 1 // 4% - flags = MATERIAL_PADDING - conductive = 0 - integrity = 40 - pass_stack_colors = TRUE - supply_conversion_value = 2 - -/datum/material/cloth/syncloth - name = "syncloth" - stack_origin_tech = list(TECH_MATERIAL = 3, TECH_BIO = 2) - door_icon_base = "wood" - ignition_point = T0C+532 - melting_point = T0C+600 - integrity = 200 - protectiveness = 15 // 4% - flags = MATERIAL_PADDING - conductive = 0 - pass_stack_colors = TRUE - supply_conversion_value = 3 - -/datum/material/cult - name = "cult" - display_name = "disturbing stone" - icon_base = "cult" - icon_colour = "#402821" - icon_reinf = "reinf_cult" - shard_type = SHARD_STONE_PIECE - sheet_singular_name = "brick" - sheet_plural_name = "bricks" - conductive = 0 - -/datum/material/cult/place_dismantled_girder(var/turf/target) - new /obj/structure/girder/cult(target, "cult") - -/datum/material/cult/place_dismantled_product(var/turf/target) - new /obj/effect/decal/cleanable/blood(target) - -/datum/material/cult/reinf - name = "cult2" - display_name = "human remains" - -/datum/material/cult/reinf/place_dismantled_product(var/turf/target) - new /obj/effect/decal/remains/human(target) - -/datum/material/chitin - name = MAT_CHITIN - icon_colour = "#8d6653" - stack_type = /obj/item/stack/material/chitin - stack_origin_tech = list(TECH_MATERIAL = 3, TECH_BIO = 4) - icon_base = "solid" - icon_reinf = "reinf_mesh" - integrity = 60 - weight = 10 - ignition_point = T0C+400 - melting_point = T0C+500 - protectiveness = 20 - conductive = 0 - supply_conversion_value = 4 - -//TODO PLACEHOLDERS: -/datum/material/leather - name = MAT_LEATHER - display_name = "plainleather" - icon_colour = "#5C4831" - stack_type = /obj/item/stack/material/leather - stack_origin_tech = list(TECH_MATERIAL = 2, TECH_BIO = 2) - flags = MATERIAL_PADDING - ignition_point = T0C+300 - melting_point = T0C+300 - protectiveness = 3 // 13% - conductive = 0 - integrity = 40 - supply_conversion_value = 3 - -/datum/material/carpet - name = "carpet" - display_name = "comfy" - use_name = "red upholstery" - icon_colour = "#DA020A" - flags = MATERIAL_PADDING - ignition_point = T0C+232 - melting_point = T0C+300 - sheet_singular_name = "tile" - sheet_plural_name = "tiles" - protectiveness = 1 // 4% - conductive = 0 - -/datum/material/cotton - name = "cotton" - display_name ="cotton" - icon_colour = "#FFFFFF" - flags = MATERIAL_PADDING - ignition_point = T0C+232 - melting_point = T0C+300 - protectiveness = 1 // 4% - conductive = 0 - -// This all needs to be OOP'd and use inheritence if its ever used in the future. -/datum/material/cloth_teal - name = "teal" - display_name ="teal" - use_name = "teal cloth" - icon_colour = "#00EAFA" - flags = MATERIAL_PADDING - ignition_point = T0C+232 - melting_point = T0C+300 - protectiveness = 1 // 4% - conductive = 0 - -/datum/material/cloth_black - name = "black" - display_name = "black" - use_name = "black cloth" - icon_colour = "#505050" - flags = MATERIAL_PADDING - ignition_point = T0C+232 - melting_point = T0C+300 - protectiveness = 1 // 4% - conductive = 0 - -/datum/material/cloth_green - name = "green" - display_name = "green" - use_name = "green cloth" - icon_colour = "#01C608" - flags = MATERIAL_PADDING - ignition_point = T0C+232 - melting_point = T0C+300 - protectiveness = 1 // 4% - conductive = 0 - -/datum/material/cloth_puple - name = "purple" - display_name = "purple" - use_name = "purple cloth" - icon_colour = "#9C56C4" - flags = MATERIAL_PADDING - ignition_point = T0C+232 - melting_point = T0C+300 - protectiveness = 1 // 4% - conductive = 0 - -/datum/material/cloth_blue - name = "blue" - display_name = "blue" - use_name = "blue cloth" - icon_colour = "#6B6FE3" - flags = MATERIAL_PADDING - ignition_point = T0C+232 - melting_point = T0C+300 - protectiveness = 1 // 4% - conductive = 0 - -/datum/material/cloth_beige - name = "beige" - display_name = "beige" - use_name = "beige cloth" - icon_colour = "#E8E7C8" - flags = MATERIAL_PADDING - ignition_point = T0C+232 - melting_point = T0C+300 - protectiveness = 1 // 4% - conductive = 0 - -/datum/material/cloth_lime - name = "lime" - display_name = "lime" - use_name = "lime cloth" - icon_colour = "#62E36C" - flags = MATERIAL_PADDING - ignition_point = T0C+232 - melting_point = T0C+300 - protectiveness = 1 // 4% - conductive = 0 - -/datum/material/cloth_yellow - name = "yellow" - display_name = "yellow" - use_name = "yellow cloth" - icon_colour = "#EEF573" - flags = MATERIAL_PADDING - ignition_point = T0C+232 - melting_point = T0C+300 - protectiveness = 1 // 4% - conductive = 0 - -/datum/material/cloth_orange - name = "orange" - display_name = "orange" - use_name = "orange cloth" - icon_colour = "#E3BF49" - flags = MATERIAL_PADDING - ignition_point = T0C+232 - melting_point = T0C+300 - protectiveness = 1 // 4% - conductive = 0 - -/datum/material/toy_foam - name = "foam" - display_name = "foam" - use_name = "foam" - flags = MATERIAL_PADDING - ignition_point = T0C+232 - melting_point = T0C+300 - icon_colour = "#ff9900" - hardness = 1 - weight = 1 - protectiveness = 0 // 0% - conductive = 0 - -/datum/material/void_opal - name = "void opal" - display_name = "void opal" - use_name = "void opal" - icon_colour = "#0f0f0f" - stack_type = /obj/item/stack/material/void_opal - flags = MATERIAL_UNMELTABLE - cut_delay = 60 - reflectivity = 0 - conductivity = 1 - shard_type = SHARD_SHARD - tableslam_noise = 'sound/effects/Glasshit.ogg' - hardness = 100 - stack_origin_tech = list(TECH_ARCANE = 1, TECH_MATERIAL = 6) - sheet_singular_name = "gem" - sheet_plural_name = "gems" - supply_conversion_value = 30 // These are hilariously rare. - -/datum/material/painite - name = "painite" - display_name = "painite" - use_name = "painite" - icon_colour = "#6b4947" - stack_type = /obj/item/stack/material/painite - flags = MATERIAL_UNMELTABLE - reflectivity = 0.3 - tableslam_noise = 'sound/effects/Glasshit.ogg' - sheet_singular_name = "gem" - sheet_plural_name = "gems" - supply_conversion_value = 4 - -/datum/material/tin - name = "tin" - display_name = "tin" - use_name = "tin" - stack_type = /obj/item/stack/material/tin - icon_colour = "#b2afaf" - sheet_singular_name = "ingot" - sheet_plural_name = "ingots" - supply_conversion_value = 1 - hardness = 50 - weight = 13 - -/datum/material/copper - name = "copper" - display_name = "copper" - use_name = "copper" - stack_type = /obj/item/stack/material/copper - conductivity = 52 - icon_colour = "#af633e" - sheet_singular_name = "ingot" - sheet_plural_name = "ingots" - supply_conversion_value = 1 - weight = 13 - hardness = 50 - -/datum/material/quartz - name = "quartz" - display_name = "quartz" - use_name = "quartz" - icon_colour = "#e6d7df" - stack_type = /obj/item/stack/material/quartz - tableslam_noise = 'sound/effects/Glasshit.ogg' - sheet_singular_name = "crystal" - sheet_plural_name = "crystals" - supply_conversion_value = 4 - -/datum/material/aluminium - name = "aluminium" - display_name = "aluminium" - use_name = "aluminium" - icon_colour = "#e5e2d0" - stack_type = /obj/item/stack/material/aluminium - sheet_singular_name = "ingot" - sheet_plural_name = "ingots" - supply_conversion_value = 2 - weight = 10 diff --git a/code/modules/materials/materials/_materials.dm b/code/modules/materials/materials/_materials.dm new file mode 100644 index 00000000000..1b6cabffd96 --- /dev/null +++ b/code/modules/materials/materials/_materials.dm @@ -0,0 +1,284 @@ +/* + MATERIAL DATUMS + This data is used by various parts of the game for basic physical properties and behaviors + of the metals/materials used for constructing many objects. Each var is commented and should be pretty + self-explanatory but the various object types may have their own documentation. ~Z + + PATHS THAT USE DATUMS + turf/simulated/wall + obj/item/weapon/material + obj/structure/barricade + obj/item/stack/material + obj/structure/table + + VALID ICONS + WALLS + stone + metal + solid + resin + ONLY WALLS + cult + hull + curvy + jaggy + brick + REINFORCEMENT + reinf_over + reinf_mesh + reinf_cult + reinf_metal + DOORS + stone + metal + resin + wood +*/ + +// Assoc list containing all material datums indexed by name. +var/list/name_to_material + +//Returns the material the object is made of, if applicable. +//Will we ever need to return more than one value here? Or should we just return the "dominant" material. +/obj/proc/get_material() + return null + +//mostly for convenience +/obj/proc/get_material_name() + var/datum/material/material = get_material() + if(material) + return material.name + +// Builds the datum list above. +/proc/populate_material_list(force_remake=0) + if(name_to_material && !force_remake) return // Already set up! + name_to_material = list() + for(var/type in subtypesof(/datum/material)) + var/datum/material/new_mineral = new type + if(!new_mineral.name) + continue + name_to_material[lowertext(new_mineral.name)] = new_mineral + return 1 + +// Safety proc to make sure the material list exists before trying to grab from it. +/proc/get_material_by_name(name) + if(!name_to_material) + populate_material_list() + return name_to_material[name] + +/proc/material_display_name(name) + var/datum/material/material = get_material_by_name(name) + if(material) + return material.display_name + return null + +// Material definition and procs follow. +/datum/material + var/name // Unique name for use in indexing the list. + var/display_name // Prettier name for display. + var/use_name + var/flags = 0 // Various status modifiers. + var/sheet_singular_name = "sheet" + var/sheet_plural_name = "sheets" + var/is_fusion_fuel + + // Shards/tables/structures + var/shard_type = SHARD_SHRAPNEL // Path of debris object. + var/shard_icon // Related to above. + var/shard_can_repair = 1 // Can shards be turned into sheets with a welder? + var/list/recipes // Holder for all recipes usable with a sheet of this material. + var/destruction_desc = "breaks apart" // Fancy string for barricades/tables/objects exploding. + + // Icons + var/icon_colour // Colour applied to products of this material. + var/icon_base = "metal" // Wall and table base icon tag. See header. + var/door_icon_base = "metal" // Door base icon tag. See header. + var/icon_reinf = "reinf_metal" // Overlay used + var/list/stack_origin_tech = list(TECH_MATERIAL = 1) // Research level for stacks. + var/pass_stack_colors = FALSE // Will stacks made from this material pass their colors onto objects? + + // Attributes + var/cut_delay = 0 // Delay in ticks when cutting through this wall. + var/radioactivity // Radiation var. Used in wall and object processing to irradiate surroundings. + var/ignition_point // K, point at which the material catches on fire. + var/melting_point = 1800 // K, walls will take damage if they're next to a fire hotter than this + var/integrity = 150 // General-use HP value for products. + var/protectiveness = 10 // How well this material works as armor. Higher numbers are better, diminishing returns applies. + var/opacity = 1 // Is the material transparent? 0.5< makes transparent walls/doors. + var/reflectivity = 0 // How reflective to light is the material? Currently used for laser reflection and defense. + var/explosion_resistance = 5 // Only used by walls currently. + var/negation = 0 // Objects that respect this will randomly absorb impacts with this var as the percent chance. + var/spatial_instability = 0 // Objects that have trouble staying in the same physical space by sheer laws of nature have this. Percent for respecting items to cause teleportation. + var/conductive = 1 // Objects without this var add NOCONDUCT to flags on spawn. + var/conductivity = null // How conductive the material is. Iron acts as the baseline, at 10. + var/list/composite_material // If set, object matter var will be a list containing these values. + var/luminescence + var/radiation_resistance = 0 // Radiation resistance, which is added on top of a material's weight for blocking radiation. Needed to make lead special without superrobust weapons. + var/supply_conversion_value // Supply points per sheet that this material sells for. + + // Placeholder vars for the time being, todo properly integrate windows/light tiles/rods. + var/created_window + var/created_fulltile_window + var/rod_product + var/wire_product + var/list/window_options = list() + + // Damage values. + var/hardness = 60 // Prob of wall destruction by hulk, used for edge damage in weapons. Also used for bullet protection in armor. + var/weight = 20 // Determines blunt damage/throwforce for weapons. + + // Noise when someone is faceplanted onto a table made of this material. + var/tableslam_noise = 'sound/weapons/tablehit1.ogg' + // Noise made when a simple door made of this material opens or closes. + var/dooropen_noise = 'sound/effects/stonedoor_openclose.ogg' + // Path to resulting stacktype. Todo remove need for this. + var/stack_type + // Wallrot crumble message. + var/rotting_touch_message = "crumbles under your touch" + +// Placeholders for light tiles and rglass. +/datum/material/proc/build_rod_product(var/mob/user, var/obj/item/stack/used_stack, var/obj/item/stack/target_stack) + if(!rod_product) + to_chat(user, "You cannot make anything out of \the [target_stack]") + return + if(used_stack.get_amount() < 1 || target_stack.get_amount() < 1) + to_chat(user, "You need one rod and one sheet of [display_name] to make anything useful.") + return + used_stack.use(1) + target_stack.use(1) + var/obj/item/stack/S = new rod_product(get_turf(user)) + S.add_fingerprint(user) + S.add_to_stacks(user) + +/datum/material/proc/build_wired_product(var/mob/living/user, var/obj/item/stack/used_stack, var/obj/item/stack/target_stack) + if(!wire_product) + to_chat(user, "You cannot make anything out of \the [target_stack]") + return + if(used_stack.get_amount() < 5 || target_stack.get_amount() < 1) + to_chat(user, "You need five wires and one sheet of [display_name] to make anything useful.") + return + + used_stack.use(5) + target_stack.use(1) + to_chat(user, "You attach wire to the [name].") + var/obj/item/product = new wire_product(get_turf(user)) + user.put_in_hands(product) + +// Make sure we have a display name and shard icon even if they aren't explicitly set. +/datum/material/New() + ..() + if(!display_name) + display_name = name + if(!use_name) + use_name = display_name + if(!shard_icon) + shard_icon = shard_type + +// This is a placeholder for proper integration of windows/windoors into the system. +/datum/material/proc/build_windows(var/mob/living/user, var/obj/item/stack/used_stack) + return 0 + +// Weapons handle applying a divisor for this value locally. +/datum/material/proc/get_blunt_damage() + return weight //todo + +// Return the matter comprising this material. +/datum/material/proc/get_matter() + var/list/temp_matter = list() + if(islist(composite_material)) + for(var/material_string in composite_material) + temp_matter[material_string] = composite_material[material_string] + else if(SHEET_MATERIAL_AMOUNT) + temp_matter[name] = SHEET_MATERIAL_AMOUNT + return temp_matter + +// As above. +/datum/material/proc/get_edge_damage() + return hardness //todo + +// Snowflakey, only checked for alien doors at the moment. +/datum/material/proc/can_open_material_door(var/mob/living/user) + return 1 + +// Currently used for weapons and objects made of uranium to irradiate things. +/datum/material/proc/products_need_process() + return (radioactivity>0) //todo + +// Used by walls when qdel()ing to avoid neighbor merging. +/datum/material/placeholder + name = "placeholder" + +// Places a girder object when a wall is dismantled, also applies reinforced material. +/datum/material/proc/place_dismantled_girder(var/turf/target, var/datum/material/reinf_material, var/datum/material/girder_material) + var/obj/structure/girder/G = new(target) + if(reinf_material) + G.reinf_material = reinf_material + G.reinforce_girder() + if(girder_material) + if(istype(girder_material, /datum/material)) + girder_material = girder_material.name + G.set_material(girder_material) + + +// General wall debris product placement. +// Not particularly necessary aside from snowflakey cult girders. +/datum/material/proc/place_dismantled_product(var/turf/target) + place_sheet(target) + +// Debris product. Used ALL THE TIME. +/datum/material/proc/place_sheet(var/turf/target) + if(stack_type) + return new stack_type(target) + +// As above. +/datum/material/proc/place_shard(var/turf/target) + if(shard_type) + return new /obj/item/weapon/material/shard(target, src.name) + +// Used by walls and weapons to determine if they break or not. +/datum/material/proc/is_brittle() + return !!(flags & MATERIAL_BRITTLE) + +/datum/material/proc/combustion_effect(var/turf/T, var/temperature) + return + +// Used by walls to do on-touch things, after checking for crumbling and open-ability. +/datum/material/proc/wall_touch_special(var/turf/simulated/wall/W, var/mob/living/L) + return + +/datum/material/proc/get_recipes() + if(!recipes) + generate_recipes() + return recipes + +/datum/material/proc/generate_recipes() + // If is_brittle() returns true, these are only good for a single strike. + recipes = list( + new /datum/stack_recipe("[display_name] baseball bat", /obj/item/weapon/material/twohanded/baseballbat, 10, time = 20, one_per_turf = 0, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE), + new /datum/stack_recipe("[display_name] ashtray", /obj/item/weapon/material/ashtray, 2, one_per_turf = 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE), + new /datum/stack_recipe("[display_name] spoon", /obj/item/weapon/material/kitchen/utensil/spoon/plastic, 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE), + new /datum/stack_recipe("[display_name] armor plate", /obj/item/weapon/material/armor_plating, 1, time = 20, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE), + new /datum/stack_recipe("[display_name] armor plate insert", /obj/item/weapon/material/armor_plating/insert, 2, time = 40, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE), + new /datum/stack_recipe("[display_name] grave marker", /obj/item/weapon/material/gravemarker, 5, time = 50, supplied_material = "[name]", pass_stack_color = TRUE), + new /datum/stack_recipe("[display_name] ring", /obj/item/clothing/gloves/ring/material, 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE), + new /datum/stack_recipe("[display_name] bracelet", /obj/item/clothing/accessory/bracelet/material, 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE) + ) + + if(integrity>=50) + recipes += list( + new /datum/stack_recipe("[display_name] door", /obj/structure/simple_door, 10, one_per_turf = 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE), + new /datum/stack_recipe("[display_name] barricade", /obj/structure/barricade, 5, time = 50, one_per_turf = 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE), + new /datum/stack_recipe("[display_name] stool", /obj/item/weapon/stool, one_per_turf = 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE), + new /datum/stack_recipe("[display_name] chair", /obj/structure/bed/chair, one_per_turf = 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE), + new /datum/stack_recipe("[display_name] bed", /obj/structure/bed, 2, one_per_turf = 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE), + new /datum/stack_recipe("[display_name] double bed", /obj/structure/bed/double, 4, one_per_turf = 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE), + new /datum/stack_recipe("[display_name] wall girders", /obj/structure/girder, 2, time = 50, one_per_turf = 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE) + ) + + if(hardness>50) + recipes += list( + new /datum/stack_recipe("[display_name] fork", /obj/item/weapon/material/kitchen/utensil/fork/plastic, 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE), + new /datum/stack_recipe("[display_name] knife", /obj/item/weapon/material/knife/plastic, 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE), + new /datum/stack_recipe("[display_name] blade", /obj/item/weapon/material/butterflyblade, 6, time = 20, one_per_turf = 0, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE), + new /datum/stack_recipe("[display_name] defense wire", /obj/item/weapon/material/barbedwire, 10, time = 1 MINUTE, one_per_turf = 0, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE) + ) \ No newline at end of file diff --git a/code/modules/materials/materials/_materials_vr.dm b/code/modules/materials/materials/_materials_vr.dm new file mode 100644 index 00000000000..8c91622fb35 --- /dev/null +++ b/code/modules/materials/materials/_materials_vr.dm @@ -0,0 +1,9 @@ +/obj/item/stack/material/attack(mob/living/M as mob, mob/living/user as mob) + if(M.handle_eat_minerals(src, user)) + return + ..() + +/obj/item/stack/material/attack_generic(var/mob/living/user) //Allow adminbussed mobs to eat ore if they click it while NOT on help intent. + if(user.handle_eat_minerals(src)) + return + ..() diff --git a/code/modules/materials/materials/alien_alloy.dm b/code/modules/materials/materials/alien_alloy.dm new file mode 100644 index 00000000000..741f0275b75 --- /dev/null +++ b/code/modules/materials/materials/alien_alloy.dm @@ -0,0 +1,36 @@ +// Adminspawn only, do not let anyone get this. +/datum/material/alienalloy + name = "alienalloy" + display_name = "durable alloy" + stack_type = null + flags = MATERIAL_UNMELTABLE + icon_colour = "#6C7364" + integrity = 1200 + melting_point = 6000 // Hull plating. + explosion_resistance = 200 // Hull plating. + hardness = 500 + weight = 500 + protectiveness = 80 // 80% + +/datum/material/alienalloy/elevatorium + name = "elevatorium" + display_name = "elevator panelling" + icon_colour = "#666666" + +/datum/material/alienalloy/dungeonium + name = "dungeonium" + display_name = "ultra-durable" + icon_base = "dungeon" + icon_colour = "#FFFFFF" + +/datum/material/alienalloy/bedrock + name = "bedrock" + display_name = "impassable rock" + icon_base = "rock" + icon_colour = "#FFFFFF" + +/datum/material/alienalloy/alium + name = "alium" + display_name = "alien" + icon_base = "alien" + icon_colour = "#FFFFFF" \ No newline at end of file diff --git a/code/modules/materials/materials/cult.dm b/code/modules/materials/materials/cult.dm new file mode 100644 index 00000000000..7d8d4be9f2f --- /dev/null +++ b/code/modules/materials/materials/cult.dm @@ -0,0 +1,23 @@ +/datum/material/cult + name = "cult" + display_name = "disturbing stone" + icon_base = "cult" + icon_colour = "#402821" + icon_reinf = "reinf_cult" + shard_type = SHARD_STONE_PIECE + sheet_singular_name = "brick" + sheet_plural_name = "bricks" + conductive = 0 + +/datum/material/cult/place_dismantled_girder(var/turf/target) + new /obj/structure/girder/cult(target, "cult") + +/datum/material/cult/place_dismantled_product(var/turf/target) + new /obj/effect/decal/cleanable/blood(target) + +/datum/material/cult/reinf + name = "cult2" + display_name = "human remains" + +/datum/material/cult/reinf/place_dismantled_product(var/turf/target) + new /obj/effect/decal/remains/human(target) \ No newline at end of file diff --git a/code/modules/materials/materials/gems.dm b/code/modules/materials/materials/gems.dm new file mode 100644 index 00000000000..9ec22a86b13 --- /dev/null +++ b/code/modules/materials/materials/gems.dm @@ -0,0 +1,154 @@ +/datum/material/phoron + name = "phoron" + stack_type = /obj/item/stack/material/phoron + ignition_point = PHORON_MINIMUM_BURN_TEMPERATURE + icon_base = "stone" + icon_colour = "#FC2BC5" + shard_type = SHARD_SHARD + hardness = 30 + stack_origin_tech = list(TECH_MATERIAL = 2, TECH_PHORON = 2) + door_icon_base = "stone" + sheet_singular_name = "crystal" + sheet_plural_name = "crystals" + supply_conversion_value = 5 + +/* +// Commenting this out while fires are so spectacularly lethal, as I can't seem to get this balanced appropriately. +/datum/material/phoron/combustion_effect(var/turf/T, var/temperature, var/effect_multiplier) + if(isnull(ignition_point)) + return 0 + if(temperature < ignition_point) + return 0 + var/totalPhoron = 0 + for(var/turf/simulated/floor/target_tile in range(2,T)) + var/phoronToDeduce = (temperature/30) * effect_multiplier + totalPhoron += phoronToDeduce + target_tile.assume_gas("phoron", phoronToDeduce, 200+T0C) + spawn (0) + target_tile.hotspot_expose(temperature, 400) + return round(totalPhoron/100) +*/ + +/datum/material/diamond + name = "diamond" + stack_type = /obj/item/stack/material/diamond + flags = MATERIAL_UNMELTABLE + cut_delay = 60 + icon_colour = "#00FFE1" + opacity = 0.4 + reflectivity = 0.6 + conductive = 0 + conductivity = 1 + shard_type = SHARD_SHARD + tableslam_noise = 'sound/effects/Glasshit.ogg' + hardness = 100 + stack_origin_tech = list(TECH_MATERIAL = 6) + supply_conversion_value = 8 + +/datum/material/quartz + name = "quartz" + display_name = "quartz" + use_name = "quartz" + icon_colour = "#e6d7df" + stack_type = /obj/item/stack/material/quartz + tableslam_noise = 'sound/effects/Glasshit.ogg' + sheet_singular_name = "crystal" + sheet_plural_name = "crystals" + supply_conversion_value = 4 + +/datum/material/painite + name = "painite" + display_name = "painite" + use_name = "painite" + icon_colour = "#6b4947" + stack_type = /obj/item/stack/material/painite + flags = MATERIAL_UNMELTABLE + reflectivity = 0.3 + tableslam_noise = 'sound/effects/Glasshit.ogg' + sheet_singular_name = "gem" + sheet_plural_name = "gems" + supply_conversion_value = 4 + +/datum/material/void_opal + name = "void opal" + display_name = "void opal" + use_name = "void opal" + icon_colour = "#0f0f0f" + stack_type = /obj/item/stack/material/void_opal + flags = MATERIAL_UNMELTABLE + cut_delay = 60 + reflectivity = 0 + conductivity = 1 + shard_type = SHARD_SHARD + tableslam_noise = 'sound/effects/Glasshit.ogg' + hardness = 100 + stack_origin_tech = list(TECH_ARCANE = 1, TECH_MATERIAL = 6) + sheet_singular_name = "gem" + sheet_plural_name = "gems" + supply_conversion_value = 30 // These are hilariously rare. + +// Particle Smasher and other exotic materials. +/datum/material/valhollide + name = MAT_VALHOLLIDE + stack_type = /obj/item/stack/material/valhollide + icon_base = "stone" + door_icon_base = "stone" + icon_reinf = "reinf_mesh" + icon_colour = "##FFF3B2" + protectiveness = 30 + integrity = 240 + weight = 30 + hardness = 45 + negation = 2 + conductive = 0 + conductivity = 5 + reflectivity = 0.5 + radiation_resistance = 20 + spatial_instability = 30 + stack_origin_tech = list(TECH_MATERIAL = 7, TECH_PHORON = 5, TECH_BLUESPACE = 5) + sheet_singular_name = "gem" + sheet_plural_name = "gems" + +/datum/material/verdantium + name = MAT_VERDANTIUM + stack_type = /obj/item/stack/material/verdantium + icon_base = "metal" + door_icon_base = "metal" + icon_reinf = "reinf_metal" + icon_colour = "#4FE95A" + integrity = 80 + protectiveness = 15 + weight = 15 + hardness = 30 + shard_type = SHARD_SHARD + negation = 15 + conductivity = 60 + reflectivity = 0.3 + radiation_resistance = 5 + stack_origin_tech = list(TECH_MATERIAL = 6, TECH_POWER = 5, TECH_BIO = 4) + sheet_singular_name = "sheet" + sheet_plural_name = "sheets" + supply_conversion_value = 8 + +/datum/material/morphium + name = MAT_MORPHIUM + stack_type = /obj/item/stack/material/morphium + icon_base = "metal" + door_icon_base = "metal" + icon_colour = "#37115A" + icon_reinf = "reinf_metal" + protectiveness = 60 + integrity = 300 + conductive = 0 + conductivity = 1.5 + hardness = 90 + shard_type = SHARD_SHARD + weight = 30 + negation = 25 + explosion_resistance = 85 + reflectivity = 0.2 + radiation_resistance = 10 + stack_origin_tech = list(TECH_MATERIAL = 8, TECH_ILLEGAL = 1, TECH_PHORON = 4, TECH_BLUESPACE = 4, TECH_ARCANE = 1) + supply_conversion_value = 13 + + diff --git a/code/modules/materials/materials/glass.dm b/code/modules/materials/materials/glass.dm new file mode 100644 index 00000000000..79535422785 --- /dev/null +++ b/code/modules/materials/materials/glass.dm @@ -0,0 +1,143 @@ +/datum/material/glass + name = "glass" + stack_type = /obj/item/stack/material/glass + flags = MATERIAL_BRITTLE + icon_colour = "#00E1FF" + opacity = 0.3 + integrity = 100 + shard_type = SHARD_SHARD + tableslam_noise = 'sound/effects/Glasshit.ogg' + hardness = 30 + weight = 15 + protectiveness = 0 // 0% + conductive = 0 + conductivity = 1 // Glass shards don't conduct. + door_icon_base = "stone" + destruction_desc = "shatters" + window_options = list("One Direction" = 1, "Full Window" = 4, "Windoor" = 2) + created_window = /obj/structure/window/basic + created_fulltile_window = /obj/structure/window/basic/full + rod_product = /obj/item/stack/material/glass/reinforced + +/datum/material/glass/build_windows(var/mob/living/user, var/obj/item/stack/used_stack) + + if(!user || !used_stack || !created_window || !created_fulltile_window || !window_options.len) + return 0 + + if(!user.IsAdvancedToolUser()) + to_chat(user, "This task is too complex for your clumsy hands.") + return 1 + + var/turf/T = user.loc + if(!istype(T)) + to_chat(user, "You must be standing on open flooring to build a window.") + return 1 + + var/title = "Sheet-[used_stack.name] ([used_stack.get_amount()] sheet\s left)" + var/choice = input(title, "What would you like to construct?") as null|anything in window_options + + if(!choice || !used_stack || !user || used_stack.loc != user || user.stat || user.loc != T) + return 1 + + // Get data for building windows here. + var/list/possible_directions = cardinal.Copy() + var/window_count = 0 + for (var/obj/structure/window/check_window in user.loc) + window_count++ + possible_directions -= check_window.dir + for (var/obj/structure/windoor_assembly/check_assembly in user.loc) + window_count++ + possible_directions -= check_assembly.dir + for (var/obj/machinery/door/window/check_windoor in user.loc) + window_count++ + possible_directions -= check_windoor.dir + + // Get the closest available dir to the user's current facing. + var/build_dir = SOUTHWEST //Default to southwest for fulltile windows. + var/failed_to_build + + if(window_count >= 4) + failed_to_build = 1 + else + if(choice in list("One Direction","Windoor")) + if(possible_directions.len) + for(var/direction in list(user.dir, turn(user.dir,90), turn(user.dir,270), turn(user.dir,180))) + if(direction in possible_directions) + build_dir = direction + break + else + failed_to_build = 1 + if(failed_to_build) + to_chat(user, "There is no room in this location.") + return 1 + + var/build_path = /obj/structure/windoor_assembly + var/sheets_needed = window_options[choice] + if(choice == "Windoor") + if(is_reinforced()) + build_path = /obj/structure/windoor_assembly/secure + else if(choice == "Full Window") + build_path = created_fulltile_window + else + build_path = created_window + + if(used_stack.get_amount() < sheets_needed) + to_chat(user, "You need at least [sheets_needed] sheets to build this.") + return 1 + + // Build the structure and update sheet count etc. + used_stack.use(sheets_needed) + new build_path(T, build_dir, 1) + return 1 + +/datum/material/glass/proc/is_reinforced() + return (hardness > 35) //todo + +/datum/material/glass/reinforced + name = "rglass" + display_name = "reinforced glass" + stack_type = /obj/item/stack/material/glass/reinforced + flags = MATERIAL_BRITTLE + icon_colour = "#00E1FF" + opacity = 0.3 + integrity = 100 + shard_type = SHARD_SHARD + tableslam_noise = 'sound/effects/Glasshit.ogg' + hardness = 40 + weight = 30 + stack_origin_tech = list(TECH_MATERIAL = 2) + composite_material = list(DEFAULT_WALL_MATERIAL = SHEET_MATERIAL_AMOUNT / 2, "glass" = SHEET_MATERIAL_AMOUNT) + window_options = list("One Direction" = 1, "Full Window" = 4, "Windoor" = 2) + created_window = /obj/structure/window/reinforced + created_fulltile_window = /obj/structure/window/reinforced/full + wire_product = null + rod_product = null + +/datum/material/glass/phoron + name = "borosilicate glass" + display_name = "borosilicate glass" + stack_type = /obj/item/stack/material/glass/phoronglass + flags = MATERIAL_BRITTLE + integrity = 100 + icon_colour = "#FC2BC5" + stack_origin_tech = list(TECH_MATERIAL = 4) + window_options = list("One Direction" = 1, "Full Window" = 4) + created_window = /obj/structure/window/phoronbasic + created_fulltile_window = /obj/structure/window/phoronbasic/full + wire_product = null + rod_product = /obj/item/stack/material/glass/phoronrglass + +/datum/material/glass/phoron/reinforced + name = "reinforced borosilicate glass" + display_name = "reinforced borosilicate glass" + stack_type = /obj/item/stack/material/glass/phoronrglass + stack_origin_tech = list(TECH_MATERIAL = 5) + composite_material = list() //todo + window_options = list("One Direction" = 1, "Full Window" = 4) + created_window = /obj/structure/window/phoronreinforced + created_fulltile_window = /obj/structure/window/phoronreinforced/full + hardness = 40 + weight = 30 + stack_origin_tech = list(TECH_MATERIAL = 2) + composite_material = list(DEFAULT_WALL_MATERIAL = SHEET_MATERIAL_AMOUNT / 2, "borosilicate glass" = SHEET_MATERIAL_AMOUNT) + rod_product = null diff --git a/code/modules/materials/materials/glass_vr.dm b/code/modules/materials/materials/glass_vr.dm new file mode 100644 index 00000000000..9d7cd818796 --- /dev/null +++ b/code/modules/materials/materials/glass_vr.dm @@ -0,0 +1,33 @@ +/datum/material/glass/titaniumglass + name = MAT_TITANIUMGLASS + display_name = "titanium glass" + stack_type = /obj/item/stack/material/glass/titanium + integrity = 150 + hardness = 50 + weight = 50 + flags = MATERIAL_BRITTLE + icon_colour = "#A7A3A6" + stack_origin_tech = list(TECH_MATERIAL = 5) + window_options = list("One Direction" = 1, "Full Window" = 4) + created_window = /obj/structure/window/titanium + created_fulltile_window = /obj/structure/window/titanium/full + wire_product = null + rod_product = /obj/item/stack/material/glass/titanium + composite_material = list(MAT_TITANIUM = SHEET_MATERIAL_AMOUNT, "glass" = SHEET_MATERIAL_AMOUNT) + +/datum/material/glass/plastaniumglass + name = MAT_PLASTITANIUMGLASS + display_name = "plas-titanium glass" + stack_type = /obj/item/stack/material/glass/plastitanium + integrity = 200 + hardness = 60 + weight = 80 + flags = MATERIAL_BRITTLE + icon_colour = "#676366" + stack_origin_tech = list(TECH_MATERIAL = 6) + window_options = list("One Direction" = 1, "Full Window" = 4) + created_window = /obj/structure/window/plastitanium + created_fulltile_window = /obj/structure/window/plastitanium/full + wire_product = null + rod_product = /obj/item/stack/material/glass/plastitanium + composite_material = list(MAT_PLASTITANIUM = SHEET_MATERIAL_AMOUNT, "glass" = SHEET_MATERIAL_AMOUNT) diff --git a/code/modules/materials/materials/holographic.dm b/code/modules/materials/materials/holographic.dm new file mode 100644 index 00000000000..ff6474ec1e7 --- /dev/null +++ b/code/modules/materials/materials/holographic.dm @@ -0,0 +1,17 @@ +/datum/material/steel/holographic + name = "holo" + DEFAULT_WALL_MATERIAL + display_name = DEFAULT_WALL_MATERIAL + stack_type = null + shard_type = SHARD_NONE + +/datum/material/plastic/holographic + name = "holoplastic" + display_name = "plastic" + stack_type = null + shard_type = SHARD_NONE + +/datum/material/wood/holographic + name = "holowood" + display_name = "wood" + stack_type = null + shard_type = SHARD_NONE \ No newline at end of file diff --git a/code/modules/materials/materials/metals/hull.dm b/code/modules/materials/materials/metals/hull.dm new file mode 100644 index 00000000000..caf8f13de74 --- /dev/null +++ b/code/modules/materials/materials/metals/hull.dm @@ -0,0 +1,53 @@ +/datum/material/steel/hull + name = MAT_STEELHULL + stack_type = /obj/item/stack/material/steel/hull + integrity = 250 + explosion_resistance = 10 + icon_base = "hull" + icon_reinf = "reinf_mesh" + icon_colour = "#666677" + +/datum/material/steel/hull/place_sheet(var/turf/target) //Deconstructed into normal steel sheets. + new /obj/item/stack/material/steel(target) + +/datum/material/plasteel/hull + name = MAT_PLASTEELHULL + stack_type = /obj/item/stack/material/plasteel/hull + integrity = 600 + icon_base = "hull" + icon_reinf = "reinf_mesh" + icon_colour = "#777788" + explosion_resistance = 40 + +/datum/material/plasteel/hull/place_sheet(var/turf/target) //Deconstructed into normal plasteel sheets. + new /obj/item/stack/material/plasteel(target) + +/datum/material/durasteel/hull //The 'Hardball' of starship hulls. + name = MAT_DURASTEELHULL + stack_type = /obj/item/stack/material/durasteel/hull + icon_base = "hull" + icon_reinf = "reinf_mesh" + icon_colour = "#45829a" + explosion_resistance = 90 + reflectivity = 0.9 + +/datum/material/durasteel/hull/place_sheet(var/turf/target) //Deconstructed into normal durasteel sheets. + new /obj/item/stack/material/durasteel(target) + +/datum/material/titanium/hull + name = MAT_TITANIUMHULL + stack_type = /obj/item/stack/material/titanium/hull + icon_base = "hull" + icon_reinf = "reinf_mesh" + +/datum/material/titanium/hull/place_sheet(var/turf/target) //Deconstructed into normal titanium sheets. + new /obj/item/stack/material/titanium(target) + +/datum/material/morphium/hull + name = MAT_MORPHIUMHULL + stack_type = /obj/item/stack/material/morphium/hull + icon_base = "hull" + icon_reinf = "reinf_mesh" + +/datum/material/morphium/hull/place_sheet(var/turf/target) + new /obj/item/stack/material/morphium(target) \ No newline at end of file diff --git a/code/modules/materials/materials/metals/hull_vr.dm b/code/modules/materials/materials/metals/hull_vr.dm new file mode 100644 index 00000000000..3c35b3cf398 --- /dev/null +++ b/code/modules/materials/materials/metals/hull_vr.dm @@ -0,0 +1,20 @@ +/datum/material/plastitanium/hull + name = MAT_PLASTITANIUMHULL + stack_type = /obj/item/stack/material/plastitanium/hull + icon_base = "hull" + icon_reinf = "reinf_mesh" + icon_colour = "#585658" + explosion_resistance = 50 + +/datum/material/plastitanium/hull/place_sheet(var/turf/target) //Deconstructed into normal plasteel sheets. + new /obj/item/stack/material/plastitanium(target) + +/datum/material/gold/hull + name = MAT_GOLDHULL + stack_type = /obj/item/stack/material/gold/hull + icon_base = "hull" + icon_reinf = "reinf_mesh" + explosion_resistance = 50 + +/datum/material/gold/hull/place_sheet(var/turf/target) //Deconstructed into normal gold sheets. + new /obj/item/stack/material/gold(target) diff --git a/code/modules/materials/materials/metals/metals.dm b/code/modules/materials/materials/metals/metals.dm new file mode 100644 index 00000000000..a36ffef5c1c --- /dev/null +++ b/code/modules/materials/materials/metals/metals.dm @@ -0,0 +1,199 @@ + + + + +// Very rare alloy that is reflective, should be used sparingly. +/datum/material/durasteel + name = "durasteel" + stack_type = /obj/item/stack/material/durasteel + integrity = 600 + melting_point = 7000 + icon_base = "metal" + icon_reinf = "reinf_metal" + icon_colour = "#6EA7BE" + explosion_resistance = 75 + hardness = 100 + weight = 28 + protectiveness = 60 // 75% + reflectivity = 0.7 // Not a perfect mirror, but close. + stack_origin_tech = list(TECH_MATERIAL = 8) + composite_material = list("plasteel" = SHEET_MATERIAL_AMOUNT, "diamond" = SHEET_MATERIAL_AMOUNT) //shrug + supply_conversion_value = 9 + +/datum/material/titanium + name = MAT_TITANIUM + stack_type = /obj/item/stack/material/titanium + conductivity = 2.38 + icon_base = "metal" + door_icon_base = "metal" + icon_colour = "#D1E6E3" + icon_reinf = "reinf_metal" + composite_material = null + +/datum/material/iron + name = "iron" + stack_type = /obj/item/stack/material/iron + icon_colour = "#5C5454" + weight = 22 + conductivity = 10 + sheet_singular_name = "ingot" + sheet_plural_name = "ingots" + +/datum/material/lead + name = MAT_LEAD + stack_type = /obj/item/stack/material/lead + icon_colour = "#273956" + weight = 23 // Lead is a bit more dense than silver IRL, and silver has 22 ingame. + conductivity = 10 + sheet_singular_name = "ingot" + sheet_plural_name = "ingots" + radiation_resistance = 25 // Lead is Special and so gets to block more radiation than it normally would with just weight, totalling in 48 protection. + supply_conversion_value = 2 + +/datum/material/gold + name = "gold" + stack_type = /obj/item/stack/material/gold + icon_colour = "#EDD12F" + weight = 24 + hardness = 40 + conductivity = 41 + stack_origin_tech = list(TECH_MATERIAL = 4) + sheet_singular_name = "ingot" + sheet_plural_name = "ingots" + supply_conversion_value = 2 + +/datum/material/silver + name = "silver" + stack_type = /obj/item/stack/material/silver + icon_colour = "#D1E6E3" + weight = 22 + hardness = 50 + conductivity = 63 + stack_origin_tech = list(TECH_MATERIAL = 3) + sheet_singular_name = "ingot" + sheet_plural_name = "ingots" + supply_conversion_value = 2 + +/datum/material/platinum + name = "platinum" + stack_type = /obj/item/stack/material/platinum + icon_colour = "#9999FF" + weight = 27 + conductivity = 9.43 + stack_origin_tech = list(TECH_MATERIAL = 2) + sheet_singular_name = "ingot" + sheet_plural_name = "ingots" + supply_conversion_value = 5 + +/datum/material/uranium + name = "uranium" + stack_type = /obj/item/stack/material/uranium + radioactivity = 12 + icon_base = "stone" + icon_reinf = "reinf_stone" + icon_colour = "#007A00" + weight = 22 + stack_origin_tech = list(TECH_MATERIAL = 5) + door_icon_base = "stone" + supply_conversion_value = 2 + +/datum/material/mhydrogen + name = "mhydrogen" + stack_type = /obj/item/stack/material/mhydrogen + icon_colour = "#E6C5DE" + stack_origin_tech = list(TECH_MATERIAL = 6, TECH_POWER = 6, TECH_MAGNET = 5) + conductivity = 100 + is_fusion_fuel = 1 + supply_conversion_value = 6 + +/datum/material/deuterium + name = "deuterium" + stack_type = /obj/item/stack/material/deuterium + icon_colour = "#999999" + stack_origin_tech = list(TECH_MATERIAL = 3) + sheet_singular_name = "ingot" + sheet_plural_name = "ingots" + is_fusion_fuel = 1 + conductive = 0 + +/datum/material/tritium + name = "tritium" + stack_type = /obj/item/stack/material/tritium + icon_colour = "#777777" + stack_origin_tech = list(TECH_MATERIAL = 5) + sheet_singular_name = "ingot" + sheet_plural_name = "ingots" + is_fusion_fuel = 1 + conductive = 0 + +/datum/material/osmium + name = "osmium" + stack_type = /obj/item/stack/material/osmium + icon_colour = "#9999FF" + stack_origin_tech = list(TECH_MATERIAL = 5) + sheet_singular_name = "ingot" + sheet_plural_name = "ingots" + conductivity = 100 + supply_conversion_value = 6 + +/datum/material/graphite + name = MAT_GRAPHITE + stack_type = /obj/item/stack/material/graphite + flags = MATERIAL_BRITTLE + icon_base = "solid" + icon_reinf = "reinf_mesh" + icon_colour = "#333333" + hardness = 75 + weight = 15 + integrity = 175 + protectiveness = 15 + conductivity = 18 + melting_point = T0C+3600 + radiation_resistance = 15 + stack_origin_tech = list(TECH_MATERIAL = 2, TECH_MAGNET = 2) + +/datum/material/bronze + name = "bronze" + stack_type = /obj/item/stack/material/bronze + icon_colour = "#EDD12F" + icon_base = "solid" + icon_reinf = "reinf_over" + integrity = 120 + conductivity = 12 + protectiveness = 9 // 33% + +/datum/material/tin + name = "tin" + display_name = "tin" + use_name = "tin" + stack_type = /obj/item/stack/material/tin + icon_colour = "#b2afaf" + sheet_singular_name = "ingot" + sheet_plural_name = "ingots" + supply_conversion_value = 1 + hardness = 50 + weight = 13 + +/datum/material/copper + name = "copper" + display_name = "copper" + use_name = "copper" + stack_type = /obj/item/stack/material/copper + conductivity = 52 + icon_colour = "#af633e" + sheet_singular_name = "ingot" + sheet_plural_name = "ingots" + supply_conversion_value = 1 + weight = 13 + hardness = 50 + +/datum/material/aluminium + name = "aluminium" + display_name = "aluminium" + use_name = "aluminium" + icon_colour = "#e5e2d0" + stack_type = /obj/item/stack/material/aluminium + sheet_singular_name = "ingot" + sheet_plural_name = "ingots" + supply_conversion_value = 2 + weight = 10 \ No newline at end of file diff --git a/code/modules/materials/materials/metals/metals_vr.dm b/code/modules/materials/materials/metals/metals_vr.dm new file mode 100644 index 00000000000..f600b2fe025 --- /dev/null +++ b/code/modules/materials/materials/metals/metals_vr.dm @@ -0,0 +1,6 @@ +/datum/material/durasteel/generate_recipes() + . = ..() + recipes += list( + new /datum/stack_recipe("durasteel fishing rod", /obj/item/weapon/material/fishing_rod/modern/strong, 2), + new /datum/stack_recipe("whetstone", /obj/item/weapon/whetstone, 2, time = 30), + ) diff --git a/code/modules/materials/materials/metals/plasteel.dm b/code/modules/materials/materials/metals/plasteel.dm new file mode 100644 index 00000000000..6fc7ed29dec --- /dev/null +++ b/code/modules/materials/materials/metals/plasteel.dm @@ -0,0 +1,27 @@ +/datum/material/plasteel + name = "plasteel" + stack_type = /obj/item/stack/material/plasteel + integrity = 400 + melting_point = 6000 + icon_base = "solid" + icon_reinf = "reinf_over" + icon_colour = "#777777" + explosion_resistance = 25 + hardness = 80 + weight = 23 + protectiveness = 20 // 50% + conductivity = 13 // For the purposes of balance. + stack_origin_tech = list(TECH_MATERIAL = 2) + composite_material = list(DEFAULT_WALL_MATERIAL = SHEET_MATERIAL_AMOUNT, "platinum" = SHEET_MATERIAL_AMOUNT) //todo + supply_conversion_value = 6 + +/datum/material/plasteel/generate_recipes() + ..() + recipes += list( + new /datum/stack_recipe("AI core", /obj/structure/AIcore, 4, time = 50, one_per_turf = 1, recycle_material = "[name]"), + new /datum/stack_recipe("Metal crate", /obj/structure/closet/crate, 10, time = 50, one_per_turf = 1, recycle_material = "[name]"), + new /datum/stack_recipe("knife grip", /obj/item/weapon/material/butterflyhandle, 4, time = 20, one_per_turf = 0, on_floor = 1, supplied_material = "[name]"), + new /datum/stack_recipe("dark floor tile", /obj/item/stack/tile/floor/dark, 1, 4, 20, recycle_material = "[name]"), + new /datum/stack_recipe("roller bed", /obj/item/roller, 5, time = 30, on_floor = 1, recycle_material = "[name]"), + new /datum/stack_recipe("whetstone", /obj/item/weapon/whetstone, 2, time = 10, recycle_material = "[name]") + ) \ No newline at end of file diff --git a/code/modules/materials/materials/metals/plasteel_vr.dm b/code/modules/materials/materials/metals/plasteel_vr.dm new file mode 100644 index 00000000000..bca3fdf27b8 --- /dev/null +++ b/code/modules/materials/materials/metals/plasteel_vr.dm @@ -0,0 +1,22 @@ +/datum/material/plastitanium + name = MAT_PLASTITANIUM + stack_type = /obj/item/stack/material/plastitanium + integrity = 600 + melting_point = 9000 + icon_base = "solid" + icon_reinf = "reinf_over" + icon_colour = "#585658" + explosion_resistance = 35 + hardness = 90 + weight = 40 + protectiveness = 30 + conductivity = 7 + stack_origin_tech = list(TECH_MATERIAL = 5) + composite_material = list(MAT_TITANIUM = SHEET_MATERIAL_AMOUNT, MAT_PLASTEEL = SHEET_MATERIAL_AMOUNT) + supply_conversion_value = 8 + +/datum/material/plastitanium/generate_recipes() + ..() + recipes += list( + new /datum/stack_recipe("whetstone", /obj/item/weapon/whetstone, 2, time = 20), + ) diff --git a/code/modules/materials/materials/metals/steel.dm b/code/modules/materials/materials/metals/steel.dm new file mode 100644 index 00000000000..ca323c81374 --- /dev/null +++ b/code/modules/materials/materials/metals/steel.dm @@ -0,0 +1,87 @@ +/datum/material/steel + name = DEFAULT_WALL_MATERIAL + stack_type = /obj/item/stack/material/steel + integrity = 150 + conductivity = 11 // Assuming this is carbon steel, it would actually be slightly less conductive than iron, but lets ignore that. + protectiveness = 10 // 33% + icon_base = "solid" + icon_reinf = "reinf_over" + icon_colour = "#666666" + +/datum/material/steel/generate_recipes() + ..() + recipes += list( + new /datum/stack_recipe_list("office chairs",list( + new /datum/stack_recipe("dark office chair", /obj/structure/bed/chair/office/dark, 5, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), + new /datum/stack_recipe("light office chair", /obj/structure/bed/chair/office/light, 5, one_per_turf = 1, on_floor = 1, recycle_material = "[name]") + )), + new /datum/stack_recipe_list("comfy chairs", list( + new /datum/stack_recipe("beige comfy chair", /obj/structure/bed/chair/comfy/beige, 2, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), + new /datum/stack_recipe("black comfy chair", /obj/structure/bed/chair/comfy/black, 2, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), + new /datum/stack_recipe("brown comfy chair", /obj/structure/bed/chair/comfy/brown, 2, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), + new /datum/stack_recipe("lime comfy chair", /obj/structure/bed/chair/comfy/lime, 2, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), + new /datum/stack_recipe("teal comfy chair", /obj/structure/bed/chair/comfy/teal, 2, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), + new /datum/stack_recipe("red comfy chair", /obj/structure/bed/chair/comfy/red, 2, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), + new /datum/stack_recipe("blue comfy chair", /obj/structure/bed/chair/comfy/blue, 2, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), + new /datum/stack_recipe("purple comfy chair", /obj/structure/bed/chair/comfy/purp, 2, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), + new /datum/stack_recipe("green comfy chair", /obj/structure/bed/chair/comfy/green, 2, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), + new /datum/stack_recipe("yellow comfy chair", /obj/structure/bed/chair/comfy/yellow, 2, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), + new /datum/stack_recipe("orange comfy chair", /obj/structure/bed/chair/comfy/orange, 2, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), + )), + new /datum/stack_recipe_list("airlock assemblies", list( + new /datum/stack_recipe("standard airlock assembly", /obj/structure/door_assembly, 4, time = 50, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), + new /datum/stack_recipe("command airlock assembly", /obj/structure/door_assembly/door_assembly_com, 4, time = 50, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), + new /datum/stack_recipe("security airlock assembly", /obj/structure/door_assembly/door_assembly_sec, 4, time = 50, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), + new /datum/stack_recipe("eng atmos airlock assembly", /obj/structure/door_assembly/door_assembly_eat, 4, time = 50, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), + new /datum/stack_recipe("engineering airlock assembly", /obj/structure/door_assembly/door_assembly_eng, 4, time = 50, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), + new /datum/stack_recipe("mining airlock assembly", /obj/structure/door_assembly/door_assembly_min, 4, time = 50, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), + new /datum/stack_recipe("atmospherics airlock assembly", /obj/structure/door_assembly/door_assembly_atmo, 4, time = 50, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), + new /datum/stack_recipe("research airlock assembly", /obj/structure/door_assembly/door_assembly_research, 4, time = 50, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), + new /datum/stack_recipe("medical airlock assembly", /obj/structure/door_assembly/door_assembly_med, 4, time = 50, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), + new /datum/stack_recipe("maintenance airlock assembly", /obj/structure/door_assembly/door_assembly_mai, 4, time = 50, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), + new /datum/stack_recipe("external airlock assembly", /obj/structure/door_assembly/door_assembly_ext, 4, time = 50, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), + new /datum/stack_recipe("freezer airlock assembly", /obj/structure/door_assembly/door_assembly_fre, 4, time = 50, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), + new /datum/stack_recipe("airtight hatch assembly", /obj/structure/door_assembly/door_assembly_hatch, 4, time = 50, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), + new /datum/stack_recipe("maintenance hatch assembly", /obj/structure/door_assembly/door_assembly_mhatch, 4, time = 50, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), + new /datum/stack_recipe("high security airlock assembly", /obj/structure/door_assembly/door_assembly_highsecurity, 4, time = 50, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), + new /datum/stack_recipe("voidcraft airlock assembly horizontal", /obj/structure/door_assembly/door_assembly_voidcraft, 4, time = 50, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), + new /datum/stack_recipe("voidcraft airlock assembly vertical", /obj/structure/door_assembly/door_assembly_voidcraft/vertical, 4, time = 50, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), + new /datum/stack_recipe("emergency shutter", /obj/structure/firedoor_assembly, 4, time = 50, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), + new /datum/stack_recipe("multi-tile airlock assembly", /obj/structure/door_assembly/multi_tile, 4, time = 50, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), + )), + new /datum/stack_recipe_list("modular computer frames", list( + new /datum/stack_recipe("modular console frame", /obj/item/modular_computer/console, 20, recycle_material = "[name]"),\ + new /datum/stack_recipe("modular telescreen frame", /obj/item/modular_computer/telescreen, 10, recycle_material = "[name]"),\ + new /datum/stack_recipe("modular laptop frame", /obj/item/modular_computer/laptop, 10, recycle_material = "[name]"),\ + new /datum/stack_recipe("modular tablet frame", /obj/item/modular_computer/tablet, 5, recycle_material = "[name]"),\ + )), + new /datum/stack_recipe_list("filing cabinets", list( + new /datum/stack_recipe("filing cabinet", /obj/structure/filingcabinet, 4, time = 20, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), + new /datum/stack_recipe("tall filing cabinet", /obj/structure/filingcabinet/filingcabinet, 4, time = 20, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), + new /datum/stack_recipe("chest drawer", /obj/structure/filingcabinet/chestdrawer, 4, time = 20, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), + )), + new /datum/stack_recipe("table frame", /obj/structure/table, 1, time = 10, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), + new /datum/stack_recipe("bench frame", /obj/structure/table/bench, 1, time = 10, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), + new /datum/stack_recipe("rack", /obj/structure/table/rack, 1, time = 5, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), + new /datum/stack_recipe("closet", /obj/structure/closet, 2, time = 15, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), + new /datum/stack_recipe("canister", /obj/machinery/portable_atmospherics/canister, 10, time = 15, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), + new /datum/stack_recipe("cannon frame", /obj/item/weapon/cannonframe, 10, time = 15, one_per_turf = 0, on_floor = 0, recycle_material = "[name]"), + new /datum/stack_recipe("regular floor tile", /obj/item/stack/tile/floor, 1, 4, 20, recycle_material = "[name]"), + new /datum/stack_recipe("roofing tile", /obj/item/stack/tile/roofing, 3, 4, 20, recycle_material = "[name]"), + new /datum/stack_recipe("metal rod", /obj/item/stack/rods, 1, 2, 60, recycle_material = "[name]"), + new /datum/stack_recipe("frame", /obj/item/frame, 5, time = 25, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), + new /datum/stack_recipe("mirror frame", /obj/item/frame/mirror, 1, time = 5, one_per_turf = 0, on_floor = 1, recycle_material = "[name]"), + new /datum/stack_recipe("fire extinguisher cabinet frame", /obj/item/frame/extinguisher_cabinet, 4, time = 5, one_per_turf = 0, on_floor = 1, recycle_material = "[name]"), + new /datum/stack_recipe("railing", /obj/structure/railing, 2, time = 50, one_per_turf = 0, on_floor = 1, recycle_material = "[name]"), + new /datum/stack_recipe("turret frame", /obj/machinery/porta_turret_construct, 5, time = 25, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), + //new /datum/stack_recipe("IV drip", /obj/machinery/iv_drip, 4, time = 20, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), //VOREStation Removal + new /datum/stack_recipe("medical stand", /obj/structure/medical_stand, 4, time = 20, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), //VOREStation Replacement, + new /datum/stack_recipe("conveyor switch", /obj/machinery/conveyor_switch, 2, time = 20, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"), + new /datum/stack_recipe("grenade casing", /obj/item/weapon/grenade/chem_grenade, recycle_material = "[name]"), + new /datum/stack_recipe("light fixture frame", /obj/item/frame/light, 2, recycle_material = "[name]"), + new /datum/stack_recipe("small light fixture frame", /obj/item/frame/light/small, 1, recycle_material = "[name]"), + new /datum/stack_recipe("floor lamp fixture frame", /obj/machinery/light_construct/flamp, 2, recycle_material = "[name]"), + new /datum/stack_recipe("apc frame", /obj/item/frame/apc, 2, recycle_material = "[name]"), + new /datum/stack_recipe("desk bell", /obj/item/weapon/deskbell, 1, on_floor = 1, supplied_material = "[name]"), + new /datum/stack_recipe("tanning rack", /obj/structure/tanning_rack, 3, one_per_turf = TRUE, time = 20, on_floor = TRUE, supplied_material = "[name]") + ) \ No newline at end of file diff --git a/code/modules/materials/materials/metals/steel_vr.dm b/code/modules/materials/materials/metals/steel_vr.dm new file mode 100644 index 00000000000..b112f362171 --- /dev/null +++ b/code/modules/materials/materials/metals/steel_vr.dm @@ -0,0 +1,82 @@ +/datum/material/steel/generate_recipes() + . = ..() + recipes += list( + new /datum/stack_recipe_list("mounted chairs",list( + new /datum/stack_recipe("mounted chair", /obj/structure/bed/chair/bay/chair, 2, one_per_turf = 1, on_floor = 1, time = 10), + new /datum/stack_recipe("red mounted chair", /obj/structure/bed/chair/bay/chair/padded/red, 2, one_per_turf = 1, on_floor = 1, time = 10), + new /datum/stack_recipe("brown mounted chair", /obj/structure/bed/chair/bay/chair/padded/brown, 2, one_per_turf = 1, on_floor = 1, time = 10), + new /datum/stack_recipe("teal mounted chair", /obj/structure/bed/chair/bay/chair/padded/teal, 2, one_per_turf = 1, on_floor = 1, time = 10), + new /datum/stack_recipe("black mounted chair", /obj/structure/bed/chair/bay/chair/padded/black, 2, one_per_turf = 1, on_floor = 1, time = 10), + new /datum/stack_recipe("green mounted chair", /obj/structure/bed/chair/bay/chair/padded/green, 2, one_per_turf = 1, on_floor = 1, time = 10), + new /datum/stack_recipe("purple mounted chair", /obj/structure/bed/chair/bay/chair/padded/purple, 2, one_per_turf = 1, on_floor = 1, time = 10), + new /datum/stack_recipe("blue mounted chair", /obj/structure/bed/chair/bay/chair/padded/blue, 2, one_per_turf = 1, on_floor = 1, time = 10), + new /datum/stack_recipe("beige mounted chair", /obj/structure/bed/chair/bay/chair/padded/beige, 2, one_per_turf = 1, on_floor = 1, time = 10), + new /datum/stack_recipe("lime mounted chair", /obj/structure/bed/chair/bay/chair/padded/lime, 2, one_per_turf = 1, on_floor = 1, time = 10), + new /datum/stack_recipe("yellow mounted chair", /obj/structure/bed/chair/bay/chair/padded/yellow, 2, one_per_turf = 1, on_floor = 1, time = 10) + )), + new /datum/stack_recipe_list("mounted comfy chairs",list( + new /datum/stack_recipe("mounted comfy chair", /obj/structure/bed/chair/bay/comfy, 3, one_per_turf = 1, on_floor = 1, time = 20), + new /datum/stack_recipe("red mounted comfy chair", /obj/structure/bed/chair/bay/comfy/red, 3, one_per_turf = 1, on_floor = 1, time = 20), + new /datum/stack_recipe("brown mounted comfy chair", /obj/structure/bed/chair/bay/comfy/brown, 3, one_per_turf = 1, on_floor = 1, time = 20), + new /datum/stack_recipe("teal mounted comfy chair", /obj/structure/bed/chair/bay/comfy/teal, 3, one_per_turf = 1, on_floor = 1, time = 20), + new /datum/stack_recipe("black mounted comfy chair", /obj/structure/bed/chair/bay/comfy/black, 3, one_per_turf = 1, on_floor = 1, time = 20), + new /datum/stack_recipe("green mounted comfy chair", /obj/structure/bed/chair/bay/comfy/green, 3, one_per_turf = 1, on_floor = 1, time = 20), + new /datum/stack_recipe("purple mounted comfy chair", /obj/structure/bed/chair/bay/comfy/purple, 3, one_per_turf = 1, on_floor = 1, time = 20), + new /datum/stack_recipe("blue mounted comfy chair", /obj/structure/bed/chair/bay/comfy/blue, 3, one_per_turf = 1, on_floor = 1, time = 20), + new /datum/stack_recipe("beige mounted comfy chair", /obj/structure/bed/chair/bay/comfy/beige, 3, one_per_turf = 1, on_floor = 1, time = 20), + new /datum/stack_recipe("lime mounted comfy chair", /obj/structure/bed/chair/bay/comfy/lime, 3, one_per_turf = 1, on_floor = 1, time = 20), + new /datum/stack_recipe("yellow mounted comfy chair", /obj/structure/bed/chair/bay/comfy/yellow, 3, one_per_turf = 1, on_floor = 1, time = 20) + )), + new /datum/stack_recipe("mounted captain's chair", /obj/structure/bed/chair/bay/comfy/captain, 4, one_per_turf = 1, on_floor = 1, time = 20), + new /datum/stack_recipe("dropship seat", /obj/structure/bed/chair/bay/shuttle, 4, one_per_turf = 1, on_floor = 1, time = 20), + new /datum/stack_recipe("small teshari nest", /obj/structure/bed/chair/bay/chair/padded/red/smallnest, 2, one_per_turf = 1, on_floor = 1, time = 10), + new /datum/stack_recipe("large teshari nest", /obj/structure/bed/chair/bay/chair/padded/red/bignest, 4, one_per_turf = 1, on_floor = 1, time = 20), + new /datum/stack_recipe("dance pole", /obj/structure/dancepole, 2, one_per_turf = 1, on_floor = 1, time = 20), + new /datum/stack_recipe("light switch frame", /obj/item/frame/lightswitch, 2), + new /datum/stack_recipe_list("sofas",list( + new /datum/stack_recipe("red sofa middle", /obj/structure/bed/chair/sofa, 1, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("red sofa left", /obj/structure/bed/chair/sofa/left, 1, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("red sofa right", /obj/structure/bed/chair/sofa/right, 1, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("red sofa corner", /obj/structure/bed/chair/sofa/corner, 1, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("brown sofa middle", /obj/structure/bed/chair/sofa/brown, 1, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("brown sofa left", /obj/structure/bed/chair/sofa/brown/left, 1, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("brown sofa right", /obj/structure/bed/chair/sofa/brown/right, 1, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("brown sofa corner", /obj/structure/bed/chair/sofa/brown/corner, 1, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("teal sofa middle", /obj/structure/bed/chair/sofa/teal, 1, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("teal sofa left", /obj/structure/bed/chair/sofa/teal/left, 1, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("teal sofa right", /obj/structure/bed/chair/sofa/teal/right, 1, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("teal sofa corner", /obj/structure/bed/chair/sofa/teal/corner, 1, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("black sofa middle", /obj/structure/bed/chair/sofa/black, 1, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("black sofa left", /obj/structure/bed/chair/sofa/black/left, 1, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("black sofa right", /obj/structure/bed/chair/sofa/black/right, 1, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("black sofa corner", /obj/structure/bed/chair/sofa/black/corner, 1, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("green sofa middle", /obj/structure/bed/chair/sofa/green, 1, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("green sofa left", /obj/structure/bed/chair/sofa/green/left, 1, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("green sofa right", /obj/structure/bed/chair/sofa/green/right, 1, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("green sofa corner", /obj/structure/bed/chair/sofa/green/corner, 1, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("purple sofa middle", /obj/structure/bed/chair/sofa/purp, 1, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("purple sofa left", /obj/structure/bed/chair/sofa/purp/left, 1, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("purple sofa right", /obj/structure/bed/chair/sofa/purp/right, 1, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("purple sofa corner", /obj/structure/bed/chair/sofa/purp/corner, 1, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("blue sofa middle", /obj/structure/bed/chair/sofa/blue, 1, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("blue sofa left", /obj/structure/bed/chair/sofa/blue/left, 1, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("blue sofa right", /obj/structure/bed/chair/sofa/blue/right, 1, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("blue sofa corner", /obj/structure/bed/chair/sofa/blue/corner, 1, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("beige sofa middle", /obj/structure/bed/chair/sofa/beige, 1, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("beige sofa left", /obj/structure/bed/chair/sofa/beige/left, 1, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("beige sofa right", /obj/structure/bed/chair/sofa/beige/right, 1, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("beige sofa corner", /obj/structure/bed/chair/sofa/beige/corner, 1, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("lime sofa middle", /obj/structure/bed/chair/sofa/lime, 1, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("lime sofa left", /obj/structure/bed/chair/sofa/lime/left, 1, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("lime sofa right", /obj/structure/bed/chair/sofa/lime/right, 1, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("lime sofa corner", /obj/structure/bed/chair/sofa/lime/corner, 1, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("yellow sofa middle", /obj/structure/bed/chair/sofa/yellow, 1, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("yellow sofa left", /obj/structure/bed/chair/sofa/yellow/left, 1, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("yellow sofa right", /obj/structure/bed/chair/sofa/yellow/right, 1, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("yellow sofa corner", /obj/structure/bed/chair/sofa/yellow/corner, 1, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("orange sofa middle", /obj/structure/bed/chair/sofa/orange, 1, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("orange sofa left", /obj/structure/bed/chair/sofa/orange/left, 1, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("orange sofa right", /obj/structure/bed/chair/sofa/orange/right, 1, one_per_turf = 1, on_floor = 1), \ + new /datum/stack_recipe("orange sofa corner", /obj/structure/bed/chair/sofa/orange/corner, 1, one_per_turf = 1, on_floor = 1), \ + )), + ) diff --git a/code/modules/materials/materials/organic/animal_products.dm b/code/modules/materials/materials/organic/animal_products.dm new file mode 100644 index 00000000000..592cc6bc7bb --- /dev/null +++ b/code/modules/materials/materials/organic/animal_products.dm @@ -0,0 +1,28 @@ +/datum/material/diona + name = "biomass" + icon_colour = null + stack_type = null + integrity = 600 + icon_base = "diona" + icon_reinf = "noreinf" + +/datum/material/diona/place_dismantled_product() + return + +/datum/material/diona/place_dismantled_girder(var/turf/target) + spawn_diona_nymph(target) + +/datum/material/chitin + name = MAT_CHITIN + icon_colour = "#8d6653" + stack_type = /obj/item/stack/material/chitin + stack_origin_tech = list(TECH_MATERIAL = 3, TECH_BIO = 4) + icon_base = "solid" + icon_reinf = "reinf_mesh" + integrity = 60 + weight = 10 + ignition_point = T0C+400 + melting_point = T0C+500 + protectiveness = 20 + conductive = 0 + supply_conversion_value = 4 diff --git a/code/modules/materials/materials/organic/cloth.dm b/code/modules/materials/materials/organic/cloth.dm new file mode 100644 index 00000000000..588a7ad86fb --- /dev/null +++ b/code/modules/materials/materials/organic/cloth.dm @@ -0,0 +1,121 @@ +/datum/material/cloth + name = "cloth" + stack_origin_tech = list(TECH_MATERIAL = 2) + door_icon_base = "wood" + ignition_point = T0C+232 + melting_point = T0C+300 + protectiveness = 1 // 4% + flags = MATERIAL_PADDING + conductive = 0 + integrity = 40 + pass_stack_colors = TRUE + supply_conversion_value = 2 + +/datum/material/cloth/generate_recipes() + recipes = list( + new /datum/stack_recipe("woven net", /obj/item/weapon/material/fishing_net, 10, time = 30 SECONDS, pass_stack_color = TRUE, supplied_material = "[name]"), + new /datum/stack_recipe("bedsheet", /obj/item/weapon/bedsheet, 10, time = 30 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("uniform", /obj/item/clothing/under/color/white, 8, time = 15 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("foot wraps", /obj/item/clothing/shoes/footwraps, 2, time = 5 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("gloves", /obj/item/clothing/gloves/white, 2, time = 5 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("wig", /obj/item/clothing/head/powdered_wig, 4, time = 10 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("philosopher's wig", /obj/item/clothing/head/philosopher_wig, 50, time = 2 MINUTES, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("taqiyah", /obj/item/clothing/head/taqiyah, 3, time = 6 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("turban", /obj/item/clothing/head/turban, 3, time = 6 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("hijab", /obj/item/clothing/head/hijab, 3, time = 6 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("kippa", /obj/item/clothing/head/kippa, 3, time = 6 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("scarf", /obj/item/clothing/accessory/scarf/white, 4, time = 5 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("baggy pants", /obj/item/clothing/under/pants/baggy/white, 8, time = 10 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("belt pouch", /obj/item/weapon/storage/belt/fannypack/white, 25, time = 1 MINUTE, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("crude bandage", /obj/item/stack/medical/crude_pack, 1, time = 2 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("empty sandbag", /obj/item/stack/emptysandbag, 2, time = 2 SECONDS, pass_stack_color = TRUE, supplied_material = "[name]") + ) + +/datum/material/cloth/syncloth + name = "syncloth" + stack_origin_tech = list(TECH_MATERIAL = 3, TECH_BIO = 2) + ignition_point = T0C+532 + melting_point = T0C+600 + integrity = 200 + protectiveness = 15 // 4% + pass_stack_colors = TRUE + supply_conversion_value = 3 + +/datum/material/cloth/teal + name = "teal" + display_name ="teal" + use_name = "teal cloth" + icon_colour = "#00EAFA" + +/datum/material/cloth/black + name = "black" + display_name = "black" + use_name = "black cloth" + icon_colour = "#505050" + +/datum/material/cloth/green + name = "green" + display_name = "green" + use_name = "green cloth" + icon_colour = "#01C608" + +/datum/material/cloth/puple + name = "purple" + display_name = "purple" + use_name = "purple cloth" + icon_colour = "#9C56C4" + +/datum/material/cloth/blue + name = "blue" + display_name = "blue" + use_name = "blue cloth" + icon_colour = "#6B6FE3" + +/datum/material/cloth/beige + name = "beige" + display_name = "beige" + use_name = "beige cloth" + icon_colour = "#E8E7C8" + +/datum/material/cloth/lime + name = "lime" + display_name = "lime" + use_name = "lime cloth" + icon_colour = "#62E36C" + +/datum/material/cloth/yellow + name = "yellow" + display_name = "yellow" + use_name = "yellow cloth" + icon_colour = "#EEF573" + +/datum/material/cloth/orange + name = "orange" + display_name = "orange" + use_name = "orange cloth" + icon_colour = "#E3BF49" + + + +/datum/material/carpet + name = "carpet" + display_name = "comfy" + use_name = "red upholstery" + icon_colour = "#DA020A" + flags = MATERIAL_PADDING + ignition_point = T0C+232 + melting_point = T0C+300 + sheet_singular_name = "tile" + sheet_plural_name = "tiles" + protectiveness = 1 // 4% + conductive = 0 + +/datum/material/cotton + name = "cotton" + display_name ="cotton" + icon_colour = "#FFFFFF" + flags = MATERIAL_PADDING + ignition_point = T0C+232 + melting_point = T0C+300 + protectiveness = 1 // 4% + conductive = 0 \ No newline at end of file diff --git a/code/modules/materials/materials/organic/leather.dm b/code/modules/materials/materials/organic/leather.dm new file mode 100644 index 00000000000..f5fc8cb2f97 --- /dev/null +++ b/code/modules/materials/materials/organic/leather.dm @@ -0,0 +1,37 @@ +/datum/material/leather + name = MAT_LEATHER + display_name = "plainleather" + icon_colour = "#5C4831" + stack_type = /obj/item/stack/material/leather + stack_origin_tech = list(TECH_MATERIAL = 2, TECH_BIO = 2) + flags = MATERIAL_PADDING + ignition_point = T0C+300 + melting_point = T0C+300 + protectiveness = 3 // 13% + conductive = 0 + integrity = 40 + supply_conversion_value = 3 + +/datum/material/leather/generate_recipes() + recipes = list( + new /datum/stack_recipe("bedsheet", /obj/item/weapon/bedsheet, 10, time = 30 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("uniform", /obj/item/clothing/under/color/white, 8, time = 15 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("foot wraps", /obj/item/clothing/shoes/footwraps, 2, time = 5 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("gloves", /obj/item/clothing/gloves/white, 2, time = 5 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("wig", /obj/item/clothing/head/powdered_wig, 4, time = 10 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("philosopher's wig", /obj/item/clothing/head/philosopher_wig, 50, time = 2 MINUTES, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("taqiyah", /obj/item/clothing/head/taqiyah, 3, time = 6 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("turban", /obj/item/clothing/head/turban, 3, time = 6 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("hijab", /obj/item/clothing/head/hijab, 3, time = 6 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("kippa", /obj/item/clothing/head/kippa, 3, time = 6 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("scarf", /obj/item/clothing/accessory/scarf/white, 4, time = 5 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("baggy pants", /obj/item/clothing/under/pants/baggy/white, 8, time = 10 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("belt pouch", /obj/item/weapon/storage/belt/fannypack/white, 25, time = 1 MINUTE, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("crude [display_name] bandage", /obj/item/stack/medical/crude_pack, 1, time = 2 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("[display_name] net", /obj/item/weapon/material/fishing_net, 10, time = 5 SECONDS, supplied_material = "[name]", pass_stack_color = TRUE), + new /datum/stack_recipe("[display_name] ring", /obj/item/clothing/gloves/ring/material, 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE), + new /datum/stack_recipe("[display_name] bracelet", /obj/item/clothing/accessory/bracelet/material, 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE), + new /datum/stack_recipe("[display_name] armor plate", /obj/item/weapon/material/armor_plating, 1, time = 20, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE), + new /datum/stack_recipe("empty sandbag", /obj/item/stack/emptysandbag, 2, time = 2 SECONDS, pass_stack_color = TRUE, supplied_material = "[name]"), + new /datum/stack_recipe("whip", /obj/item/weapon/material/whip, 5, time = 15 SECONDS, pass_stack_color = TRUE, supplied_material = "[name]") + ) \ No newline at end of file diff --git a/code/modules/materials/materials/organic/resin.dm b/code/modules/materials/materials/organic/resin.dm new file mode 100644 index 00000000000..a42735627aa --- /dev/null +++ b/code/modules/materials/materials/organic/resin.dm @@ -0,0 +1,45 @@ +/datum/material/resin + name = "resin" + icon_colour = "#35343a" + icon_base = "resin" + dooropen_noise = 'sound/effects/attackblob.ogg' + door_icon_base = "resin" + icon_reinf = "reinf_mesh" + melting_point = T0C+300 + sheet_singular_name = "blob" + sheet_plural_name = "blobs" + conductive = 0 + explosion_resistance = 60 + radiation_resistance = 10 + stack_origin_tech = list(TECH_MATERIAL = 8, TECH_PHORON = 4, TECH_BLUESPACE = 4, TECH_BIO = 7) + stack_type = /obj/item/stack/material/resin + +/datum/material/resin/can_open_material_door(var/mob/living/user) + var/mob/living/carbon/M = user + if(istype(M) && locate(/obj/item/organ/internal/xenos/hivenode) in M.internal_organs) + return TRUE + return FALSE + +/datum/material/resin/wall_touch_special(var/turf/simulated/wall/W, var/mob/living/L) + var/mob/living/carbon/M = L + if(istype(M) && locate(/obj/item/organ/internal/xenos/hivenode) in M.internal_organs) + to_chat(M, "\The [W] shudders under your touch, starting to become porous.") + playsound(W, 'sound/effects/attackblob.ogg', 50, 1) + if(do_after(L, 5 SECONDS)) + spawn(2) + playsound(W, 'sound/effects/attackblob.ogg', 100, 1) + W.dismantle_wall() + return TRUE + return FALSE + +/datum/material/resin/generate_recipes() + recipes = list( + new /datum/stack_recipe("[display_name] door", /obj/structure/simple_door/resin, 10, one_per_turf = 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE), + new /datum/stack_recipe("[display_name] barricade", /obj/effect/alien/resin/wall, 5, time = 5 SECONDS, one_per_turf = 1, on_floor = 1, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("[display_name] nest", /obj/structure/bed/nest, 2, one_per_turf = 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE), + new /datum/stack_recipe("[display_name] wall girders", /obj/structure/girder/resin, 2, time = 5 SECONDS, one_per_turf = 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE), + new /datum/stack_recipe("crude [display_name] bandage", /obj/item/stack/medical/crude_pack, 1, time = 2 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("[display_name] net", /obj/item/weapon/material/fishing_net, 10, time = 5 SECONDS, supplied_material = "[name]", pass_stack_color = TRUE), + new /datum/stack_recipe("[display_name] membrane", /obj/effect/alien/resin/membrane, 1, time = 2 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("[display_name] node", /obj/effect/alien/weeds/node, 1, time = 4 SECONDS, recycle_material = "[name]") + ) \ No newline at end of file diff --git a/code/modules/materials/materials/organic/wood.dm b/code/modules/materials/materials/organic/wood.dm new file mode 100644 index 00000000000..ecdad547ca5 --- /dev/null +++ b/code/modules/materials/materials/organic/wood.dm @@ -0,0 +1,84 @@ +/datum/material/wood + name = MAT_WOOD + stack_type = /obj/item/stack/material/wood + icon_colour = "#9c5930" + integrity = 50 + icon_base = "wood" + explosion_resistance = 2 + shard_type = SHARD_SPLINTER + shard_can_repair = 0 // you can't weld splinters back into planks + hardness = 15 + weight = 18 + protectiveness = 8 // 28% + conductive = 0 + conductivity = 1 + melting_point = T0C+300 //okay, not melting in this case, but hot enough to destroy wood + ignition_point = T0C+288 + stack_origin_tech = list(TECH_MATERIAL = 1, TECH_BIO = 1) + dooropen_noise = 'sound/effects/doorcreaky.ogg' + door_icon_base = "wood" + destruction_desc = "splinters" + sheet_singular_name = "plank" + sheet_plural_name = "planks" + +/datum/material/wood/generate_recipes() + ..() + recipes += list( + new /datum/stack_recipe("oar", /obj/item/weapon/oar, 2, time = 30, supplied_material = "[name]", pass_stack_color = TRUE), + new /datum/stack_recipe("boat", /obj/vehicle/boat, 20, time = 10 SECONDS, supplied_material = "[name]", pass_stack_color = TRUE), + new /datum/stack_recipe("dragon boat", /obj/vehicle/boat/dragon, 50, time = 30 SECONDS, supplied_material = "[name]", pass_stack_color = TRUE), + new /datum/stack_recipe("wooden sandals", /obj/item/clothing/shoes/sandal, 1, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("wood circlet", /obj/item/clothing/head/woodcirclet, 1, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("clipboard", /obj/item/weapon/clipboard, 1, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("wood floor tile", /obj/item/stack/tile/wood, 1, 4, 20, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("wooden chair", /obj/structure/bed/chair/wood, 3, time = 10, one_per_turf = 1, on_floor = 1, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("crossbow frame", /obj/item/weapon/crossbowframe, 5, time = 25, one_per_turf = 0, on_floor = 0, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("coffin", /obj/structure/closet/coffin, 5, time = 15, one_per_turf = 1, on_floor = 1, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("beehive assembly", /obj/item/beehive_assembly, 4, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("beehive frame", /obj/item/honey_frame, 1, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("book shelf", /obj/structure/bookcase, 5, time = 15, one_per_turf = 1, on_floor = 1, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("noticeboard frame", /obj/item/frame/noticeboard, 4, time = 5, one_per_turf = 0, on_floor = 1, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("wooden bucket", /obj/item/weapon/reagent_containers/glass/bucket/wood, 2, time = 4, one_per_turf = 0, on_floor = 0, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("coilgun stock", /obj/item/weapon/coilgun_assembly, 5, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("crude fishing rod", /obj/item/weapon/material/fishing_rod/built, 8, time = 10 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("wooden standup figure", /obj/structure/barricade/cutout, 5, time = 10 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]"), //VOREStation Add + new /datum/stack_recipe("noticeboard", /obj/structure/noticeboard, 1, recycle_material = "[name]"), + new /datum/stack_recipe("tanning rack", /obj/structure/tanning_rack, 3, one_per_turf = TRUE, time = 20, on_floor = TRUE, supplied_material = "[name]") + ) + +/datum/material/wood/sif + name = MAT_SIFWOOD + stack_type = /obj/item/stack/material/wood/sif + icon_colour = "#0099cc" // Cyan-ish + stack_origin_tech = list(TECH_MATERIAL = 2, TECH_BIO = 2) // Alien wood would presumably be more interesting to the analyzer. + +/datum/material/wood/sif/generate_recipes() + ..() + recipes += new /datum/stack_recipe("alien wood floor tile", /obj/item/stack/tile/wood/sif, 1, 4, 20, pass_stack_color = TRUE) + for(var/datum/stack_recipe/r_recipe in recipes) + if(r_recipe.title == "wood floor tile") + recipes -= r_recipe + continue + if(r_recipe.title == "wooden chair") + recipes -= r_recipe + continue + +/datum/material/wood/log + name = MAT_LOG + icon_base = "log" + stack_type = /obj/item/stack/material/log + sheet_singular_name = null + sheet_plural_name = "pile" + pass_stack_colors = TRUE + supply_conversion_value = 1 + +/datum/material/wood/log/generate_recipes() + recipes = list( + new /datum/stack_recipe("bonfire", /obj/structure/bonfire, 5, time = 50, supplied_material = "[name]", pass_stack_color = TRUE, recycle_material = "[name]") + ) + +/datum/material/wood/log/sif + name = MAT_SIFLOG + icon_colour = "#0099cc" // Cyan-ish + stack_origin_tech = list(TECH_MATERIAL = 2, TECH_BIO = 2) + stack_type = /obj/item/stack/material/log/sif \ No newline at end of file diff --git a/code/modules/materials/materials/other_vr.dm b/code/modules/materials/materials/other_vr.dm new file mode 100644 index 00000000000..d54dd4f726e --- /dev/null +++ b/code/modules/materials/materials/other_vr.dm @@ -0,0 +1,32 @@ +/datum/material/flesh + name = "flesh" + display_name = "chunk of flesh" + icon_colour = "#dd90aa" + sheet_singular_name = "meat" + sheet_plural_name = "meats" + integrity = 1200 + melting_point = 6000 + explosion_resistance = 200 + hardness = 500 + weight = 500 + +/datum/material/fluff //This is to allow for 2 handed weapons that don't want to have a prefix. + name = " " + display_name = "" + icon_colour = "#000000" + sheet_singular_name = "fluff" + sheet_plural_name = "fluffs" + hardness = 60 + weight = 20 //Strong as iron. + +/datum/material/darkglass + name = "darkglass" + display_name = "darkglass" + icon_base = "darkglass" + icon_colour = "#FFFFFF" + +/datum/material/fancyblack + name = "fancyblack" + display_name = "fancyblack" + icon_base = "fancyblack" + icon_colour = "#FFFFFF" diff --git a/code/modules/materials/materials/plastic.dm b/code/modules/materials/materials/plastic.dm new file mode 100644 index 00000000000..6cf45fe677e --- /dev/null +++ b/code/modules/materials/materials/plastic.dm @@ -0,0 +1,88 @@ +/datum/material/plastic + name = "plastic" + stack_type = /obj/item/stack/material/plastic + flags = MATERIAL_BRITTLE + icon_base = "solid" + icon_reinf = "reinf_over" + icon_colour = "#CCCCCC" + hardness = 10 + weight = 12 + protectiveness = 5 // 20% + conductive = 0 + conductivity = 2 // For the sake of material armor diversity, we're gonna pretend this plastic is a good insulator. + melting_point = T0C+371 //assuming heat resistant plastic + stack_origin_tech = list(TECH_MATERIAL = 3) + +/datum/material/plastic/generate_recipes() + ..() + recipes += list( + new /datum/stack_recipe("plastic crate", /obj/structure/closet/crate/plastic, 10, one_per_turf = 1, on_floor = 1, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("plastic bag", /obj/item/weapon/storage/bag/plasticbag, 3, on_floor = 1, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("blood pack", /obj/item/weapon/reagent_containers/blood/empty, 4, on_floor = 0, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("reagent dispenser cartridge (large)", /obj/item/weapon/reagent_containers/chem_disp_cartridge, 5, on_floor=0, pass_stack_color = TRUE, recycle_material = "[name]"), // 500u + new /datum/stack_recipe("reagent dispenser cartridge (med)", /obj/item/weapon/reagent_containers/chem_disp_cartridge/medium, 3, on_floor=0, pass_stack_color = TRUE, recycle_material = "[name]"), // 250u + new /datum/stack_recipe("reagent dispenser cartridge (small)", /obj/item/weapon/reagent_containers/chem_disp_cartridge/small, 1, on_floor=0, pass_stack_color = TRUE, recycle_material = "[name]"), // 100u + new /datum/stack_recipe("white floor tile", /obj/item/stack/tile/floor/white, 1, 4, 20, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("freezer floor tile", /obj/item/stack/tile/floor/freezer, 1, 4, 20, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("shower curtain", /obj/structure/curtain, 4, time = 15, one_per_turf = 1, on_floor = 1, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("plastic flaps", /obj/structure/plasticflaps, 4, time = 25, one_per_turf = 1, on_floor = 1, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("water-cooler", /obj/structure/reagent_dispensers/water_cooler, 4, time = 10, one_per_turf = 1, on_floor = 1, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("lampshade", /obj/item/weapon/lampshade, 1, time = 1, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("plastic net", /obj/item/weapon/material/fishing_net, 25, time = 1 MINUTE, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("plastic fishtank", /obj/item/glass_jar/fish/plastic, 2, time = 30 SECONDS, recycle_material = "[name]"), + new /datum/stack_recipe("reagent tubing", /obj/item/stack/hose, 1, 4, 20, pass_stack_color = TRUE, recycle_material = "[name]") + ) + +/datum/material/cardboard + name = "cardboard" + stack_type = /obj/item/stack/material/cardboard + flags = MATERIAL_BRITTLE + integrity = 10 + icon_base = "solid" + icon_reinf = "reinf_over" + icon_colour = "#AAAAAA" + hardness = 1 + weight = 1 + protectiveness = 0 // 0% + conductive = 0 + ignition_point = T0C+232 //"the temperature at which book-paper catches fire, and burns." close enough + melting_point = T0C+232 //temperature at which cardboard walls would be destroyed + stack_origin_tech = list(TECH_MATERIAL = 1) + door_icon_base = "wood" + destruction_desc = "crumples" + radiation_resistance = 1 + pass_stack_colors = TRUE + +/datum/material/cardboard/generate_recipes() + ..() + recipes += list( + new /datum/stack_recipe("box", /obj/item/weapon/storage/box, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("donut box", /obj/item/weapon/storage/box/donut/empty, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("egg box", /obj/item/weapon/storage/fancy/egg_box, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("light tubes box", /obj/item/weapon/storage/box/lights/tubes, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("light bulbs box", /obj/item/weapon/storage/box/lights/bulbs, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("mouse traps box", /obj/item/weapon/storage/box/mousetraps, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("cardborg suit", /obj/item/clothing/suit/cardborg, 3, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("cardborg helmet", /obj/item/clothing/head/cardborg, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("pizza box", /obj/item/pizzabox, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe_list("folders",list( + new /datum/stack_recipe("blue folder", /obj/item/weapon/folder/blue, recycle_material = "[name]"), + new /datum/stack_recipe("grey folder", /obj/item/weapon/folder, recycle_material = "[name]"), + new /datum/stack_recipe("red folder", /obj/item/weapon/folder/red, recycle_material = "[name]"), + new /datum/stack_recipe("white folder", /obj/item/weapon/folder/white, recycle_material = "[name]"), + new /datum/stack_recipe("yellow folder", /obj/item/weapon/folder/yellow, recycle_material = "[name]") + )) + ) + +/datum/material/toy_foam + name = "foam" + display_name = "foam" + use_name = "foam" + flags = MATERIAL_PADDING + ignition_point = T0C+232 + melting_point = T0C+300 + icon_colour = "#ff9900" + hardness = 1 + weight = 1 + protectiveness = 0 // 0% + conductive = 0 \ No newline at end of file diff --git a/code/modules/materials/materials/snow.dm b/code/modules/materials/materials/snow.dm new file mode 100644 index 00000000000..bd535798118 --- /dev/null +++ b/code/modules/materials/materials/snow.dm @@ -0,0 +1,56 @@ +/datum/material/snow + name = MAT_SNOW + stack_type = /obj/item/stack/material/snow + flags = MATERIAL_BRITTLE + icon_base = "solid" + icon_reinf = "reinf_over" + icon_colour = "#FFFFFF" + integrity = 1 + hardness = 1 + weight = 1 + protectiveness = 0 // 0% + stack_origin_tech = list(TECH_MATERIAL = 1) + melting_point = T0C+1 + destruction_desc = "crumples" + sheet_singular_name = "pile" + sheet_plural_name = "pile" //Just a bigger pile + radiation_resistance = 1 + +/datum/material/snow/generate_recipes() + recipes = list( + new /datum/stack_recipe("snowball", /obj/item/weapon/material/snow/snowball, 1, time = 10, recycle_material = "[name]"), + new /datum/stack_recipe("snow brick", /obj/item/stack/material/snowbrick, 2, time = 10, recycle_material = "[name]"), + new /datum/stack_recipe("snowman", /obj/structure/snowman, 2, time = 15, recycle_material = "[name]"), + new /datum/stack_recipe("snow robot", /obj/structure/snowman/borg, 2, time = 10, recycle_material = "[name]"), + new /datum/stack_recipe("snow spider", /obj/structure/snowman/spider, 3, time = 20, recycle_material = "[name]") + ) + +/datum/material/snowbrick //only slightly stronger than snow, used to make igloos mostly + name = "packed snow" + flags = MATERIAL_BRITTLE + stack_type = /obj/item/stack/material/snowbrick + icon_base = "stone" + icon_reinf = "reinf_stone" + icon_colour = "#D8FDFF" + integrity = 50 + weight = 2 + hardness = 2 + protectiveness = 0 // 0% + stack_origin_tech = list(TECH_MATERIAL = 1) + melting_point = T0C+1 + destruction_desc = "crumbles" + sheet_singular_name = "brick" + sheet_plural_name = "bricks" + radiation_resistance = 1 + +/datum/material/snowbrick/generate_recipes() + recipes = list( + new /datum/stack_recipe("[display_name] door", /obj/structure/simple_door, 10, one_per_turf = 1, on_floor = 1, supplied_material = "[name]"), + new /datum/stack_recipe("[display_name] barricade", /obj/structure/barricade, 5, time = 50, one_per_turf = 1, on_floor = 1, supplied_material = "[name]"), + new /datum/stack_recipe("[display_name] stool", /obj/item/weapon/stool, one_per_turf = 1, on_floor = 1, supplied_material = "[name]"), + new /datum/stack_recipe("[display_name] chair", /obj/structure/bed/chair, one_per_turf = 1, on_floor = 1, supplied_material = "[name]"), + new /datum/stack_recipe("[display_name] bed", /obj/structure/bed, 2, one_per_turf = 1, on_floor = 1, supplied_material = "[name]"), + new /datum/stack_recipe("[display_name] double bed", /obj/structure/bed/double, 4, one_per_turf = 1, on_floor = 1, supplied_material = "[name]"), + new /datum/stack_recipe("[display_name] wall girders", /obj/structure/girder, 2, time = 50, one_per_turf = 1, on_floor = 1, supplied_material = "[name]"), + new /datum/stack_recipe("[display_name] ashtray", /obj/item/weapon/material/ashtray, 2, one_per_turf = 1, on_floor = 1, supplied_material = "[name]") + ) \ No newline at end of file diff --git a/code/modules/materials/materials/stone.dm b/code/modules/materials/materials/stone.dm new file mode 100644 index 00000000000..823dd19914c --- /dev/null +++ b/code/modules/materials/materials/stone.dm @@ -0,0 +1,35 @@ +/datum/material/stone + name = "sandstone" + stack_type = /obj/item/stack/material/sandstone + icon_base = "stone" + icon_reinf = "reinf_stone" + icon_colour = "#D9C179" + shard_type = SHARD_STONE_PIECE + weight = 22 + hardness = 55 + protectiveness = 5 // 20% + conductive = 0 + conductivity = 5 + door_icon_base = "stone" + sheet_singular_name = "brick" + sheet_plural_name = "bricks" + +/datum/material/stone/generate_recipes() + ..() + recipes += new /datum/stack_recipe("planting bed", /obj/machinery/portable_atmospherics/hydroponics/soil, 3, time = 10, one_per_turf = 1, on_floor = 1, recycle_material = "[name]") + +/datum/material/stone/marble + name = "marble" + icon_colour = "#AAAAAA" + weight = 26 + hardness = 30 //VOREStation Edit - Please. + integrity = 201 //hack to stop kitchen benches being flippable, todo: refactor into weight system + stack_type = /obj/item/stack/material/marble + supply_conversion_value = 2 + +/datum/material/stone/marble/generate_recipes() + ..() + recipes += list( + new /datum/stack_recipe("light marble floor tile", /obj/item/stack/tile/wmarble, 1, 4, 20, recycle_material = "[name]"), + new /datum/stack_recipe("dark marble floor tile", /obj/item/stack/tile/bmarble, 1, 4, 20, recycle_material = "[name]") + ) \ No newline at end of file diff --git a/code/modules/materials/materials/supermatter.dm b/code/modules/materials/materials/supermatter.dm new file mode 100644 index 00000000000..5ee3b34671c --- /dev/null +++ b/code/modules/materials/materials/supermatter.dm @@ -0,0 +1,23 @@ +//R-UST port +/datum/material/supermatter + name = "supermatter" + icon_colour = "#FFFF00" + stack_type = /obj/item/stack/material/supermatter + shard_type = SHARD_SHARD + radioactivity = 20 + stack_type = null + luminescence = 3 + ignition_point = PHORON_MINIMUM_BURN_TEMPERATURE + icon_base = "stone" + shard_type = SHARD_SHARD + hardness = 30 + door_icon_base = "stone" + sheet_singular_name = "crystal" + sheet_plural_name = "crystals" + is_fusion_fuel = 1 + stack_origin_tech = list(TECH_MATERIAL = 8, TECH_PHORON = 5, TECH_BLUESPACE = 4) + +/datum/material/supermatter/generate_recipes() + recipes = list( + new /datum/stack_recipe("supermatter shard", /obj/machinery/power/supermatter/shard, 30 , one_per_turf = 1, time = 600, on_floor = 1, recycle_material = "[name]") + ) \ No newline at end of file diff --git a/code/modules/materials/materials_vr.dm b/code/modules/materials/materials_vr.dm deleted file mode 100644 index e66f1ebfa85..00000000000 --- a/code/modules/materials/materials_vr.dm +++ /dev/null @@ -1,104 +0,0 @@ -/datum/material/flesh - name = "flesh" - display_name = "chunk of flesh" - icon_colour = "#dd90aa" - sheet_singular_name = "meat" - sheet_plural_name = "meats" - integrity = 1200 - melting_point = 6000 - explosion_resistance = 200 - hardness = 500 - weight = 500 - -/datum/material/fluff //This is to allow for 2 handed weapons that don't want to have a prefix. - name = " " - display_name = "" - icon_colour = "#000000" - sheet_singular_name = "fluff" - sheet_plural_name = "fluffs" - hardness = 60 - weight = 20 //Strong as iron. - -/datum/material/darkglass - name = "darkglass" - display_name = "darkglass" - icon_base = "darkglass" - icon_colour = "#FFFFFF" - -/datum/material/fancyblack - name = "fancyblack" - display_name = "fancyblack" - icon_base = "fancyblack" - icon_colour = "#FFFFFF" - -/datum/material/glass/titaniumglass - name = MAT_TITANIUMGLASS - display_name = "titanium glass" - stack_type = /obj/item/stack/material/glass/titanium - integrity = 150 - hardness = 50 - weight = 50 - flags = MATERIAL_BRITTLE - icon_colour = "#A7A3A6" - stack_origin_tech = list(TECH_MATERIAL = 5) - window_options = list("One Direction" = 1, "Full Window" = 4) - created_window = /obj/structure/window/titanium - created_fulltile_window = /obj/structure/window/titanium/full - wire_product = null - rod_product = /obj/item/stack/material/glass/titanium - composite_material = list(MAT_TITANIUM = SHEET_MATERIAL_AMOUNT, "glass" = SHEET_MATERIAL_AMOUNT) - -/datum/material/plastitanium - name = MAT_PLASTITANIUM - stack_type = /obj/item/stack/material/plastitanium - integrity = 600 - melting_point = 9000 - icon_base = "solid" - icon_reinf = "reinf_over" - icon_colour = "#585658" - explosion_resistance = 35 - hardness = 90 - weight = 40 - protectiveness = 30 - conductivity = 7 - stack_origin_tech = list(TECH_MATERIAL = 5) - composite_material = list(MAT_TITANIUM = SHEET_MATERIAL_AMOUNT, MAT_PLASTEEL = SHEET_MATERIAL_AMOUNT) - supply_conversion_value = 8 - -/datum/material/plastitanium/hull - name = MAT_PLASTITANIUMHULL - stack_type = /obj/item/stack/material/plastitanium/hull - icon_base = "hull" - icon_reinf = "reinf_mesh" - icon_colour = "#585658" - explosion_resistance = 50 - -/datum/material/plastitanium/hull/place_sheet(var/turf/target) //Deconstructed into normal plasteel sheets. - new /obj/item/stack/material/plastitanium(target) - -/datum/material/glass/plastaniumglass - name = MAT_PLASTITANIUMGLASS - display_name = "plas-titanium glass" - stack_type = /obj/item/stack/material/glass/plastitanium - integrity = 200 - hardness = 60 - weight = 80 - flags = MATERIAL_BRITTLE - icon_colour = "#676366" - stack_origin_tech = list(TECH_MATERIAL = 6) - window_options = list("One Direction" = 1, "Full Window" = 4) - created_window = /obj/structure/window/plastitanium - created_fulltile_window = /obj/structure/window/plastitanium/full - wire_product = null - rod_product = /obj/item/stack/material/glass/plastitanium - composite_material = list(MAT_PLASTITANIUM = SHEET_MATERIAL_AMOUNT, "glass" = SHEET_MATERIAL_AMOUNT) - -/datum/material/gold/hull - name = MAT_GOLDHULL - stack_type = /obj/item/stack/material/gold/hull - icon_base = "hull" - icon_reinf = "reinf_mesh" - explosion_resistance = 50 - -/datum/material/gold/hull/place_sheet(var/turf/target) //Deconstructed into normal plasteel sheets. - new /obj/item/stack/material/gold(target) \ No newline at end of file diff --git a/code/modules/materials/sheets/_sheets.dm b/code/modules/materials/sheets/_sheets.dm new file mode 100644 index 00000000000..7572d0e6545 --- /dev/null +++ b/code/modules/materials/sheets/_sheets.dm @@ -0,0 +1,89 @@ +// Stacked resources. They use a material datum for a lot of inherited values. +// If you're adding something here, make sure to add it to fifty_spawner_mats.dm as well +/obj/item/stack/material + force = 5.0 + throwforce = 5 + w_class = ITEMSIZE_NORMAL + throw_speed = 3 + throw_range = 3 + center_of_mass = null + max_amount = 50 + item_icons = list( + slot_l_hand_str = 'icons/mob/items/lefthand_material.dmi', + slot_r_hand_str = 'icons/mob/items/righthand_material.dmi', + ) + + var/default_type = DEFAULT_WALL_MATERIAL + var/datum/material/material + var/perunit = SHEET_MATERIAL_AMOUNT + var/apply_colour //temp pending icon rewrite + drop_sound = 'sound/items/drop/axe.ogg' + pickup_sound = 'sound/items/pickup/axe.ogg' + +/obj/item/stack/material/Initialize() + . = ..() + + randpixel_xy() + + if(!default_type) + default_type = DEFAULT_WALL_MATERIAL + material = get_material_by_name("[default_type]") + if(!material) + return INITIALIZE_HINT_QDEL + + recipes = material.get_recipes() + stacktype = material.stack_type + if(islist(material.stack_origin_tech)) + origin_tech = material.stack_origin_tech.Copy() + + if(apply_colour) + color = material.icon_colour + + if(!material.conductive) + flags |= NOCONDUCT + + matter = material.get_matter() + update_strings() + +/obj/item/stack/material/get_material() + return material + +/obj/item/stack/material/proc/update_strings() + // Update from material datum. + singular_name = material.sheet_singular_name + + if(amount>1) + name = "[material.use_name] [material.sheet_plural_name]" + desc = "A stack of [material.use_name] [material.sheet_plural_name]." + gender = PLURAL + else + name = "[material.use_name] [material.sheet_singular_name]" + desc = "A [material.sheet_singular_name] of [material.use_name]." + gender = NEUTER + +/obj/item/stack/material/use(var/used) + . = ..() + update_strings() + return + +/obj/item/stack/material/transfer_to(obj/item/stack/S, var/tamount=null, var/type_verified) + var/obj/item/stack/material/M = S + if(!istype(M) || material.name != M.material.name) + return 0 + var/transfer = ..(S,tamount,1) + if(src) update_strings() + if(M) M.update_strings() + return transfer + +/obj/item/stack/material/attack_self(var/mob/user) + if(!material.build_windows(user, src)) + ..() + +/obj/item/stack/material/attackby(var/obj/item/W, var/mob/user) + if(istype(W,/obj/item/stack/cable_coil)) + material.build_wired_product(user, W, src) + return + else if(istype(W, /obj/item/stack/rods)) + material.build_rod_product(user, W, src) + return + return ..() \ No newline at end of file diff --git a/code/modules/materials/sheets/gems.dm b/code/modules/materials/sheets/gems.dm new file mode 100644 index 00000000000..1906da8eab0 --- /dev/null +++ b/code/modules/materials/sheets/gems.dm @@ -0,0 +1,66 @@ +/obj/item/stack/material/phoron + name = "solid phoron" + icon_state = "sheet-phoron" + default_type = "phoron" + no_variants = FALSE + drop_sound = 'sound/items/drop/glass.ogg' + pickup_sound = 'sound/items/pickup/glass.ogg' + +/obj/item/stack/material/diamond + name = "diamond" + icon_state = "sheet-diamond" + default_type = "diamond" + drop_sound = 'sound/items/drop/glass.ogg' + pickup_sound = 'sound/items/pickup/glass.ogg' + +/obj/item/stack/material/painite + name = "painite" + icon_state = "sheet-gem" + singular_name = "painite gem" + default_type = "painite" + apply_colour = 1 + no_variants = FALSE + +/obj/item/stack/material/void_opal + name = "void opal" + icon_state = "sheet-void_opal" + singular_name = "void opal" + default_type = "void opal" + apply_colour = 1 + no_variants = FALSE + +/obj/item/stack/material/quartz + name = "quartz" + icon_state = "sheet-gem" + singular_name = "quartz gem" + default_type = "quartz" + apply_colour = 1 + no_variants = FALSE + +/obj/item/stack/material/valhollide + name = MAT_VALHOLLIDE + icon_state = "sheet-gem" + item_state = "diamond" + default_type = MAT_VALHOLLIDE + no_variants = FALSE + apply_colour = TRUE + +// Particle Smasher and Exotic material. +/obj/item/stack/material/verdantium + name = MAT_VERDANTIUM + icon_state = "sheet-wavy" + item_state = "mhydrogen" + default_type = MAT_VERDANTIUM + no_variants = FALSE + apply_colour = TRUE + +/obj/item/stack/material/morphium + name = MAT_MORPHIUM + icon_state = "sheet-wavy" + item_state = "mhydrogen" + default_type = MAT_MORPHIUM + no_variants = FALSE + apply_colour = TRUE + + + diff --git a/code/modules/materials/sheets/glass.dm b/code/modules/materials/sheets/glass.dm new file mode 100644 index 00000000000..bf891347ea0 --- /dev/null +++ b/code/modules/materials/sheets/glass.dm @@ -0,0 +1,33 @@ +/obj/item/stack/material/glass + name = "glass" + icon_state = "sheet-transparent" + default_type = "glass" + no_variants = FALSE + drop_sound = 'sound/items/drop/glass.ogg' + pickup_sound = 'sound/items/pickup/glass.ogg' + apply_colour = TRUE + +/obj/item/stack/material/glass/reinforced + name = "reinforced glass" + icon_state = "sheet-rtransparent" + default_type = "rglass" + no_variants = FALSE + apply_colour = TRUE + +/obj/item/stack/material/glass/phoronglass + name = "borosilicate glass" + desc = "This sheet is special platinum-glass alloy designed to withstand large temperatures" + singular_name = "borosilicate glass sheet" + icon_state = "sheet-transparent" + default_type = "borosilicate glass" + no_variants = FALSE + apply_colour = TRUE + +/obj/item/stack/material/glass/phoronrglass + name = "reinforced borosilicate glass" + desc = "This sheet is special platinum-glass alloy designed to withstand large temperatures. It is reinforced with few rods." + singular_name = "reinforced borosilicate glass sheet" + icon_state = "sheet-rtransparent" + default_type = "reinforced borosilicate glass" + no_variants = FALSE + apply_colour = TRUE \ No newline at end of file diff --git a/code/modules/materials/sheets/glass_vr.dm b/code/modules/materials/sheets/glass_vr.dm new file mode 100644 index 00000000000..23aad9c0cc2 --- /dev/null +++ b/code/modules/materials/sheets/glass_vr.dm @@ -0,0 +1,17 @@ +/obj/item/stack/material/glass/titanium + name = "ti-glass sheets" + icon = 'icons/obj/stacks_vr.dmi' + icon_state = "sheet-titaniumglass" + item_state = "sheet-silver" + no_variants = FALSE + drop_sound = 'sound/items/drop/glass.ogg' + default_type = MAT_TITANIUMGLASS + +/obj/item/stack/material/glass/plastitanium + name = "plastitanium glass sheets" + icon = 'icons/obj/stacks_vr.dmi' + icon_state = "sheet-plastitaniumglass" + item_state = "sheet-silver" + no_variants = FALSE + drop_sound = 'sound/items/drop/glass.ogg' + default_type = MAT_PLASTITANIUMGLASS diff --git a/code/modules/materials/sheets/metals/hull.dm b/code/modules/materials/sheets/metals/hull.dm new file mode 100644 index 00000000000..5a6d429f448 --- /dev/null +++ b/code/modules/materials/sheets/metals/hull.dm @@ -0,0 +1,18 @@ +/obj/item/stack/material/steel/hull + name = MAT_STEELHULL + default_type = MAT_STEELHULL + +/obj/item/stack/material/plasteel/hull + name = MAT_PLASTEELHULL + default_type = MAT_PLASTEELHULL + +/obj/item/stack/material/durasteel/hull + name = MAT_DURASTEELHULL + +/obj/item/stack/material/titanium/hull + name = MAT_TITANIUMHULL + default_type = MAT_TITANIUMHULL + +/obj/item/stack/material/morphium/hull + name = MAT_MORPHIUMHULL + default_type = MAT_MORPHIUMHULL \ No newline at end of file diff --git a/code/modules/materials/sheets/metals/hull_vr.dm b/code/modules/materials/sheets/metals/hull_vr.dm new file mode 100644 index 00000000000..29e267ab818 --- /dev/null +++ b/code/modules/materials/sheets/metals/hull_vr.dm @@ -0,0 +1,15 @@ +/obj/item/stack/material/plastitanium/hull + name = "plastitanium hull sheets" + icon = 'icons/obj/stacks_vr.dmi' + icon_state = "sheet-plastitanium" + item_state = "sheet-silver" + no_variants = FALSE + default_type = MAT_PLASTITANIUMHULL + +/obj/item/stack/material/gold/hull + name = "gold hull sheets" + icon = 'icons/obj/stacks_vr.dmi' + icon_state = "sheet-plastitanium" + item_state = "sheet-silver" + no_variants = FALSE + default_type = MAT_GOLDHULL diff --git a/code/modules/materials/sheets/metals/metal.dm b/code/modules/materials/sheets/metals/metal.dm new file mode 100644 index 00000000000..bbad559c128 --- /dev/null +++ b/code/modules/materials/sheets/metals/metal.dm @@ -0,0 +1,140 @@ +/obj/item/stack/material/steel + name = DEFAULT_WALL_MATERIAL + icon_state = "sheet-refined" + default_type = DEFAULT_WALL_MATERIAL + no_variants = FALSE + apply_colour = TRUE + +/obj/item/stack/material/plasteel + name = "plasteel" + icon_state = "sheet-reinforced" + default_type = "plasteel" + no_variants = FALSE + apply_colour = TRUE + +/obj/item/stack/material/durasteel + name = "durasteel" + icon_state = "sheet-reinforced" + item_state = "sheet-metal" + default_type = "durasteel" + no_variants = FALSE + apply_colour = TRUE + +/obj/item/stack/material/titanium + name = MAT_TITANIUM + icon_state = "sheet-refined" + apply_colour = TRUE + item_state = "sheet-silver" + default_type = MAT_TITANIUM + no_variants = FALSE + +/obj/item/stack/material/iron + name = "iron" + icon_state = "sheet-ingot" + default_type = "iron" + apply_colour = 1 + no_variants = FALSE + +/obj/item/stack/material/lead + name = "lead" + icon_state = "sheet-ingot" + default_type = "lead" + apply_colour = 1 + no_variants = FALSE + +/obj/item/stack/material/gold + name = "gold" + icon_state = "sheet-ingot" + default_type = "gold" + no_variants = FALSE + apply_colour = TRUE + +/obj/item/stack/material/silver + name = "silver" + icon_state = "sheet-ingot" + default_type = "silver" + no_variants = FALSE + apply_colour = TRUE + +//Valuable resource, cargo can sell it. +/obj/item/stack/material/platinum + name = "platinum" + icon_state = "sheet-adamantine" + default_type = "platinum" + no_variants = FALSE + apply_colour = TRUE + +/obj/item/stack/material/uranium + name = "uranium" + icon_state = "sheet-uranium" + default_type = "uranium" + no_variants = FALSE + +//Extremely valuable to Research. +/obj/item/stack/material/mhydrogen + name = "metallic hydrogen" + icon_state = "sheet-mythril" + default_type = "mhydrogen" + no_variants = FALSE + +// Fusion fuel. +/obj/item/stack/material/deuterium + name = "deuterium" + icon_state = "sheet-puck" + default_type = "deuterium" + apply_colour = 1 + no_variants = FALSE + +//Fuel for MRSPACMAN generator. +/obj/item/stack/material/tritium + name = "tritium" + icon_state = "sheet-puck" + default_type = "tritium" + apply_colour = TRUE + no_variants = FALSE + +/obj/item/stack/material/osmium + name = "osmium" + icon_state = "sheet-ingot" + default_type = "osmium" + apply_colour = 1 + no_variants = FALSE + +/obj/item/stack/material/graphite + name = "graphite" + icon_state = "sheet-puck" + default_type = MAT_GRAPHITE + apply_colour = 1 + no_variants = FALSE + +/obj/item/stack/material/bronze + name = "bronze" + icon_state = "sheet-ingot" + singular_name = "bronze ingot" + default_type = "bronze" + apply_colour = 1 + no_variants = FALSE + +/obj/item/stack/material/tin + name = "tin" + icon_state = "sheet-ingot" + singular_name = "tin ingot" + default_type = "tin" + apply_colour = 1 + no_variants = FALSE + +/obj/item/stack/material/copper + name = "copper" + icon_state = "sheet-ingot" + singular_name = "copper ingot" + default_type = "copper" + apply_colour = 1 + no_variants = FALSE + +/obj/item/stack/material/aluminium + name = "aluminium" + icon_state = "sheet-ingot" + singular_name = "aluminium ingot" + default_type = "aluminium" + apply_colour = 1 + no_variants = FALSE diff --git a/code/modules/materials/sheets/metals/metal_vr.dm b/code/modules/materials/sheets/metals/metal_vr.dm new file mode 100644 index 00000000000..1a867ea9578 --- /dev/null +++ b/code/modules/materials/sheets/metals/metal_vr.dm @@ -0,0 +1,12 @@ +/obj/item/stack/material/titanium + icon = 'icons/obj/stacks_vr.dmi' + icon_state = "sheet-titanium" + no_variants = FALSE + +/obj/item/stack/material/plastitanium + name = "plastitanium sheets" + icon = 'icons/obj/stacks_vr.dmi' + icon_state = "sheet-plastitanium" + item_state = "sheet-silver" + no_variants = FALSE + default_type = MAT_PLASTITANIUM diff --git a/code/game/objects/items/stacks/rods.dm b/code/modules/materials/sheets/metals/rods.dm similarity index 96% rename from code/game/objects/items/stacks/rods.dm rename to code/modules/materials/sheets/metals/rods.dm index 9844ae1cba9..d1c4a1ee240 100644 --- a/code/game/objects/items/stacks/rods.dm +++ b/code/modules/materials/sheets/metals/rods.dm @@ -1,109 +1,109 @@ -/obj/item/stack/rods - name = "metal rod" - desc = "Some rods. Can be used for building, or something." - singular_name = "metal rod" - icon_state = "rods" - w_class = ITEMSIZE_NORMAL - force = 9.0 - throwforce = 15.0 - throw_speed = 5 - throw_range = 20 - drop_sound = 'sound/items/drop/metalweapon.ogg' - pickup_sound = 'sound/items/pickup/metalweapon.ogg' - matter = list(DEFAULT_WALL_MATERIAL = SHEET_MATERIAL_AMOUNT / 2) - max_amount = 60 - attack_verb = list("hit", "bludgeoned", "whacked") - - color = "#666666" - -/obj/item/stack/rods/cyborg - name = "metal rod synthesizer" - desc = "A device that makes metal rods." - gender = NEUTER - matter = null - uses_charge = 1 - charge_costs = list(500) - stacktype = /obj/item/stack/rods - no_variants = TRUE - -/obj/item/stack/rods/Initialize() - . = ..() - recipes = rods_recipes - update_icon() - -/obj/item/stack/rods/update_icon() - var/amount = get_amount() - if((amount <= 5) && (amount > 0)) - icon_state = "rods-[amount]" - else - icon_state = "rods" - -var/global/list/datum/stack_recipe/rods_recipes = list( \ - new/datum/stack_recipe("grille", /obj/structure/grille, 2, time = 10, one_per_turf = 1, on_floor = 0), - new/datum/stack_recipe("catwalk", /obj/structure/catwalk, 2, time = 80, one_per_turf = 1, on_floor = 1)) - -/obj/item/stack/rods/attackby(obj/item/W as obj, mob/user as mob) - if (istype(W, /obj/item/weapon/weldingtool)) - var/obj/item/weapon/weldingtool/WT = W - - if(get_amount() < 2) - to_chat(user, "You need at least two rods to do this.") - return - - if(WT.remove_fuel(0,user)) - var/obj/item/stack/material/steel/new_item = new(usr.loc) - new_item.add_to_stacks(usr) - for (var/mob/M in viewers(src)) - M.show_message("[src] is shaped into metal by [user.name] with the weldingtool.", 3, "You hear welding.", 2) - var/obj/item/stack/rods/R = src - src = null - var/replace = (user.get_inactive_hand()==R) - R.use(2) - if (!R && replace) - user.put_in_hands(new_item) - return - - if (istype(W, /obj/item/weapon/tape_roll)) - var/obj/item/stack/medical/splint/ghetto/new_splint = new(get_turf(user)) - new_splint.add_fingerprint(user) - - user.visible_message("\The [user] constructs \a [new_splint] out of a [singular_name].", \ - "You use make \a [new_splint] out of a [singular_name].") - src.use(1) - return - - ..() - -/* -/obj/item/stack/rods/attack_self(mob/user as mob) - src.add_fingerprint(user) - - if(!istype(user.loc,/turf)) return 0 - - if (locate(/obj/structure/grille, usr.loc)) - for(var/obj/structure/grille/G in usr.loc) - if (G.destroyed) - G.health = 10 - G.density = 1 - G.destroyed = 0 - G.icon_state = "grille" - use(1) - else - return 1 - - else if(!in_use) - if(get_amount() < 2) - to_chat(user, "You need at least two rods to do this.") - return - to_chat(usr, "Assembling grille...") - in_use = 1 - if (!do_after(usr, 10)) - in_use = 0 - return - var/obj/structure/grille/F = new /obj/structure/grille/ ( usr.loc ) - to_chat(usr, "You assemble a grille") - in_use = 0 - F.add_fingerprint(usr) - use(2) - return +/obj/item/stack/rods + name = "metal rod" + desc = "Some rods. Can be used for building, or something." + singular_name = "metal rod" + icon_state = "rods" + w_class = ITEMSIZE_NORMAL + force = 9.0 + throwforce = 15.0 + throw_speed = 5 + throw_range = 20 + drop_sound = 'sound/items/drop/metalweapon.ogg' + pickup_sound = 'sound/items/pickup/metalweapon.ogg' + matter = list(DEFAULT_WALL_MATERIAL = SHEET_MATERIAL_AMOUNT / 2) + max_amount = 60 + attack_verb = list("hit", "bludgeoned", "whacked") + + color = "#666666" + +/obj/item/stack/rods/cyborg + name = "metal rod synthesizer" + desc = "A device that makes metal rods." + gender = NEUTER + matter = null + uses_charge = 1 + charge_costs = list(500) + stacktype = /obj/item/stack/rods + no_variants = TRUE + +/obj/item/stack/rods/Initialize() + . = ..() + recipes = rods_recipes + update_icon() + +/obj/item/stack/rods/update_icon() + var/amount = get_amount() + if((amount <= 5) && (amount > 0)) + icon_state = "rods-[amount]" + else + icon_state = "rods" + +var/global/list/datum/stack_recipe/rods_recipes = list( \ + new/datum/stack_recipe("grille", /obj/structure/grille, 2, time = 10, one_per_turf = 1, on_floor = 0), + new/datum/stack_recipe("catwalk", /obj/structure/catwalk, 2, time = 80, one_per_turf = 1, on_floor = 1)) + +/obj/item/stack/rods/attackby(obj/item/W as obj, mob/user as mob) + if (istype(W, /obj/item/weapon/weldingtool)) + var/obj/item/weapon/weldingtool/WT = W + + if(get_amount() < 2) + to_chat(user, "You need at least two rods to do this.") + return + + if(WT.remove_fuel(0,user)) + var/obj/item/stack/material/steel/new_item = new(usr.loc) + new_item.add_to_stacks(usr) + for (var/mob/M in viewers(src)) + M.show_message("[src] is shaped into metal by [user.name] with the weldingtool.", 3, "You hear welding.", 2) + var/obj/item/stack/rods/R = src + src = null + var/replace = (user.get_inactive_hand()==R) + R.use(2) + if (!R && replace) + user.put_in_hands(new_item) + return + + if (istype(W, /obj/item/weapon/tape_roll)) + var/obj/item/stack/medical/splint/ghetto/new_splint = new(get_turf(user)) + new_splint.add_fingerprint(user) + + user.visible_message("\The [user] constructs \a [new_splint] out of a [singular_name].", \ + "You use make \a [new_splint] out of a [singular_name].") + src.use(1) + return + + ..() + +/* +/obj/item/stack/rods/attack_self(mob/user as mob) + src.add_fingerprint(user) + + if(!istype(user.loc,/turf)) return 0 + + if (locate(/obj/structure/grille, usr.loc)) + for(var/obj/structure/grille/G in usr.loc) + if (G.destroyed) + G.health = 10 + G.density = 1 + G.destroyed = 0 + G.icon_state = "grille" + use(1) + else + return 1 + + else if(!in_use) + if(get_amount() < 2) + to_chat(user, "You need at least two rods to do this.") + return + to_chat(usr, "Assembling grille...") + in_use = 1 + if (!do_after(usr, 10)) + in_use = 0 + return + var/obj/structure/grille/F = new /obj/structure/grille/ ( usr.loc ) + to_chat(usr, "You assemble a grille") + in_use = 0 + F.add_fingerprint(usr) + use(2) + return */ \ No newline at end of file diff --git a/code/modules/materials/sheets/organic/animal_products.dm b/code/modules/materials/sheets/organic/animal_products.dm new file mode 100644 index 00000000000..4620da5ea9c --- /dev/null +++ b/code/modules/materials/sheets/organic/animal_products.dm @@ -0,0 +1,31 @@ +/obj/item/stack/material/chitin + name = "chitin" + desc = "The by-product of mob grinding." + icon_state = "chitin" + default_type = MAT_CHITIN + no_variants = FALSE + pass_color = TRUE + strict_color_stacking = TRUE + drop_sound = 'sound/items/drop/leather.ogg' + pickup_sound = 'sound/items/pickup/leather.ogg' + +//don't see anywhere else to put these, maybe together they could be used to make the xenos suit? +/obj/item/stack/xenochitin + name = "alien chitin" + desc = "A piece of the hide of a terrible creature." + singular_name = "alien chitin piece" + icon = 'icons/mob/alien.dmi' + icon_state = "chitin" + stacktype = "hide-chitin" + +/obj/item/xenos_claw + name = "alien claw" + desc = "The claw of a terrible creature." + icon = 'icons/mob/alien.dmi' + icon_state = "claw" + +/obj/item/weed_extract + name = "weed extract" + desc = "A piece of slimy, purplish weed." + icon = 'icons/mob/alien.dmi' + icon_state = "weed_extract" \ No newline at end of file diff --git a/code/modules/materials/sheets/organic/resin.dm b/code/modules/materials/sheets/organic/resin.dm new file mode 100644 index 00000000000..7120911f2d5 --- /dev/null +++ b/code/modules/materials/sheets/organic/resin.dm @@ -0,0 +1,8 @@ +/obj/item/stack/material/resin + name = "resin" + icon_state = "sheet-resin" + default_type = "resin" + no_variants = TRUE + apply_colour = TRUE + pass_color = TRUE + strict_color_stacking = TRUE \ No newline at end of file diff --git a/code/modules/materials/sheets/organic/tanning/hide.dm b/code/modules/materials/sheets/organic/tanning/hide.dm new file mode 100644 index 00000000000..a8b229c9eba --- /dev/null +++ b/code/modules/materials/sheets/organic/tanning/hide.dm @@ -0,0 +1,90 @@ +/obj/item/stack/animalhide + name = "hide" + desc = "The hide of some creature." + description_info = "Use something sharp, like a knife, to scrape the hairs/feathers/etc off this hide to prepare it for tanning." + icon_state = "sheet-hide" + drop_sound = 'sound/items/drop/cloth.ogg' + pickup_sound = 'sound/items/pickup/cloth.ogg' + amount = 1 + max_amount = 20 + stacktype = "hide" + no_variants = TRUE +// This needs to be very clearly documented for players. Whether it should stay in the main description is up for debate. +/obj/item/stack/animalhide/examine(var/mob/user) + . = ..() + . += description_info + +//Step one - dehairing. +/obj/item/stack/animalhide/attackby(obj/item/weapon/W as obj, mob/user as mob) + if(has_edge(W) || is_sharp(W)) + //visible message on mobs is defined as visible_message(var/message, var/self_message, var/blind_message) + user.visible_message("\The [user] starts cutting hair off \the [src]", "You start cutting the hair off \the [src]", "You hear the sound of a knife rubbing against flesh") + var/scraped = 0 + while(amount > 0 && do_after(user, 2.5 SECONDS)) // 2.5s per hide + //Try locating an exisitng stack on the tile and add to there if possible + var/obj/item/stack/hairlesshide/H = null + for(var/obj/item/stack/hairlesshide/HS in user.loc) // Could be scraping something inside a locker, hence the .loc, not get_turf + if(HS.amount < HS.max_amount) + H = HS + break + + // Either we found a valid stack, in which case increment amount, + // Or we need to make a new stack + if(istype(H)) + H.amount++ + else + H = new /obj/item/stack/hairlesshide(user.loc) + + // Increment the amount + src.use(1) + scraped++ + + if(scraped) + to_chat(user, SPAN_NOTICE("You scrape the hair off [scraped] hide\s.")) + else + ..() + +/obj/item/stack/animalhide/human + name = "skin" + desc = "The by-product of sapient farming." + singular_name = "skin piece" + icon_state = "sheet-hide" + no_variants = FALSE + drop_sound = 'sound/items/drop/leather.ogg' + pickup_sound = 'sound/items/pickup/leather.ogg' + stacktype = "hide-human" + +/obj/item/stack/animalhide/corgi + name = "corgi hide" + desc = "The by-product of corgi farming." + singular_name = "corgi hide piece" + icon_state = "sheet-corgi" + stacktype = "hide-corgi" + +/obj/item/stack/animalhide/cat + name = "cat hide" + desc = "The by-product of cat farming." + singular_name = "cat hide piece" + icon_state = "sheet-cat" + stacktype = "hide-cat" + +/obj/item/stack/animalhide/monkey + name = "monkey hide" + desc = "The by-product of monkey farming." + singular_name = "monkey hide piece" + icon_state = "sheet-monkey" + stacktype = "hide-monkey" + +/obj/item/stack/animalhide/lizard + name = "lizard skin" + desc = "Sssssss..." + singular_name = "lizard skin piece" + icon_state = "sheet-lizard" + stacktype = "hide-lizard" + +/obj/item/stack/animalhide/xeno + name = "alien hide" + desc = "The skin of a terrible creature." + singular_name = "alien hide piece" + icon_state = "sheet-xeno" + stacktype = "hide-xeno" \ No newline at end of file diff --git a/code/modules/materials/sheets/organic/tanning/hide_hairless.dm b/code/modules/materials/sheets/organic/tanning/hide_hairless.dm new file mode 100644 index 00000000000..72b235e415d --- /dev/null +++ b/code/modules/materials/sheets/organic/tanning/hide_hairless.dm @@ -0,0 +1,48 @@ +//Step two - washing..... it's actually in washing machine code, and ere. + +/obj/item/stack/hairlesshide + name = "hairless hide" + desc = "This hide was stripped of it's hair, but still needs tanning." + description_info = "Get it wet to continue tanning this into leather.
\ + You could set it in a river, wash it with a sink, or just splash water on it with a bucket." + singular_name = "hairless hide piece" + icon_state = "sheet-hairlesshide" + no_variants = FALSE + max_amount = 20 + stacktype = "hairlesshide" + +/obj/item/stack/hairlesshide/examine(var/mob/user) + . = ..() + . += description_info + +/obj/item/stack/hairlesshide/water_act(var/wateramount) + . = ..() + wateramount = min(amount, round(wateramount)) + for(var/i in 1 to wateramount) + var/obj/item/stack/wetleather/H = null + for(var/obj/item/stack/wetleather/HS in get_turf(src)) // Doesn't have a user, can't just use their loc + if(HS.amount < HS.max_amount) + H = HS + break + + // Either we found a valid stack, in which case increment amount, + // Or we need to make a new stack + if(istype(H)) + H.amount++ + else + H = new /obj/item/stack/wetleather(get_turf(src)) + + // Increment the amount + src.use(1) + +/obj/item/stack/hairlesshide/proc/rapidcure(var/stacknum = 1) + stacknum = min(stacknum, amount) + + while(stacknum) + var/obj/item/stack/wetleather/I = new /obj/item/stack/wetleather(get_turf(src)) + + if(istype(I)) + I.dry() + + use(1) + stacknum -= 1 \ No newline at end of file diff --git a/code/modules/materials/sheets/organic/tanning/leather_wet.dm b/code/modules/materials/sheets/organic/tanning/leather_wet.dm new file mode 100644 index 00000000000..64f672512ce --- /dev/null +++ b/code/modules/materials/sheets/organic/tanning/leather_wet.dm @@ -0,0 +1,51 @@ +//Step three - drying +/obj/item/stack/wetleather + name = "wet leather" + desc = "This leather has been cleaned but still needs to be dried." + description_info = "To finish tanning the leather, you need to dry it. \ + You could place it under a fire, \ + put it in a drying rack, \ + or build a tanning rack from steel or wooden boards." + singular_name = "wet leather piece" + icon_state = "sheet-wetleather" + var/wetness = 30 //Reduced when exposed to high temperautres + var/drying_threshold_temperature = 500 //Kelvin to start drying + no_variants = FALSE + max_amount = 20 + stacktype = "wetleather" + + var/dry_type = /obj/item/stack/material/leather + +/obj/item/stack/wetleather/examine(var/mob/user) + . = ..() + . += description_info + . += "\The [src] is [get_dryness_text()]." + +/obj/item/stack/wetleather/proc/get_dryness_text() + if(wetness > 20) + return "wet" + if(wetness > 10) + return "damp" + if(wetness) + return "almost dry" + return "dry" + +/obj/item/stack/wetleather/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume) + ..() + if(exposed_temperature >= drying_threshold_temperature) + wetness-- + if(wetness == 0) + dry() + +/obj/item/stack/wetleather/proc/dry() + var/obj/item/stack/material/leather/L = new(src.loc) + L.amount = amount + use(amount) + return L + +/obj/item/stack/wetleather/transfer_to(obj/item/stack/S, var/tamount=null, var/type_verified) + . = ..() + if(.) // If it transfers any, do a weighted average of the wetness + var/obj/item/stack/wetleather/W = S + var/oldamt = W.amount - . + W.wetness = round(((oldamt * W.wetness) + (. * wetness)) / W.amount) diff --git a/code/modules/materials/sheets/organic/tanning/tanning_rack.dm b/code/modules/materials/sheets/organic/tanning/tanning_rack.dm new file mode 100644 index 00000000000..96d70d90967 --- /dev/null +++ b/code/modules/materials/sheets/organic/tanning/tanning_rack.dm @@ -0,0 +1,70 @@ +/obj/structure/tanning_rack + name = "tanning rack" + desc = "A rack used to stretch leather out and hold it taut during the tanning process." + icon = 'icons/obj/kitchen.dmi' + icon_state = "spike" + + var/obj/item/stack/wetleather/drying = null + +/obj/structure/tanning_rack/Initialize() + . = ..() + START_PROCESSING(SSobj, src) // SSObj fires ~every 2s , starting from wetness 30 takes ~1m + +/obj/structure/tanning_rack/Destroy() + STOP_PROCESSING(SSobj, src) + return ..() + +/obj/structure/tanning_rack/process() + if(drying && drying.wetness) + drying.wetness = max(drying.wetness - 1, 0) + if(!drying.wetness) + visible_message("The [drying] is dry!") + update_icon() + +/obj/structure/tanning_rack/examine(var/mob/user) + . = ..() + if(drying) + . += "\The [drying] is [drying.get_dryness_text()]." + +/obj/structure/tanning_rack/update_icon() + overlays.Cut() + if(drying) + var/image/I + if(drying.wetness) + I = image(icon, "leather_wet") + else + I = image(icon, "leather_dry") + add_overlay(I) + +/obj/structure/tanning_rack/attackby(var/atom/A, var/mob/user) + if(istype(A, /obj/item/stack/wetleather)) + if(!drying) // If not drying anything, start drying the thing + if(user.unEquip(A, target = src)) + drying = A + else // Drying something, add if possible + var/obj/item/stack/wetleather/W = A + W.transfer_to(drying, W.amount, TRUE) + update_icon() + return TRUE + return ..() + +/obj/structure/tanning_rack/attack_hand(var/mob/user) + if(drying) + var/obj/item/stack/S = drying + if(!drying.wetness) // If it's dry, make a stack of dry leather and prepare to put that in their hands + var/obj/item/stack/material/leather/L = new(src) + L.amount = drying.amount + drying.use(drying.amount) + S = L + + if(ishuman(user)) + var/mob/living/carbon/human/H = user + if(!H.put_in_any_hand_if_possible(S)) + S.forceMove(get_turf(src)) + else + S.forceMove(get_turf(src)) + drying = null + update_icon() + +/obj/structure/tanning_rack/attack_robot(var/mob/user) + attack_hand(user) // That has checks to \ No newline at end of file diff --git a/code/modules/materials/sheets/organic/textiles.dm b/code/modules/materials/sheets/organic/textiles.dm new file mode 100644 index 00000000000..a534ee19b1c --- /dev/null +++ b/code/modules/materials/sheets/organic/textiles.dm @@ -0,0 +1,23 @@ +/obj/item/stack/material/leather + name = "leather" + desc = "The by-product of mob grinding." + icon_state = "sheet-leather" + default_type = MAT_LEATHER + no_variants = FALSE + pass_color = TRUE + strict_color_stacking = TRUE + drop_sound = 'sound/items/drop/leather.ogg' + pickup_sound = 'sound/items/pickup/leather.ogg' + +/obj/item/stack/material/cloth + name = "cloth" + icon_state = "sheet-cloth" + default_type = "cloth" + no_variants = FALSE + pass_color = TRUE + strict_color_stacking = TRUE + drop_sound = 'sound/items/drop/clothing.ogg' + pickup_sound = 'sound/items/pickup/clothing.ogg' + +/obj/item/stack/material/cloth/diyaab + color = "#c6ccf0" diff --git a/code/modules/materials/sheets/organic/wood.dm b/code/modules/materials/sheets/organic/wood.dm new file mode 100644 index 00000000000..d3d1fd6418e --- /dev/null +++ b/code/modules/materials/sheets/organic/wood.dm @@ -0,0 +1,55 @@ +/obj/item/stack/material/wood + name = "wooden plank" + icon_state = "sheet-wood" + default_type = MAT_WOOD + strict_color_stacking = TRUE + apply_colour = 1 + drop_sound = 'sound/items/drop/wooden.ogg' + pickup_sound = 'sound/items/pickup/wooden.ogg' + no_variants = FALSE + +/obj/item/stack/material/wood/sif + name = "alien wooden plank" + color = "#0099cc" + default_type = MAT_SIFWOOD + +/obj/item/stack/material/log + name = "log" + icon_state = "sheet-log" + default_type = MAT_LOG + no_variants = FALSE + color = "#824B28" + max_amount = 25 + w_class = ITEMSIZE_HUGE + description_info = "Use inhand to craft things, or use a sharp and edged object on this to convert it into two wooden planks." + var/plank_type = /obj/item/stack/material/wood + drop_sound = 'sound/items/drop/wooden.ogg' + pickup_sound = 'sound/items/pickup/wooden.ogg' + +/obj/item/stack/material/log/sif + name = "alien log" + default_type = MAT_SIFLOG + color = "#0099cc" + plank_type = /obj/item/stack/material/wood/sif + +/obj/item/stack/material/log/attackby(var/obj/item/W, var/mob/user) + if(!istype(W) || W.force <= 0) + return ..() + if(W.sharp && W.edge) + var/time = (3 SECONDS / max(W.force / 10, 1)) * W.toolspeed + user.setClickCooldown(time) + if(do_after(user, time, src) && use(1)) + to_chat(user, "You cut up a log into planks.") + playsound(src, 'sound/effects/woodcutting.ogg', 50, 1) + var/obj/item/stack/material/wood/existing_wood = null + for(var/obj/item/stack/material/wood/M in user.loc) + if(M.material.name == src.material.name) + existing_wood = M + break + + var/obj/item/stack/material/wood/new_wood = new plank_type(user.loc) + new_wood.amount = 2 + if(existing_wood && new_wood.transfer_to(existing_wood)) + to_chat(user, "You add the newly-formed wood to the stack. It now contains [existing_wood.amount] planks.") + else + return ..() diff --git a/code/modules/materials/sheets/plastic.dm b/code/modules/materials/sheets/plastic.dm new file mode 100644 index 00000000000..41415af606a --- /dev/null +++ b/code/modules/materials/sheets/plastic.dm @@ -0,0 +1,15 @@ +/obj/item/stack/material/plastic + name = "plastic" + icon_state = "sheet-plastic" + default_type = "plastic" + no_variants = FALSE + +/obj/item/stack/material/cardboard + name = "cardboard" + icon_state = "sheet-card" + default_type = "cardboard" + no_variants = FALSE + pass_color = TRUE + strict_color_stacking = TRUE + drop_sound = 'sound/items/drop/cardboardbox.ogg' + pickup_sound = 'sound/items/pickup/cardboardbox.ogg' diff --git a/code/modules/materials/sheets/snow.dm b/code/modules/materials/sheets/snow.dm new file mode 100644 index 00000000000..7ecc4c4e64d --- /dev/null +++ b/code/modules/materials/sheets/snow.dm @@ -0,0 +1,16 @@ +// Ok, technically not stones, but the snowbrick's function is similar to sandstone and marble +/obj/item/stack/material/snow + name = "snow" + desc = "The temptation to build a snowman rises." + icon_state = "sheet-snow" + drop_sound = 'sound/items/drop/gloves.ogg' + pickup_sound = 'sound/items/pickup/clothing.ogg' + default_type = "snow" + +/obj/item/stack/material/snowbrick + name = "snow brick" + desc = "For all of your igloo building needs." + icon_state = "sheet-snowbrick" + default_type = "packed snow" + drop_sound = 'sound/items/drop/gloves.ogg' + pickup_sound = 'sound/items/pickup/clothing.ogg' \ No newline at end of file diff --git a/code/modules/materials/sheets/stone.dm b/code/modules/materials/sheets/stone.dm new file mode 100644 index 00000000000..17347ff9d8f --- /dev/null +++ b/code/modules/materials/sheets/stone.dm @@ -0,0 +1,15 @@ +/obj/item/stack/material/sandstone + name = "sandstone brick" + icon_state = "sheet-sandstone" + default_type = "sandstone" + no_variants = FALSE + drop_sound = 'sound/items/drop/boots.ogg' + pickup_sound = 'sound/items/pickup/boots.ogg' + +/obj/item/stack/material/marble + name = "marble brick" + icon_state = "sheet-marble" + default_type = "marble" + no_variants = FALSE + drop_sound = 'sound/items/drop/boots.ogg' + pickup_sound = 'sound/items/pickup/boots.ogg' diff --git a/code/modules/materials/sheets/supermatter.dm b/code/modules/materials/sheets/supermatter.dm new file mode 100644 index 00000000000..c56f2980881 --- /dev/null +++ b/code/modules/materials/sheets/supermatter.dm @@ -0,0 +1,55 @@ +// Forged in the equivalent of Hell, one piece at a time. +/obj/item/stack/material/supermatter + name = MAT_SUPERMATTER + icon_state = "sheet-super" + item_state = "diamond" + default_type = MAT_SUPERMATTER + apply_colour = TRUE + +/obj/item/stack/material/supermatter/proc/update_mass() // Due to how dangerous they can be, the item will get heavier and larger the more are in the stack. + slowdown = amount / 10 + w_class = min(5, round(amount / 10) + 1) + throw_range = round(amount / 7) + 1 + +/obj/item/stack/material/supermatter/use(var/used) + . = ..() + update_mass() + return + +/obj/item/stack/material/supermatter/attack_hand(mob/user) + . = ..() + + update_mass() + SSradiation.radiate(src, 5 + amount) + var/mob/living/M = user + if(!istype(M)) + return + + var/burn_user = TRUE + if(istype(M, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = user + var/obj/item/clothing/gloves/G = H.gloves + if(istype(G) && ((G.flags & THICKMATERIAL && prob(70)) || istype(G, /obj/item/clothing/gloves/gauntlets))) + burn_user = FALSE + + if(burn_user) + H.visible_message("\The [src] flashes as it scorches [H]'s hands!") + H.apply_damage(amount / 2 + 5, BURN, "r_hand", used_weapon="Supermatter Chunk") + H.apply_damage(amount / 2 + 5, BURN, "l_hand", used_weapon="Supermatter Chunk") + H.drop_from_inventory(src, get_turf(H)) + return + + if(istype(user, /mob/living/silicon/robot)) + burn_user = FALSE + + if(burn_user) + M.apply_damage(amount, BURN, null, used_weapon="Supermatter Chunk") + +/obj/item/stack/material/supermatter/ex_act(severity) // An incredibly hard to manufacture material, SM chunks are unstable by their 'stabilized' nature. + if(prob((4 / severity) * 20)) + SSradiation.radiate(get_turf(src), amount * 4) + explosion(get_turf(src),round(amount / 12) , round(amount / 6), round(amount / 3), round(amount / 25)) + qdel(src) + return + SSradiation.radiate(get_turf(src), amount * 2) + ..() \ No newline at end of file diff --git a/code/modules/mining/machine_input_output_plates.dm b/code/modules/mining/machinery/machine_input_output_plates.dm similarity index 90% rename from code/modules/mining/machine_input_output_plates.dm rename to code/modules/mining/machinery/machine_input_output_plates.dm index d8693a1316b..0e7680e6728 100644 --- a/code/modules/mining/machine_input_output_plates.dm +++ b/code/modules/mining/machinery/machine_input_output_plates.dm @@ -1,19 +1,19 @@ -/**********************Input and output plates**************************/ - -/obj/machinery/mineral/input - icon = 'icons/mob/screen1.dmi' - icon_state = "x2" - name = "Input area" - density = 0 - anchored = 1.0 - New() - icon_state = "blank" - -/obj/machinery/mineral/output - icon = 'icons/mob/screen1.dmi' - icon_state = "x" - name = "Output area" - density = 0 - anchored = 1.0 - New() +/**********************Input and output plates**************************/ + +/obj/machinery/mineral/input + icon = 'icons/mob/screen1.dmi' + icon_state = "x2" + name = "Input area" + density = 0 + anchored = 1.0 + New() + icon_state = "blank" + +/obj/machinery/mineral/output + icon = 'icons/mob/screen1.dmi' + icon_state = "x" + name = "Output area" + density = 0 + anchored = 1.0 + New() icon_state = "blank" \ No newline at end of file diff --git a/code/modules/mining/machine_processing.dm b/code/modules/mining/machinery/machine_processing.dm similarity index 100% rename from code/modules/mining/machine_processing.dm rename to code/modules/mining/machinery/machine_processing.dm diff --git a/code/modules/mining/machine_stacking.dm b/code/modules/mining/machinery/machine_stacking.dm similarity index 100% rename from code/modules/mining/machine_stacking.dm rename to code/modules/mining/machinery/machine_stacking.dm diff --git a/code/modules/mining/machine_unloading.dm b/code/modules/mining/machinery/machine_unloading.dm similarity index 100% rename from code/modules/mining/machine_unloading.dm rename to code/modules/mining/machinery/machine_unloading.dm diff --git a/code/modules/mining/mine_turfs.dm b/code/modules/mining/mine_turfs.dm index 9747179320c..2608e3c7887 100644 --- a/code/modules/mining/mine_turfs.dm +++ b/code/modules/mining/mine_turfs.dm @@ -40,7 +40,7 @@ var/list/mining_overlay_cache = list() var/datum/artifact_find/artifact_find var/ignore_mapgen - var/ore_types = list( + var/static/list/ore_types = list( "hematite" = /obj/item/weapon/ore/iron, "uranium" = /obj/item/weapon/ore/uranium, "gold" = /obj/item/weapon/ore/gold, diff --git a/code/modules/mining/ore_redemption_machine/survey_vendor.dm b/code/modules/mining/ore_redemption_machine/survey_vendor.dm index 9956084c11d..0d15c5675aa 100644 --- a/code/modules/mining/ore_redemption_machine/survey_vendor.dm +++ b/code/modules/mining/ore_redemption_machine/survey_vendor.dm @@ -52,6 +52,7 @@ EQUIPMENT("Defense Equipment - Plasteel Machete", /obj/item/weapon/material/knife/machete, 50), EQUIPMENT("Defense Equipment - Razor Drone Deployer", /obj/item/weapon/grenade/spawnergrenade/manhacks/station/locked, 100), EQUIPMENT("Defense Equipment - Sentry Drone Deployer", /obj/item/weapon/grenade/spawnergrenade/ward, 150), + EQUIPMENT("Defense Equipment - Frontier Carbine", /obj/item/weapon/gun/energy/locked/frontier/carbine, 750), EQUIPMENT("Fishing Net", /obj/item/weapon/material/fishing_net, 50), EQUIPMENT("Titanium Fishing Rod", /obj/item/weapon/material/fishing_rod/modern, 100), EQUIPMENT("Durasteel Fishing Rod", /obj/item/weapon/material/fishing_rod/modern/strong, 750), @@ -81,6 +82,7 @@ prize_list["Digging Tools"] = list( EQUIPMENT("Survey Tools - Shovel", /obj/item/weapon/shovel, 40), EQUIPMENT("Survey Tools - Mechanical Trap", /obj/item/weapon/beartrap, 50), + EQUIPMENT("Survey Tools - Binoculars", /obj/item/device/binoculars,40), ) prize_list["Miscellaneous"] = list( EQUIPMENT("Absinthe", /obj/item/weapon/reagent_containers/food/drinks/bottle/absinthe, 10), diff --git a/code/modules/mining/shelter_atoms_vr.dm b/code/modules/mining/shelter_atoms_vr.dm index 4e24c543155..1c0fc5010e5 100644 --- a/code/modules/mining/shelter_atoms_vr.dm +++ b/code/modules/mining/shelter_atoms_vr.dm @@ -331,6 +331,9 @@ GLOBAL_LIST_EMPTY(unique_deployable) light_power = 1 light_color = "#FFFFFF" +/obj/structure/fans/hardlight/ex_act() + return + /obj/structure/fans/hardlight/colorable name = "hardlight shield" icon_state = "hardlight_colorable" diff --git a/code/modules/mob/death.dm b/code/modules/mob/death.dm index 9d6735ee8b6..1badc92926a 100644 --- a/code/modules/mob/death.dm +++ b/code/modules/mob/death.dm @@ -73,7 +73,7 @@ if(src.loc && istype(loc,/obj/belly) || istype(loc,/obj/item/device/dogborg/sleeper)) deathmessage = "no message" //VOREStation Add - Prevents death messages from inside mobs facing_dir = null - if(!gibbed && deathmessage != "no message") // This is gross, but reliable. Only brains use it. + if(!gibbed && deathmessage != DEATHGASP_NO_MESSAGE) src.visible_message("\The [src.name] [deathmessage]") set_stat(DEAD) diff --git a/code/modules/mob/emote.dm b/code/modules/mob/emote.dm index 2a8af560804..f59ebf612cd 100644 --- a/code/modules/mob/emote.dm +++ b/code/modules/mob/emote.dm @@ -1,64 +1,9 @@ -// All mobs should have custom emote, really.. -//m_type == 1 --> visual. -//m_type == 2 --> audible -/mob/proc/custom_emote(var/m_type=1,var/message = null,var/range=world.view) - if(stat || !use_me && usr == src) - to_chat(src, "You are unable to emote.") - return - - var/muzzled = is_muzzled() - if(m_type == 2 && muzzled) return - - var/input - if(!message) - input = sanitize_or_reflect(input(src,"Choose an emote to display.") as text|null, src) //VOREStation Edit - Reflect too long messages, within reason - else - input = message - if(input) - log_emote(message,src) //Log before we add junk - message = "[src] [input]" - else - return - - - if (message) - message = encode_html_emphasis(message) - - // Hearing gasp and such every five seconds is not good emotes were not global for a reason. - // Maybe some people are okay with that. - - var/turf/T = get_turf(src) - if(!T) return - var/list/in_range = get_mobs_and_objs_in_view_fast(T,range,2,remote_ghosts = client ? TRUE : FALSE) - var/list/m_viewers = in_range["mobs"] - var/list/o_viewers = in_range["objs"] - - for(var/mob in m_viewers) - var/mob/M = mob - spawn(0) // It's possible that it could be deleted in the meantime, or that it runtimes. - if(M) - if(isobserver(M)) - //VOREStation Edit Start - var/mob/observer/dead/D = M - if(ckey || (src in view(D))) - M.show_message(message, m_type) - message = "[src] ([ghost_follow_link(src, M)]) [input]" - else - M.show_message(message, m_type) - //VOREStation Edit End - - for(var/obj in o_viewers) - var/obj/O = obj - spawn(0) - if(O) - O.see_emote(src, message, m_type) - // Shortcuts for above proc /mob/proc/visible_emote(var/act_desc) - custom_emote(1, act_desc) + custom_emote(VISIBLE_MESSAGE, act_desc) /mob/proc/audible_emote(var/act_desc) - custom_emote(2, act_desc) + custom_emote(AUDIBLE_MESSAGE, act_desc) /mob/proc/emote_dead(var/message) diff --git a/code/modules/mob/living/bot/cleanbot.dm b/code/modules/mob/living/bot/cleanbot.dm index cdcba151bc3..e012fdee222 100644 --- a/code/modules/mob/living/bot/cleanbot.dm +++ b/code/modules/mob/living/bot/cleanbot.dm @@ -10,6 +10,7 @@ wait_if_pulled = 1 min_target_dist = 0 + var/vocal = 1 var/cleaning = 0 var/wet_floors = 0 var/spray_blood = 0 @@ -26,7 +27,7 @@ return ..() /mob/living/bot/cleanbot/handleIdle() - if(!wet_floors && !spray_blood && prob(2)) + if(!wet_floors && !spray_blood && vocal && prob(2)) custom_emote(2, "makes an excited booping sound!") playsound(src, 'sound/machines/synth_yes.ogg', 50, 0) @@ -163,9 +164,10 @@ data["on"] = on data["open"] = open data["locked"] = locked - + data["blood"] = blood data["patrol"] = will_patrol + data["vocal"] = vocal data["wet_floors"] = wet_floors data["spray_blood"] = spray_blood @@ -192,6 +194,9 @@ will_patrol = !will_patrol patrol_path = null . = TRUE + if("vocal") + vocal = !vocal + . = TRUE if("wet_floors") wet_floors = !wet_floors to_chat(usr, "You twiddle the screw.") diff --git a/code/modules/mob/living/bot/edCLNbot.dm b/code/modules/mob/living/bot/edCLNbot.dm index b4d3dfbccaa..a0b0dc31450 100644 --- a/code/modules/mob/living/bot/edCLNbot.dm +++ b/code/modules/mob/living/bot/edCLNbot.dm @@ -12,6 +12,7 @@ patrol_speed = 3 target_speed = 6 + vocal = 1 cleaning = 0 blood = 0 var/red_switch = 0 @@ -25,7 +26,7 @@ icon_state = "edCLN[on]" /mob/living/bot/cleanbot/edCLN/handleIdle() - if(prob(10)) + if(vocal && prob(10)) custom_emote(2, "makes a less than thrilled beeping sound.") playsound(src, 'sound/machines/synth_yes.ogg', 50, 0) diff --git a/code/modules/mob/living/bot/farmbot.dm b/code/modules/mob/living/bot/farmbot.dm index 9334fbbcec2..01d9702aa81 100644 --- a/code/modules/mob/living/bot/farmbot.dm +++ b/code/modules/mob/living/bot/farmbot.dm @@ -96,9 +96,18 @@ turn_on() . = TRUE + switch(action) + if("power") + if(!access_scanner.allowed(src)) + return FALSE + if(on) + turn_off() + else + turn_on() + . = TRUE + if(locked) return TRUE - switch(action) if("water") waters_trays = !waters_trays diff --git a/code/modules/mob/living/bot/floorbot.dm b/code/modules/mob/living/bot/floorbot.dm index 31d1dc0e256..54fbc8403cb 100644 --- a/code/modules/mob/living/bot/floorbot.dm +++ b/code/modules/mob/living/bot/floorbot.dm @@ -12,6 +12,7 @@ wait_if_pulled = 1 min_target_dist = 0 + var/vocal = 1 var/amount = 10 // 1 for tile, 2 for lattice var/maxAmount = 60 var/tilemake = 0 // When it reaches 100, bot makes a tile @@ -41,7 +42,8 @@ data["on"] = on data["open"] = open data["locked"] = locked - + + data["vocal"] = vocal data["amount"] = amount data["possible_bmode"] = list("NORTH", "EAST", "SOUTH", "WEST") @@ -56,7 +58,6 @@ data["eattiles"] = eattiles data["maketiles"] = maketiles data["bmode"] = dir2text(targetdirection) - return data /mob/living/bot/floorbot/attack_hand(var/mob/user) @@ -74,8 +75,8 @@ /mob/living/bot/floorbot/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) if(..()) return TRUE - - add_fingerprint(usr) + + add_fingerprint(src) switch(action) if("start") @@ -84,11 +85,14 @@ else turn_on() . = TRUE - + if(locked && !issilicon(usr)) return switch(action) + if("vocal") + vocal = !vocal + . = TRUE if("improve") improvefloors = !improvefloors . = TRUE @@ -108,7 +112,7 @@ tilemake = 0 addTiles(1) - if(prob(1)) + if(vocal && prob(1)) custom_emote(2, "makes an excited beeping sound!") playsound(src, 'sound/machines/twobeep.ogg', 50, 0) diff --git a/code/modules/mob/living/bot/medbot.dm b/code/modules/mob/living/bot/medbot.dm index 828ca72da0c..6592c37e0c2 100644 --- a/code/modules/mob/living/bot/medbot.dm +++ b/code/modules/mob/living/bot/medbot.dm @@ -312,7 +312,6 @@ declare_treatment = !declare_treatment . = TRUE - /mob/living/bot/medbot/emag_act(var/remaining_uses, var/mob/user) . = ..() if(!emagged) diff --git a/code/modules/mob/living/bot/mulebot.dm b/code/modules/mob/living/bot/mulebot.dm index fa0b76009f1..92cc55f7f06 100644 --- a/code/modules/mob/living/bot/mulebot.dm +++ b/code/modules/mob/living/bot/mulebot.dm @@ -70,17 +70,16 @@ ui.open() /mob/living/bot/mulebot/tgui_data(mob/user) - var/list/data = list( - "suffix" = suffix, - "power" = on, - "issilicon" = issilicon(user), - "load" = load, - "locked" = locked, - "auto_return" = auto_return, - "crates_only" = crates_only, - "hatch" = open, - "safety" = safety, - ) + var/list/data = ..() + data["suffix"] = suffix + data["power"] = on + data["issillicon"] = issilicon(user) + data["load"] = load + data["locked"] = locked + data["auto_return"] = auto_return + data["crates_only"] = crates_only + data["hatch"] = open + data["safety"] = safety return data /mob/living/bot/mulebot/tgui_act(action, params) diff --git a/code/modules/mob/living/bot/secbot.dm b/code/modules/mob/living/bot/secbot.dm index 583b2d7af6a..9e2ce96412e 100644 --- a/code/modules/mob/living/bot/secbot.dm +++ b/code/modules/mob/living/bot/secbot.dm @@ -108,6 +108,7 @@ data["check_arrest"] = null data["arrest_type"] = null data["declare_arrests"] = null + data["bot_patrolling"] = null data["will_patrol"] = null if(!locked || issilicon(user)) @@ -116,8 +117,8 @@ data["check_arrest"] = check_arrest data["arrest_type"] = arrest_type data["declare_arrests"] = declare_arrests - if(using_map.bot_patrolling) - data["will_patrol"] = will_patrol + data["bot_patrolling"] = using_map.bot_patrolling + data["patrol"] = will_patrol return data @@ -127,7 +128,7 @@ /mob/living/bot/secbot/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) if(..()) return - + add_fingerprint(usr) switch(action) diff --git a/code/modules/mob/living/carbon/alien/diona/diona.dm b/code/modules/mob/living/carbon/alien/diona/diona.dm index 01f1d2f57d2..739c3b09c6b 100644 --- a/code/modules/mob/living/carbon/alien/diona/diona.dm +++ b/code/modules/mob/living/carbon/alien/diona/diona.dm @@ -1,3 +1,29 @@ +var/list/_nymph_default_emotes = list( + /decl/emote/visible, + /decl/emote/visible/scratch, + /decl/emote/visible/drool, + /decl/emote/visible/nod, + /decl/emote/visible/sway, + /decl/emote/visible/sulk, + /decl/emote/visible/twitch, + /decl/emote/visible/dance, + /decl/emote/visible/roll, + /decl/emote/visible/shake, + /decl/emote/visible/jump, + /decl/emote/visible/shiver, + /decl/emote/visible/collapse, + /decl/emote/visible/spin, + /decl/emote/visible/sidestep, + /decl/emote/audible/hiss, + /decl/emote/audible, + /decl/emote/audible/scretch, + /decl/emote/audible/choke, + /decl/emote/audible/gnarl, + /decl/emote/audible/bug_hiss, + /decl/emote/audible/bug_chitter, + /decl/emote/audible/chirp +) + /mob/living/carbon/alien/diona name = "diona nymph" voice_name = "diona nymph" @@ -20,6 +46,9 @@ holder_type = /obj/item/weapon/holder/diona var/obj/item/hat +/mob/living/carbon/alien/diona/get_default_emotes() + return global._nymph_default_emotes + /mob/living/carbon/alien/diona/Initialize() . = ..() species = GLOB.all_species[SPECIES_DIONA] diff --git a/code/modules/mob/living/carbon/alien/emote.dm b/code/modules/mob/living/carbon/alien/emote.dm index 5cff048e10b..b0517e7a952 100644 --- a/code/modules/mob/living/carbon/alien/emote.dm +++ b/code/modules/mob/living/carbon/alien/emote.dm @@ -1,108 +1,31 @@ -/mob/living/carbon/alien/emote(var/act, var/m_type=1, var/message = null) - var/param = null - if(findtext(act, "-", 1, null)) - var/t1 = findtext(act, "-", 1, null) - param = copytext(act, t1 + 1, length(act) + 1) - act = copytext(act, 1, t1) +var/list/_alien_default_emotes = list( + /decl/emote/visible, + /decl/emote/visible/scratch, + /decl/emote/visible/drool, + /decl/emote/visible/nod, + /decl/emote/visible/sway, + /decl/emote/visible/sulk, + /decl/emote/visible/twitch, + /decl/emote/visible/twitch_v, + /decl/emote/visible/dance, + /decl/emote/visible/roll, + /decl/emote/visible/shake, + /decl/emote/visible/jump, + /decl/emote/visible/shiver, + /decl/emote/visible/collapse, + /decl/emote/visible/spin, + /decl/emote/visible/sidestep, + /decl/emote/audible/hiss, + /decl/emote/audible, + /decl/emote/audible/deathgasp_alien, + /decl/emote/audible/whimper, + /decl/emote/audible/gasp, + /decl/emote/audible/scretch, + /decl/emote/audible/choke, + /decl/emote/audible/moan, + /decl/emote/audible/gnarl, + /decl/emote/audible/chirp +) - var/muzzled = is_muzzled() - act = lowertext(act) - - switch(act) - if("sign") - if(!restrained()) - var/num = null - if(text2num(param)) - num = "the number [text2num(param)]" - if(num) - message = "[src] signs [num]." - m_type = 1 - if("burp") - if(!muzzled) - message = "[src] burps." - m_type = 2 - if("deathgasp") - message = "[src] lets out a waning guttural screech, green blood bubbling from its maw." - m_type = 2 - if("scratch") - if(!restrained()) - message = "[src] scratches." - m_type = 1 - if("whimper") - if(!muzzled) - message = "[src] whimpers." - m_type = 2 - if("tail") - message = "[src] waves its tail." - m_type = 1 - if("gasp") - message = "[src] gasps." - m_type = 2 - if("shiver") - message = "[src] shivers." - m_type = 2 - if("drool") - message = "[src] drools." - m_type = 1 - if("scretch") - if(!muzzled) - message = "[src] scretches." - m_type = 2 - if("choke") - message = "[src] chokes." - m_type = 2 - if("moan") - message = "[src] moans!" - m_type = 2 - if("nod") - message = "[src] nods its head." - m_type = 1 -// if("sit") -// message = "[src] sits down." //Larvan can't sit down, /N -// m_type = 1 - if("sway") - message = "[src] sways around dizzily." - m_type = 1 - if("sulk") - message = "[src] sulks down sadly." - m_type = 1 - if("twitch") - message = "[src] twitches." - m_type = 1 - if("twitch_v") - message = "[src] twitches violently." - m_type = 1 - if("dance") - if(!restrained()) - message = "[src] dances around happily." - m_type = 1 - if("roll") - if(!restrained()) - message = "[src] rolls." - m_type = 1 - if("shake") - message = "[src] shakes its head." - m_type = 1 - if("gnarl") - if(!muzzled) - message = "[src] gnarls and shows its teeth.." - m_type = 2 - if("jump") - message = "[src] jumps!" - m_type = 1 - if("hiss_") - message = "[src] hisses softly." - m_type = 1 - if("collapse") - Paralyse(2) - message = "[src] collapses!" - m_type = 2 - if("chirp") - message = "[src] chirps!" - playsound(src, 'sound/misc/nymphchirp.ogg', 50, 0) - m_type = 2 - if("help") - to_chat(src, "burp, chirp, choke, collapse, dance, drool, gasp, shiver, gnarl, jump, moan, nod, roll, scratch,\nscretch, shake, sign-#, sulk, sway, tail, twitch, whimper") - - if(!stat) - ..(act, m_type, message) +/mob/living/carbon/alien/get_default_emotes() + . = global._alien_default_emotes diff --git a/code/modules/mob/living/carbon/brain/death.dm b/code/modules/mob/living/carbon/brain/death.dm index 8b6e7f71756..687372c6ee1 100644 --- a/code/modules/mob/living/carbon/brain/death.dm +++ b/code/modules/mob/living/carbon/brain/death.dm @@ -3,7 +3,7 @@ container.icon_state = "mmi_dead" return ..(gibbed,"beeps shrilly as the MMI flatlines!") else - return ..(gibbed,"no message") + return ..(gibbed, DEATHGASP_NO_MESSAGE) /mob/living/carbon/brain/gib() if(istype(container, /obj/item/device/mmi)) diff --git a/code/modules/mob/living/carbon/brain/emote.dm b/code/modules/mob/living/carbon/brain/emote.dm index 05706fe299e..cb6ed6a1b7b 100644 --- a/code/modules/mob/living/carbon/brain/emote.dm +++ b/code/modules/mob/living/carbon/brain/emote.dm @@ -1,47 +1,17 @@ -/mob/living/carbon/brain/emote(var/act,var/m_type=1,var/message = null) - if(!(container && istype(container, /obj/item/device/mmi)))//No MMI, no emotes - return +var/list/_brain_default_emotes = list( + /decl/emote/audible/alarm, + /decl/emote/audible/alert, + /decl/emote/audible/notice, + /decl/emote/audible/whistle, + /decl/emote/audible/synth, + /decl/emote/audible/beep, + /decl/emote/audible/boop, + /decl/emote/visible/blink, + /decl/emote/visible/flash +) - if(findtext(act, "-", 1, null)) - var/t1 = findtext(act, "-", 1, null) - act = copytext(act, 1, t1) +/mob/living/carbon/brain/can_emote() + return (istype(container, /obj/item/device/mmi) && ..()) - if(stat == DEAD) - return - switch(act) - if("alarm") - to_chat(src, "You sound an alarm.") - message = "[src] sounds an alarm." - m_type = 2 - if("alert") - to_chat(src, "You let out a distressed noise.") - message = "[src] lets out a distressed noise." - m_type = 2 - if("notice") - to_chat(src, "You play a loud tone.") - message = "[src] plays a loud tone." - m_type = 2 - if("flash") - message = "The lights on [src] flash quickly." - m_type = 1 - if("blink") - message = "[src] blinks." - m_type = 1 - if("whistle") - to_chat(src, "You whistle.") - message = "[src] whistles." - m_type = 2 - if("beep") - to_chat(src, "You beep.") - message = "[src] beeps." - m_type = 2 - if("boop") - to_chat(src, "You boop.") - message = "[src] boops." - m_type = 2 - if("help") - to_chat(src, "alarm, alert, notice, flash, blink, whistle, beep, boop") - - if(!stat) - ..(act, m_type, message) - \ No newline at end of file +/mob/living/carbon/brain/get_default_emotes() + return global._brain_default_emotes diff --git a/code/modules/mob/living/carbon/human/MedicalSideEffects.dm b/code/modules/mob/living/carbon/human/MedicalSideEffects.dm index 91622f806df..9af29570741 100644 --- a/code/modules/mob/living/carbon/human/MedicalSideEffects.dm +++ b/code/modules/mob/living/carbon/human/MedicalSideEffects.dm @@ -127,7 +127,7 @@ if(11 to 30) H.custom_pain("The muscles in your body cramp up painfully.",0) if(31 to INFINITY) - H.emote("me",1,"flinches as all the muscles in their body cramp up.") + H.custom_emote(VISIBLE_MESSAGE, "flinches as all the muscles in their body cramp up.") H.custom_pain("There's pain all over your body.",1) // ITCH @@ -145,5 +145,5 @@ if(11 to 30) H.custom_pain("You want to scratch your itch badly.",0) if(31 to INFINITY) - H.emote("me",1,"shivers slightly.") + H.custom_emote(VISIBLE_MESSAGE, "shivers slightly.") H.custom_pain("This itch makes it really hard to concentrate.",1) diff --git a/code/modules/mob/living/carbon/human/chem_side_effects.dm b/code/modules/mob/living/carbon/human/chem_side_effects.dm index 91622f806df..9af29570741 100644 --- a/code/modules/mob/living/carbon/human/chem_side_effects.dm +++ b/code/modules/mob/living/carbon/human/chem_side_effects.dm @@ -127,7 +127,7 @@ if(11 to 30) H.custom_pain("The muscles in your body cramp up painfully.",0) if(31 to INFINITY) - H.emote("me",1,"flinches as all the muscles in their body cramp up.") + H.custom_emote(VISIBLE_MESSAGE, "flinches as all the muscles in their body cramp up.") H.custom_pain("There's pain all over your body.",1) // ITCH @@ -145,5 +145,5 @@ if(11 to 30) H.custom_pain("You want to scratch your itch badly.",0) if(31 to INFINITY) - H.emote("me",1,"shivers slightly.") + H.custom_emote(VISIBLE_MESSAGE, "shivers slightly.") H.custom_pain("This itch makes it really hard to concentrate.",1) diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm index 6afe10cdec7..a705f034506 100644 --- a/code/modules/mob/living/carbon/human/emote.dm +++ b/code/modules/mob/living/carbon/human/emote.dm @@ -1,843 +1,140 @@ -/mob/living/carbon/human/emote(var/act,var/m_type=1,var/message = null) - var/param = null - - var/datum/gender/T = gender_datums[get_visible_gender()] - - if(findtext(act, "-", 1, null)) - var/t1 = findtext(act, "-", 1, null) - param = copytext(act, t1 + 1, length(act) + 1) - act = copytext(act, 1, t1) - - var/muzzled = is_muzzled() - //var/m_type = 1 - - for(var/obj/item/organ/O in organs) - for(var/obj/item/weapon/implant/I in O) - if(I.implanted) - I.trigger(act, src) - - if(stat == DEAD && (act != "deathgasp")) - return - - if(attempt_vr(src, "handle_emote_vr", list(act, m_type, message))) return //VOREStation Add - Custom Emote Handler - - switch(act) - if("airguitar") - if(!restrained()) - message = "is strumming the air and headbanging like a safari chimp." - m_type = 1 - - //Machine-only emotes - if("ping", "beep", "buzz", "yes", "ye", "dwoop", "no", "rcough", "rsneeze") - - if(!isSynthetic()) - to_chat(src, "You are not a synthetic.") - return - - var/M = null - if(param) - for(var/mob/A in view(null, null)) - if(param == A.name) - M = A - break - if(!M) - param = null - - var/display_msg = "beeps" - var/use_sound = 'sound/machines/twobeep.ogg' - if(act == "buzz") - display_msg = "buzzes" - use_sound = 'sound/machines/buzz-sigh.ogg' - else if(act == "ping") - display_msg = "pings" - use_sound = 'sound/machines/ping.ogg' - else if(act == "yes" || act == "ye") - display_msg = "emits an affirmative blip" - use_sound = 'sound/machines/synth_yes.ogg' - else if(act == "dwoop") - display_msg = "chirps happily" - use_sound = 'sound/machines/dwoop.ogg' - else if(act == "no") - display_msg = "emits a negative blip" - use_sound = 'sound/machines/synth_no.ogg' - else if(act == "rcough") - display_msg = "emits a robotic cough" - if(get_gender() == FEMALE) - use_sound = pick('sound/effects/mob_effects/f_machine_cougha.ogg','sound/effects/mob_effects/f_machine_coughb.ogg') - else - use_sound = pick('sound/effects/mob_effects/m_machine_cougha.ogg','sound/effects/mob_effects/m_machine_coughb.ogg', 'sound/effects/mob_effects/m_machine_coughc.ogg') - else if(act == "rsneeze") - display_msg = "emits a robotic sneeze" - if(get_gender() == FEMALE) - use_sound = 'sound/effects/mob_effects/machine_sneeze.ogg' - else - use_sound = 'sound/effects/mob_effects/f_machine_sneeze.ogg' - - if(param) - message = "[display_msg] at [param]." - else - message = "[display_msg]." - playsound(src, use_sound, 50, 0, preference = /datum/client_preference/emote_noises) //VOREStation Add - m_type = 1 - - //Promethean-only emotes - if("squish") - /* VOREStation Removal Start - Eh. People can squish maybe. - if(species.bump_flag != SLIME) //This should definitely do it. - to_chat(src, "You are not a slime thing!") - return - */ //VOREStation Removal End - playsound(src, 'sound/effects/slime_squish.ogg', 50, 0, preference = /datum/client_preference/emote_noises) //VOREStation Add //Credit to DrMinky (freesound.org) for the sound. - message = "squishes." - m_type = 1 - - if("chirp") - /* VOREStation Removal Start - Eh. People can chirp maybe. - if ((species.bump_flag != SLIME) && (species.name != SPECIES_DIONA)) - to_chat(src, "You are not a diona or slime!") - return - */ //VOREStation Removal End - playsound(src, 'sound/misc/nymphchirp.ogg', 50, 0) - message = "chirps." - m_type = 2 - - //Skrell-only emotes - if("warble") - if(species.name != SPECIES_SKRELL) - to_chat(src, "You are not a Skrell!") - return - - playsound(src, 'sound/effects/warble.ogg', 50, 0, preference = /datum/client_preference/emote_noises) //VOREStation Add // Copyright CC BY 3.0 alienistcog (freesound.org) for the sound. - message = "warbles." - m_type = 2 - - if("blink") - message = "blinks." - m_type = 1 - - if("blink_r") - message = "blinks rapidly." - m_type = 1 - - if("bow") - if(!buckled) - var/M = null - if(param) - for(var/mob/A in view(null, null)) - if(param == A.name) - M = A - break - if(!M) - param = null - - if(param) - message = "bows to [param]." - else - message = "bows." - m_type = 1 - - if("custom") - var/input = sanitize(input("Choose an emote to display.") as text|null) - if(!input) - return - var/input2 = input("Is this a visible or hearable emote?") in list("Visible","Hearable") - if(input2 == "Visible") - m_type = 1 - else if(input2 == "Hearable") - if(miming) - return - m_type = 2 - else - alert("Unable to use this emote, must be either hearable or visible.") - return - return custom_emote(m_type, input) - - if("me") - - //if(silent && silent > 0 && findtext(message,"\"",1, null) > 0) - // return //This check does not work and I have no idea why, I'm leaving it in for reference. - - if(client) - if(client.prefs.muted & MUTE_IC) - to_chat(src, "You cannot send IC messages (muted).") - return - if(stat) - return - if(!(message)) - return - return custom_emote(m_type, message) - - if("salute") - if(!buckled) - var/M = null - if(param) - for(var/mob/A in view(null, null)) - if(param == A.name) - M = A - break - if(!M) - param = null - - if(param) - message = "salutes to [param]." - else - message = "salutes." - m_type = 1 - - if("choke") - if(miming) - message = "clutches [T.his] throat desperately!" - m_type = 1 - else - if(!muzzled) - message = "chokes!" - m_type = 2 - else - message = "makes a strong noise." - m_type = 2 - - if("clap") - if(!restrained()) - message = "claps." - playsound(src, 'sound/misc/clapping.ogg') - m_type = 2 - if(miming) - m_type = 1 - - if("flap") - if(!restrained()) - message = "flaps [T.his] wings." - m_type = 2 - if(miming) - m_type = 1 - - if("aflap") - if(!restrained()) - message = "flaps [T.his] wings ANGRILY!" - m_type = 2 - if(miming) - m_type = 1 - - if("drool") - message = "drools." - m_type = 1 - - if("eyebrow") - message = "raises an eyebrow." - m_type = 1 - - if("chuckle") - if(miming) - message = "appears to chuckle." - m_type = 1 - else - if(!muzzled) - message = "chuckles." - m_type = 2 - else - message = "makes a noise." - m_type = 2 - - if("twitch") - message = "twitches." - m_type = 1 - - if("twitch_v") - message = "twitches violently." - m_type = 1 - - if("faint") - message = "faints." - if(sleeping) - return //Can't faint while asleep - Sleeping(10) - m_type = 1 - - if("cough", "coughs") - if(miming) - message = "appears to cough!" - m_type = 1 - else - if(!muzzled) - var/robotic = 0 - m_type = 2 - if(should_have_organ(O_LUNGS)) - var/obj/item/organ/internal/lungs/L = internal_organs_by_name[O_LUNGS] - if(L && L.robotic == 2) //Hard-coded to 2, incase we add lifelike robotic lungs - robotic = 1 - if(!robotic && !isSynthetic()) - message = "coughs!" - if(get_gender() == FEMALE) - if(species.female_cough_sounds) - playsound(src, pick(species.female_cough_sounds), 120, preference = /datum/client_preference/emote_noises) //VOREStation Add - else - if(species.male_cough_sounds) - playsound(src, pick(species.male_cough_sounds), 120, preference = /datum/client_preference/emote_noises) //VOREStation Add - else - message = "emits a robotic cough" - var/use_sound - if(get_gender() == FEMALE) - use_sound = pick('sound/effects/mob_effects/f_machine_cougha.ogg','sound/effects/mob_effects/f_machine_coughb.ogg') - else - use_sound = pick('sound/effects/mob_effects/m_machine_cougha.ogg','sound/effects/mob_effects/m_machine_coughb.ogg', 'sound/effects/mob_effects/m_machine_coughc.ogg') - playsound(src, use_sound, 50, 0, preference = /datum/client_preference/emote_noises) //VOREStation Add - else - message = "makes a strong noise." - m_type = 2 - - if("frown") - message = "frowns." - m_type = 1 - - if("nod") - message = "nods." - m_type = 1 - - if("blush") - message = "blushes." - m_type = 1 - - if("wave") - message = "waves." - m_type = 1 - - if("gasp") - if(miming) - message = "appears to be gasping!" - m_type = 1 - else - if(!muzzled) - message = "gasps!" - m_type = 2 - else - message = "makes a weak noise." - m_type = 2 - - if("deathgasp") - message = "[species.get_death_message()]" - m_type = 1 - - if("giggle") - if(miming) - message = "giggles silently!" - m_type = 1 - else - if(!muzzled) - message = "giggles." - m_type = 2 - else - message = "makes a noise." - m_type = 2 - - if("glare") - var/M = null - if(param) - for(var/mob/A in view(null, null)) - if(param == A.name) - M = A - break - if(!M) - param = null - - if(param) - message = "glares at [param]." - else - message = "glares." - - if("stare") - var/M = null - if(param) - for(var/mob/A in view(null, null)) - if(param == A.name) - M = A - break - if(!M) - param = null - - if(param) - message = "stares at [param]." - else - message = "stares." - - if("look") - var/M = null - if(param) - for(var/mob/A in view(null, null)) - if(param == A.name) - M = A - break - - if(!M) - param = null - - if(param) - message = "looks at [param]." - else - message = "looks." - m_type = 1 - - if("grin") - message = "grins." - m_type = 1 - - if("cry") - if(miming) - message = "cries." - m_type = 1 - else - if(!muzzled) - message = "cries." - m_type = 2 - else - message = "makes a weak noise. [T.he] [get_visible_gender() == NEUTER ? "frown" : "frowns"]." // no good, non-unwieldy alternative to this ternary at the moment - m_type = 2 - - if("sigh") - if(miming) - message = "sighs." - m_type = 1 - else - if(!muzzled) - message = "sighs." - m_type = 2 - else - message = "makes a weak noise." - m_type = 2 - - if("laugh") - if(miming) - message = "acts out a laugh." - m_type = 1 - else - if(!muzzled) - message = "laughs." - m_type = 2 - else - message = "makes a noise." - m_type = 2 - - if("mumble") - message = "mumbles!" - m_type = 2 - if(miming) - m_type = 1 - - if("grumble") - if(miming) - message = "grumbles!" - m_type = 1 - if(!muzzled) - message = "grumbles!" - m_type = 2 - else - message = "makes a noise." - m_type = 2 - - if("groan") - if(miming) - message = "appears to groan!" - m_type = 1 - else - if(!muzzled) - message = "groans!" - m_type = 2 - else - message = "makes a loud noise." - m_type = 2 - - if("moan") - if(miming) - message = "appears to moan!" - m_type = 1 - else - message = "moans!" - m_type = 2 - - if("johnny") - var/M - if(param) - M = param - if(!M) - param = null - else - if(miming) - message = "takes a drag from a cigarette and blows \"[M]\" out in smoke." - m_type = 1 - else - message = "says, \"[M], please. He had a family.\" [name] takes a drag from a cigarette and blows his name out in smoke." - m_type = 2 - - if("point") - if(!restrained()) - var/mob/M = null - if(param) - for(var/atom/A as mob|obj|turf|area in view(null, null)) - if(param == A.name) - M = A - break - - if(!M) - message = "points." - else - pointed(M) - - if(M) - message = "points to [M]." - else - m_type = 1 - - if("crack") - if(!restrained()) - message = "cracks [T.his] knuckles." - playsound(src, 'sound/voice/knuckles.ogg', 50, 1, preference = /datum/client_preference/emote_noises) - m_type = 1 - - if("raise") - if(!restrained()) - message = "raises a hand." - m_type = 1 - - if("shake") - message = "shakes [T.his] head." - m_type = 1 - - if("shrug") - message = "shrugs." - m_type = 1 - - if("signal") - if(!restrained()) - var/t1 = round(text2num(param)) - if(isnum(t1)) - if(t1 <= 5 && (!r_hand || !l_hand)) - message = "raises [t1] finger\s." - else if(t1 <= 10 && (!r_hand && !l_hand)) - message = "raises [t1] finger\s." - m_type = 1 - - if("smile") - message = "smiles." - m_type = 1 - - if("shiver") - message = "shivers." - m_type = 2 - if(miming) - m_type = 1 - - if("pale") - message = "goes pale for a second." - m_type = 1 - - if("tremble") - message = "trembles in fear!" - m_type = 1 - - if("sneeze", "sneezes") - if(miming) - message = "sneezes." - m_type = 1 - else - if(!muzzled) - var/robotic = 0 - m_type = 2 - if(should_have_organ(O_LUNGS)) - var/obj/item/organ/internal/lungs/L = internal_organs_by_name[O_LUNGS] - if(L && L.robotic == 2) //Hard-coded to 2, incase we add lifelike robotic lungs - robotic = 1 - if(!robotic && !isSynthetic()) - message = "sneezes." - if(get_gender() == FEMALE) - playsound(src, species.female_sneeze_sound, 70, preference = /datum/client_preference/emote_noises) //VOREStation Add - else - playsound(src, species.male_sneeze_sound, 70, preference = /datum/client_preference/emote_noises) //VOREStation Add - m_type = 2 - else - message = "emits a robotic sneeze" - var/use_sound - if(get_gender() == FEMALE) - use_sound = 'sound/effects/mob_effects/machine_sneeze.ogg' - else - use_sound = 'sound/effects/mob_effects/f_machine_sneeze.ogg' - playsound(src, use_sound, 50, 0, preference = /datum/client_preference/emote_noises) //VOREStation Add - else - message = "makes a strange noise." - m_type = 2 - - if("sniff") - message = "sniffs." - m_type = 2 - if(miming) - m_type = 1 - - if("snore") - if(miming) - message = "sleeps soundly." - m_type = 1 - else - if(!muzzled) - message = "snores." - m_type = 2 - else - message = "makes a noise." - m_type = 2 - - if("whimper") - if(miming) - message = "appears hurt." - m_type = 1 - else - if(!muzzled) - message = "whimpers." - m_type = 2 - else - message = "makes a weak noise." - m_type = 2 - - if("wink") - message = "winks." - m_type = 1 - - if("yawn") - if(!muzzled) - message = "yawns." - m_type = 2 - if(miming) - m_type = 1 - - if("collapse") - Paralyse(2) - message = "collapses!" - m_type = 2 - if(miming) - m_type = 1 - - if("hug") - m_type = 1 - if(!restrained()) - var/M = null - if(param) - for(var/mob/A in view(1, null)) - if(param == A.name) - M = A - break - if(M == src) - M = null - - if(M) - message = "hugs [M]." - else - message = "hugs [T.himself]." - - if("handshake") - m_type = 1 - if(!restrained() && !r_hand) - var/mob/living/M = null - if(param) - for(var/mob/living/A in view(1, null)) - if(param == A.name) - M = A - break - if(M == src) - M = null - - if(M) - if(M.canmove && !M.r_hand && !M.restrained()) - message = "shakes hands with [M]." - else - message = "holds out [T.his] hand to [M]." - - if("dap") - m_type = 1 - if(!restrained()) - var/M = null - if(param) - for(var/mob/A in view(1, null)) - if(param == A.name) - M = A - break - if(M) - message = "gives daps to [M]." - else - message = "sadly can't find anybody to give daps to, and daps [T.himself]. Shameful." - - if("slap", "slaps") - m_type = 1 - if(!restrained()) - var/M = null - if(param) - for(var/mob/A in view(1, null)) - if(param == A.name) - M = A - break - if(M) - message = "slaps [M] across the face. Ouch!" - playsound(src, 'sound/effects/snap.ogg', 50, 1, preference = /datum/client_preference/emote_noises) //VOREStation Add - if(ishuman(M)) //Snowflakey! - var/mob/living/carbon/human/H = M - if(istype(H.wear_mask,/obj/item/clothing/mask/smokable)) - H.drop_from_inventory(H.wear_mask) - else - message = "slaps [T.himself]!" - playsound(src, 'sound/effects/snap.ogg', 50, 1, preference = /datum/client_preference/emote_noises) //VOREStation Add - - if("scream", "screams") - if(miming) - message = "acts out a scream!" - m_type = 1 - else - if(!muzzled) - message = "[species.scream_verb]!" - m_type = 2 - /* Removed, pending the location of some actually good, properly licensed sounds. - if(get_gender() == FEMALE) - playsound(src, "[species.female_scream_sound]", 80, 1) - else - playsound(src, "[species.male_scream_sound]", 80, 1) //default to male screams if no gender is present. - */ - else - message = "makes a very loud noise." - m_type = 2 - - if("snap", "snaps") - m_type = 2 - var/mob/living/carbon/human/H = src - var/obj/item/organ/external/L = H.get_organ("l_hand") - var/obj/item/organ/external/R = H.get_organ("r_hand") - var/left_hand_good = 0 - var/right_hand_good = 0 - if(L && (!(L.status & ORGAN_DESTROYED)) && (!(L.splinted)) && (!(L.status & ORGAN_BROKEN))) - left_hand_good = 1 - if(R && (!(R.status & ORGAN_DESTROYED)) && (!(R.splinted)) && (!(R.status & ORGAN_BROKEN))) - right_hand_good = 1 - - if(!left_hand_good && !right_hand_good) - to_chat(usr, "You need at least one hand in good working order to snap your fingers.") - return - - message = "snaps [T.his] fingers." - playsound(src, 'sound/effects/fingersnap.ogg', 50, 1, -3, preference = /datum/client_preference/emote_noises) //VOREStation Add - - if("swish") - animate_tail_once() - - if("wag", "sway") - animate_tail_start() - - if("qwag", "fastsway") - animate_tail_fast() - - if("swag", "stopsway") - animate_tail_stop() - - if("vomit") - if(isSynthetic()) - to_chat(src, "You are unable to vomit.") - return - vomit() - return - - if("whistle" || "whistles") - if(!muzzled) - if(!isSynthetic()) - message = "whistles a tune." - playsound(src, 'sound/voice/longwhistle.ogg', 50, 1, preference = /datum/client_preference/emote_noises) //praying this doesn't get abused - else - message = "whistles a robotic tune." - playsound(src, 'sound/voice/longwhistle_robot.ogg', 50, 1, preference = /datum/client_preference/emote_noises) - else - message = "makes a light spitting noise, a poor attempt at a whistle." - - if("qwhistle") - if(!muzzled) - if(!isSynthetic()) - message = "whistles quietly." - playsound(src, 'sound/voice/shortwhistle.ogg', 50, 1, preference = /datum/client_preference/emote_noises) - else - message = "whistles robotically." - playsound(src, 'sound/voice/shortwhistle_robot.ogg', 50, 1, preference = /datum/client_preference/emote_noises) - else - message = "makes a light spitting noise, a poor attempt at a whistle." - - if("wwhistle") - if(!muzzled) - if(!isSynthetic()) - message = "whistles inappropriately." - playsound(src, 'sound/voice/wolfwhistle.ogg', 50, 1, preference = /datum/client_preference/emote_noises) - else - message = "beeps inappropriately." - playsound(src, 'sound/voice/wolfwhistle_robot.ogg', 50, 1, preference = /datum/client_preference/emote_noises) - else - message = "makes a light spitting noise, a poor attempt at a whistle." - - if("swhistle") - if(!muzzled) - if(!isSynthetic()) - message = "summon whistles." - playsound(src, 'sound/voice/summon_whistle.ogg', 50, 1, preference = /datum/client_preference/emote_noises) - else - message = "summon whistles robotically." - playsound(src, 'sound/voice/summon_whistle_robot.ogg', 50, 1, preference = /datum/client_preference/emote_noises) - else - message = "makes a light spitting noise, a poor attempt at a whistle." - - if("flip") - m_type = 1 - if (!src.restrained()) - //message = "performs an amazing, gravity-defying backflip before landing skillfully back to the ground." - playsound(src.loc, 'sound/effects/bodyfall4.ogg', 50, 1) - src.SpinAnimation(7,1) - else - to_chat(usr, "You can't quite do something as difficult as a backflip while so... restricted.") - - if("spin") - m_type = 1 - if (!src.restrained()) - //message = "spins in a dance smoothly on their feet. Wow!" - src.spin(20, 1) - else - to_chat(usr, "You can't quite do something as difficult as a spin while so... restricted.") - - if("floorspin") - m_type = 1 - if (!src.restrained()) - //message = "gets down on the floor and spins their entire body around!" - spawn(0) - for(var/i in list(1,2,4,8,4,2,1,2,4,8,4,2,1,2,4,8,4,2)) - set_dir(i) - sleep(1) - src.SpinAnimation(20,1) - else - to_chat(usr, "You can't quite do something as difficult as a spin while so... restricted.") - - if("sidestep") - m_type = 1 - if (!src.restrained()) - //message = "steps rhymatically and conservatively as they move side to side." - playsound(src.loc, 'sound/effects/bodyfall4.ogg', 50, 1) - var/default_pixel_x = initial(pixel_x) - var/default_pixel_y = initial(pixel_y) - default_pixel_x = src.default_pixel_x - default_pixel_y = src.default_pixel_y - - animate(src, pixel_x = 5, time = 20) - sleep(3) - animate(src, pixel_x = -5, time = 20) - animate(pixel_x = default_pixel_x, pixel_y = default_pixel_y, time = 2) - else - to_chat(usr, "Sidestepping sure seems unachieveable when you're this restricted.") - - if("help") - to_chat(src, "blink, blink_r, blush, bow-(none)/mob, burp, choke, chuckle, clap, collapse, cough, cry, custom, deathgasp, drool, eyebrow, fastsway/qwag, \ - frown, gasp, giggle, glare-(none)/mob, grin, groan, grumble, handshake, hug-(none)/mob, laugh, look-(none)/mob, moan, mumble, nod, pale, point-atom, \ - qwhistle, raise, salute, scream, sneeze, shake, shiver, shrug, sigh, signal-#1-10, slap-(none)/mob, smile, sneeze, sniff, snore, stare-(none)/mob, stopsway/swag, sway/wag, swish, swhistle, \ - tremble, twitch, twitch_v, vomit, whimper, wink, whistle, wwhistle, yawn. Prometheans: squish Synthetics: beep, buzz, dwoop, yes, no, rcough, rsneeze, ping. Skrell: warble") - - else - to_chat(src, "Unusable emote '[act]'. Say *help or *vhelp for a list.") //VOREStation Edit, mention *vhelp for Virgo-specific emotes located in emote_vr.dm. - - if(message) - custom_emote(m_type,message) +var/list/_human_default_emotes = list( + /decl/emote/visible/blink, + /decl/emote/audible/synth, + /decl/emote/audible/synth/ping, + /decl/emote/audible/synth/buzz, + /decl/emote/audible/synth/confirm, + /decl/emote/audible/synth/deny, + /decl/emote/visible/nod, + /decl/emote/visible/shake, + /decl/emote/visible/shiver, + /decl/emote/visible/collapse, + /decl/emote/audible/gasp, + /decl/emote/audible/choke, + /decl/emote/audible/sneeze, + /decl/emote/audible/sniff, + /decl/emote/audible/snore, + /decl/emote/audible/whimper, + /decl/emote/audible/whistle, + /decl/emote/audible/whistle/quiet, + /decl/emote/audible/whistle/wolf, + /decl/emote/audible/whistle/summon, + /decl/emote/audible/yawn, + /decl/emote/audible/clap, + /decl/emote/audible/chuckle, + /decl/emote/audible/cough, + /decl/emote/audible/cry, + /decl/emote/audible/sigh, + /decl/emote/audible/laugh, + /decl/emote/audible/mumble, + /decl/emote/audible/grumble, + /decl/emote/audible/groan, + /decl/emote/audible/moan, + /decl/emote/audible/grunt, + /decl/emote/audible/slap, + /decl/emote/audible/crack, + /decl/emote/human, + /decl/emote/human/deathgasp, + /decl/emote/audible/giggle, + /decl/emote/audible/scream, + /decl/emote/visible/airguitar, + /decl/emote/visible/blink_r, + /decl/emote/visible/bow, + /decl/emote/visible/salute, + /decl/emote/visible/flap, + /decl/emote/visible/aflap, + /decl/emote/visible/drool, + /decl/emote/visible/eyebrow, + /decl/emote/visible/twitch, + /decl/emote/visible/dance, + /decl/emote/visible/twitch_v, + /decl/emote/visible/faint, + /decl/emote/visible/frown, + /decl/emote/visible/blush, + /decl/emote/visible/wave, + /decl/emote/visible/glare, + /decl/emote/visible/stare, + /decl/emote/visible/look, + /decl/emote/visible/point, + /decl/emote/visible/raise, + /decl/emote/visible/grin, + /decl/emote/visible/shrug, + /decl/emote/visible/smile, + /decl/emote/visible/pale, + /decl/emote/visible/tremble, + /decl/emote/visible/wink, + /decl/emote/visible/hug, + /decl/emote/visible/dap, + /decl/emote/visible/signal, + /decl/emote/visible/handshake, + /decl/emote/visible/afold, + /decl/emote/visible/alook, + /decl/emote/visible/eroll, + /decl/emote/visible/hbow, + /decl/emote/visible/hip, + /decl/emote/visible/holdup, + /decl/emote/visible/hshrug, + /decl/emote/visible/crub, + /decl/emote/visible/erub, + /decl/emote/visible/fslap, + /decl/emote/visible/ftap, + /decl/emote/visible/hrub, + /decl/emote/visible/hspread, + /decl/emote/visible/pocket, + /decl/emote/visible/rsalute, + /decl/emote/visible/rshoulder, + /decl/emote/visible/squint, + /decl/emote/visible/tfist, + /decl/emote/visible/tilt, + /decl/emote/visible/spin, + /decl/emote/visible/sidestep, + /decl/emote/audible/snap, + /decl/emote/visible/vomit, + /decl/emote/visible/floorspin, + /decl/emote/visible/flip, + //VOREStation Add + /decl/emote/audible/awoo, + /decl/emote/audible/awoo2, + /decl/emote/audible/growl, + /decl/emote/audible/woof, + /decl/emote/audible/woof2, + /decl/emote/audible/nya, + /decl/emote/audible/mrowl, + /decl/emote/audible/peep, + /decl/emote/audible/chirp, + /decl/emote/audible/hoot, + /decl/emote/audible/weh, + /decl/emote/audible/merp, + /decl/emote/audible/myarp, + /decl/emote/audible/bark, + /decl/emote/audible/bork, + /decl/emote/audible/mrow, + /decl/emote/audible/hypno, + /decl/emote/audible/hiss, + /decl/emote/audible/rattle, + /decl/emote/audible/squeak, + /decl/emote/audible/geck, + /decl/emote/audible/baa, + /decl/emote/audible/baa2, + /decl/emote/audible/mar, + /decl/emote/audible/wurble, + /decl/emote/audible/snort, + /decl/emote/audible/meow, + /decl/emote/audible/moo, + /decl/emote/audible/croak, + /decl/emote/audible/gao, + /decl/emote/audible/cackle, + + /decl/emote/visible/mlem, + /decl/emote/visible/blep, + + /decl/emote/helper/vwag, + /decl/emote/helper/vflap + //VOREStation Add End +) + +/mob/living/carbon/human/get_default_emotes() + return global._human_default_emotes /mob/living/carbon/human/verb/pose() set name = "Set Pose" diff --git a/code/modules/mob/living/carbon/human/emote_vr.dm b/code/modules/mob/living/carbon/human/emote_vr.dm index d8deee8e7bf..f4bc98bcbe6 100644 --- a/code/modules/mob/living/carbon/human/emote_vr.dm +++ b/code/modules/mob/living/carbon/human/emote_vr.dm @@ -1,185 +1,11 @@ -/mob - var/nextemote = 1 +/mob/living/carbon/human/verb/toggle_resizing_immunity() + set name = "Toggle Resizing Immunity" + set desc = "Toggles your ability to resist resizing attempts" + set category = "IC" -/mob/living/carbon/human/proc/handle_emote_vr(var/act,var/m_type=1,var/message = null) - //Reduces emote spamming - if(nextemote >= world.time)// || user.stat != CONSCIOUS - return 1 - nextemote = world.time + 12 + resizable = !resizable + to_chat(src, "You are now [resizable ? "susceptible" : "immune"] to being resized.") - switch(act) - if("vwag") - if(toggle_tail(message = 1)) - m_type = 1 - message = "[wagging ? "starts" : "stops"] wagging their tail." - else - return 1 - if("vflap") - if(toggle_wing(message = 1)) - m_type = 1 - message = "[flapping ? "starts" : "stops"] flapping their wings." - else - return 1 - if("mlem") - message = "mlems [get_visible_gender() == MALE ? "his" : get_visible_gender() == FEMALE ? "her" : "their"] tongue up over [get_visible_gender() == MALE ? "his" : get_visible_gender() == FEMALE ? "her" : "their"] nose. Mlem." - m_type = 1 - if("blep") - message = "bleps [get_visible_gender() == MALE ? "his" : get_visible_gender() == FEMALE ? "her" : "their"] tongue out. Blep." - m_type = 1 - if("awoo") - m_type = 2 - message = "lets out an awoo." - playsound(src, 'sound/voice/awoo.ogg', 50, 1, -1, preference = /datum/client_preference/emote_noises) - if("awoo2") - m_type = 2 - message = "lets out an awoo." - playsound(src, 'sound/voice/long_awoo.ogg', 50, 1, -1, preference = /datum/client_preference/emote_noises) - if("growl") - m_type = 2 - message = "lets out a growl." - playsound(src, 'sound/voice/growl.ogg', 50, 1, -1, preference = /datum/client_preference/emote_noises) - if("woof") - m_type = 2 - message = "lets out a woof." - playsound(src, 'sound/voice/woof.ogg', 50, 1, -1, preference = /datum/client_preference/emote_noises) - if("woof2") - m_type = 2 - message = "lets out a woof." - playsound(src, 'sound/voice/woof2.ogg', 50, 1, -1, preference = /datum/client_preference/emote_noises) - if("nya") - message = "lets out a nya." - m_type = 2 - playsound(src, 'sound/voice/nya.ogg', 50, 1, -1, preference = /datum/client_preference/emote_noises) - if("mrowl") - message = "mrowls." - m_type = 2 - playsound(src, 'sound/voice/mrow.ogg', 50, 1, -1, preference = /datum/client_preference/emote_noises) - if("peep") - message = "peeps like a bird." - m_type = 2 - playsound(src, 'sound/voice/peep.ogg', 50, 1, -1, preference = /datum/client_preference/emote_noises) - if("chirp") - message = "chirps!" - playsound(src, 'sound/misc/nymphchirp.ogg', 50, 0, preference = /datum/client_preference/emote_noises) - m_type = 2 - if("hoot") - message = "hoots!" - playsound(src, 'sound/voice/hoot.ogg', 50, 1, ,-1, preference = /datum/client_preference/emote_noises) - m_type = 2 - if("weh") - message = "lets out a weh." - m_type = 2 - playsound(src, 'sound/voice/weh.ogg', 50, 1, -1, preference = /datum/client_preference/emote_noises) - if("merp") - message = "lets out a merp." - m_type = 2 - playsound(src, 'sound/voice/merp.ogg', 50, 1, -1, preference = /datum/client_preference/emote_noises) - if("myarp") - message = "lets out a myarp." - m_type = 2 - playsound(src, 'sound/voice/myarp.ogg', 50, 1, -1, preference = /datum/client_preference/emote_noises) - if("bark") - message = "lets out a bark." - m_type = 2 - playsound(src, 'sound/voice/bark2.ogg', 50, 1, -1, preference = /datum/client_preference/emote_noises) - if("bork") - m_type = 2 - message = "lets out a bork." - playsound(src, 'sound/voice/bork.ogg', 50, 1, -1, preference = /datum/client_preference/emote_noises) - if ("mrow") - m_type = 2 - message = "lets out a mrow." - playsound(src, 'sound/voice/mrow.ogg', 50, 1, -1, preference = /datum/client_preference/emote_noises) - if ("hypno") - m_type = 2 - message = "lets out a mystifying tone." - playsound(src, 'sound/voice/hypno.ogg', 50, 1, -1, preference = /datum/client_preference/emote_noises) - if("hiss") - message = "lets out a hiss." - m_type = 2 - playsound(src, 'sound/voice/hiss.ogg', 50, 1, -1, preference = /datum/client_preference/emote_noises) - if("rattle") - message = "rattles!" - m_type = 2 - playsound(src, 'sound/voice/rattle.ogg', 50, 1, -1, preference = /datum/client_preference/emote_noises) - if("squeak") - message = "lets out a squeak." - m_type = 2 - playsound(src, 'sound/effects/mouse_squeak.ogg', 50, 1, -1, preference = /datum/client_preference/emote_noises) - if("geck") - message = "geckers!" - m_type = 2 - playsound(src, 'sound/voice/geck.ogg', 50, 1, -1, preference = /datum/client_preference/emote_noises) - if("baa") - message = "lets out a baa." - m_type = 2 - playsound(src, 'sound/voice/baa.ogg', 50, 1, -1, preference = /datum/client_preference/emote_noises) - if("baa2") - message = "bleats." - m_type = 2 - playsound(src, 'sound/voice/baa2.ogg', 50, 1, -1, preference = /datum/client_preference/emote_noises) - if("deathgasp2") - message = "[species.get_death_message()]" - m_type = 1 - playsound(src, 'sound/voice/deathgasp2.ogg', 50, 1, -1, preference = /datum/client_preference/emote_noises) - if("mar") - message = "lets out a mar." - m_type = 2 - playsound(src, 'sound/voice/mar.ogg', 50, 1, -1, preference = /datum/client_preference/emote_noises) - if("wurble") - message = "lets out a wurble." - m_type = 2 - playsound(src, 'sound/voice/wurble.ogg', 50, 1, -1, preference = /datum/client_preference/emote_noises) - if("snort") - message = "snorts!" - m_type = 2 - playsound(src, 'sound/voice/Snort.ogg', 50, 0, preference = /datum/client_preference/emote_noises) - if("meow") - message = "gently meows!" - m_type = 2 - playsound(src, 'sound/voice/Meow.ogg', 50, 0, preference = /datum/client_preference/emote_noises) - if("moo") - message = "takes a breath and lets out a moo." - m_type = 2 - playsound(src, 'sound/voice/Moo.ogg', 50, 0, preference = /datum/client_preference/emote_noises) - if("croak") - message = "rumbles their throat, puffs their cheeks and croaks." - m_type = 2 - playsound(src, 'sound/voice/Croak.ogg', 50, 0, preference = /datum/client_preference/emote_noises) - if("gao") - message = "lets out a gao." - m_type = 2 - playsound(src, 'sound/voice/gao.ogg', 50, 0, preference = /datum/client_preference/emote_noises) - if("cackle") - message = "cackles hysterically!" - m_type = 2 - playsound(src, 'sound/voice/YeenCackle.ogg', 50, 0, preference = /datum/client_preference/emote_noises) - if("nsay") - nsay() - return TRUE - if("nme") - nme() - return TRUE - if("flip") - var/list/involved_parts = list(BP_L_LEG, BP_R_LEG, BP_L_FOOT, BP_R_FOOT) - //Check if they are physically capable - if(sleeping || resting || buckled || weakened || restrained() || involved_parts.len < 2) - to_chat(src, "You can't *flip in your current state!") - return 1 - else - nextemote += 12 //Double delay - handle_flip_vr() - message = "does a flip!" - m_type = 1 - if("vhelp") //Help for Virgo-specific emotes. - to_chat(src, "vwag, vflap, mlem, blep, awoo, awoo2, growl, nya, peep, chirp, hoot, weh, merp, myarp, bark, bork, mrow, mrowl, hypno, hiss, rattle, squeak, geck, baa, baa2, mar, wurble, snort, meow, moo, croak, gao, cackle, nsay, nme, flip") - return TRUE - - if(message) - custom_emote(m_type,message) - return TRUE - - return FALSE /mob/living/carbon/human/proc/handle_flip_vr() var/original_density = density diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index b351c3d79be..1cb3adaa28d 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -53,6 +53,7 @@ sync_organ_dna() //verbs |= /mob/living/proc/toggle_selfsurgery //VOREStation Removal + AddComponent(/datum/component/personal_crafting) /mob/living/carbon/human/Destroy() human_mob_list -= src @@ -1162,6 +1163,9 @@ //A slew of bits that may be affected by our species change regenerate_icons() + // Update our available emote list. + update_emotes() + if(species) //if(mind) //VOREStation Removal //apply_traits() //VOREStation Removal diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 0199d387ae5..cdfef35b596 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -69,10 +69,10 @@ emp_act drop_from_inventory(c_hand) if (affected.robotic >= ORGAN_ROBOT) - emote("me", 1, "drops what they were holding, their [affected.name] malfunctioning!") + custom_emote(VISIBLE_MESSAGE, "drops what they were holding, their [affected.name] malfunctioning!") else var/emote_scream = pick("screams in pain and ", "lets out a sharp cry and ", "cries out and ") - emote("me", 1, "[affected.organ_can_feel_pain() ? "" : emote_scream] drops what they were holding in their [affected.name]!") + custom_emote(VISIBLE_MESSAGE, "[affected.organ_can_feel_pain() ? "" : emote_scream] drops what they were holding in their [affected.name]!") ..(stun_amount, agony_amount, def_zone) diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index 34b93b25738..15ea6a45542 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -81,7 +81,6 @@ var/voice = "" //Instead of new say code calling GetVoice() over and over and over, we're just going to ask this variable, which gets updated in Life() - var/miming = null //Toggle for the mime's abilities. var/special_voice = "" // For changing our voice. Used by a symptom. var/last_dam = -1 //Used for determining if we need to process all organs or just some or even none. @@ -156,4 +155,3 @@ // Custom Species Name var/custom_species - diff --git a/code/modules/mob/living/carbon/human/human_helpers.dm b/code/modules/mob/living/carbon/human/human_helpers.dm index 6795d670647..c0360d3297a 100644 --- a/code/modules/mob/living/carbon/human/human_helpers.dm +++ b/code/modules/mob/living/carbon/human/human_helpers.dm @@ -98,7 +98,8 @@ // This is the 'mechanical' check for synthetic-ness, not appearance // Returns the company that made the synthetic /mob/living/carbon/human/isSynthetic() - if(synthetic) return synthetic //Your synthetic-ness is not going away + if(synthetic) + return synthetic //Your synthetic-ness is not going away var/obj/item/organ/external/T = organs_by_name[BP_TORSO] if(T && T.robotic >= ORGAN_ROBOT) src.verbs += /mob/living/carbon/human/proc/self_diagnostics @@ -106,9 +107,9 @@ src.verbs += /mob/living/carbon/human/proc/setmonitor_state var/datum/robolimb/R = all_robolimbs[T.model] synthetic = R + update_emotes() return synthetic - - return 0 + return FALSE // Would an onlooker know this person is synthetic? // Based on sort of logical reasoning, 'Look at head, look at torso' diff --git a/code/modules/mob/living/carbon/human/human_organs.dm b/code/modules/mob/living/carbon/human/human_organs.dm index 4637bde1bd2..f9c9bc831d1 100644 --- a/code/modules/mob/living/carbon/human/human_organs.dm +++ b/code/modules/mob/living/carbon/human/human_organs.dm @@ -164,7 +164,7 @@ drop_from_inventory(r_hand) var/emote_scream = pick("screams in pain and ", "lets out a sharp cry and ", "cries out and ") - emote("me", 1, "[(can_feel_pain()) ? "" : emote_scream ]drops what they were holding in their [E.name]!") + custom_emote(VISIBLE_MESSAGE, "[(can_feel_pain()) ? "" : emote_scream ]drops what they were holding in their [E.name]!") else if(E.is_malfunctioning()) switch(E.body_part) @@ -177,7 +177,7 @@ continue drop_from_inventory(r_hand) - emote("me", 1, "drops what they were holding, their [E.name] malfunctioning!") + custom_emote(VISIBLE_MESSAGE, "drops what they were holding, their [E.name] malfunctioning!") var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() spark_system.set_up(5, 0, src) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 286c257b972..767d68a56e7 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -1556,7 +1556,7 @@ if(shock_stage >= 30) if(shock_stage == 30 && !isbelly(loc)) //VOREStation Edit - emote("me",1,"is having trouble keeping their eyes open.") + custom_emote(VISIBLE_MESSAGE, "is having trouble keeping their eyes open.") eye_blurry = max(2, eye_blurry) stuttering = max(stuttering, 5) @@ -1565,7 +1565,7 @@ if (shock_stage >= 60) if(shock_stage == 60 && !isbelly(loc)) //VOREStation Edit - emote("me",1,"'s body becomes limp.") + custom_emote(VISIBLE_MESSAGE, "'s body becomes limp.") if (prob(2)) to_chat(src, "[pick("The pain is excruciating", "Please, just end the pain", "Your whole body is going numb")]!") Weaken(20) @@ -1582,7 +1582,7 @@ if(shock_stage == 150) if(!isbelly(loc)) //VOREStation Edit - emote("me",1,"can no longer stand, collapsing!") + custom_emote(VISIBLE_MESSAGE, "can no longer stand, collapsing!") Weaken(20) if(shock_stage >= 150) diff --git a/code/modules/mob/living/carbon/human/species/outsider/vox.dm b/code/modules/mob/living/carbon/human/species/outsider/vox.dm index b29bead4f9c..e8ff96175a7 100644 --- a/code/modules/mob/living/carbon/human/species/outsider/vox.dm +++ b/code/modules/mob/living/carbon/human/species/outsider/vox.dm @@ -25,7 +25,8 @@ speech_sounds = list('sound/voice/shriek1.ogg') speech_chance = 20 - scream_verb = "shrieks" + scream_verb_1p = "shriek" + scream_verb_3p = "shrieks" male_scream_sound = 'sound/voice/shriek1.ogg' female_scream_sound = 'sound/voice/shriek1.ogg' male_cough_sounds = list('sound/voice/shriekcough.ogg') @@ -86,7 +87,11 @@ /datum/mob_descriptor/height = -1, /datum/mob_descriptor/build = 1, /datum/mob_descriptor/vox_markings = 0 - ) + ) + + default_emotes = list( + /decl/emote/audible/vox_shriek + ) /datum/species/vox/get_random_name(var/gender) var/datum/language/species_language = GLOB.all_languages[default_language] diff --git a/code/modules/mob/living/carbon/human/species/shadekin/shadekin_trait.dm b/code/modules/mob/living/carbon/human/species/shadekin/shadekin_trait.dm index 73c182dfadd..7f16315e851 100644 --- a/code/modules/mob/living/carbon/human/species/shadekin/shadekin_trait.dm +++ b/code/modules/mob/living/carbon/human/species/shadekin/shadekin_trait.dm @@ -2,7 +2,7 @@ allowed_species = list(SPECIES_SHADEKIN) var/color = BLUE_EYES name = "Shadekin Blue Adaptation" - desc = "Makes your shadekin adapted as a Blue eyed kin! This gives you decreased energy regeneration in darkness, decreased regeneration in the light amd unchanged health!" + desc = "Makes your shadekin adapted as a Blue eyed kin! This gives you decreased energy regeneration in darkness, decreased regeneration in the light and unchanged health!" cost = 0 var_changes = list( "total_health" = 100, "energy_light" = 0.5, @@ -13,7 +13,7 @@ /datum/trait/kintype/red name = "Shadekin Red Adaptation" color = RED_EYES - desc = "Makes your shadekin adapted as a Red eyed kin! This gives you minimal energy regeneration in darkness, moderate regeneration in the light amd increased health!" + desc = "Makes your shadekin adapted as a Red eyed kin! This gives you minimal energy regeneration in darkness, moderate degeneration in the light and increased health!" var_changes = list( "total_health" = 200, "energy_light" = -1, "energy_dark" = 0.1, @@ -22,37 +22,37 @@ /datum/trait/kintype/purple name = "Shadekin Purple Adaptation" color = PURPLE_EYES - desc = "Makes your shadekin adapted as a Purple eyed kin! This gives you moderate energy regeneration in darkness, minor degeneration in the light amd increased health!" + desc = "Makes your shadekin adapted as a Purple eyed kin! This gives you moderate energy regeneration in darkness, minor degeneration in the light and increased health!" var_changes = list( "total_health" = 150, - "energy_light" = 1, - "energy_dark" = -0.5, + "energy_light" = -0.5, + "energy_dark" = 1, "unarmed_types" = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/claws/shadekin, /datum/unarmed_attack/bite/sharp/shadekin,/datum/unarmed_attack/shadekinharmbap)) /datum/trait/kintype/yellow name = "Shadekin Yellow Adaptation" color = YELLOW_EYES - desc = "Makes your shadekin adapted as a Yellow eyed kin! This gives you the highest energy regeneration in darkness, high degeneration in the light amd unchanged health!" + desc = "Makes your shadekin adapted as a Yellow eyed kin! This gives you the highest energy regeneration in darkness, high degeneration in the light and unchanged health!" var_changes = list( "total_health" = 100, - "energy_light" = 3, - "energy_dark" = -2, + "energy_light" = -2, + "energy_dark" = 3, "unarmed_types" = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/claws/shadekin, /datum/unarmed_attack/bite/sharp/shadekin,/datum/unarmed_attack/shadekinharmbap)) /datum/trait/kintype/green name = "Shadekin Green Adaptation" color = GREEN_EYES - desc = "Makes your shadekin adapted as a Green eyed kin! This gives you high energy regeneration in darkness, minor regeneration in the light amd unchanged health!" + desc = "Makes your shadekin adapted as a Green eyed kin! This gives you high energy regeneration in darkness, minor regeneration in the light and unchanged health!" var_changes = list( "total_health" = 100, - "energy_light" = 2, - "energy_dark" = 0.125, + "energy_light" = 0.125, + "energy_dark" = 2, "unarmed_types" = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/claws/shadekin, /datum/unarmed_attack/bite/sharp/shadekin,/datum/unarmed_attack/shadekinharmbap)) /datum/trait/kintype/orange name = "Shadekin Orange Adaptation" color = ORANGE_EYES - desc = "Makes your shadekin adapted as a Orange eyed kin! This gives you minor energy regeneration in darkness, modeate degeneration in the light amd increased health!" + desc = "Makes your shadekin adapted as a Orange eyed kin! This gives you minor energy regeneration in darkness, moderate degeneration in the light and increased health!" var_changes = list( "total_health" = 175, - "energy_light" = 0.25, - "energy_dark" = -0.5, + "energy_light" = -0.5, + "energy_dark" = 0.25, "unarmed_types" = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/claws/shadekin, /datum/unarmed_attack/bite/sharp/shadekin,/datum/unarmed_attack/shadekinharmbap)) /datum/trait/kintype/apply(var/datum/species/shadekin/S,var/mob/living/carbon/human/H) diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm index 80ad0763e27..3ae68b2c7d8 100644 --- a/code/modules/mob/living/carbon/human/species/species.dm +++ b/code/modules/mob/living/carbon/human/species/species.dm @@ -75,7 +75,8 @@ var/list/assisted_langs = list(LANGUAGE_EAL, LANGUAGE_SKRELLIAN, LANGUAGE_SKRELLIANFAR, LANGUAGE_ROOTLOCAL, LANGUAGE_ROOTGLOBAL, LANGUAGE_VOX) //VOREStation Edit //Soundy emotey things. - var/scream_verb = "screams" + var/scream_verb_1p = "scream" + var/scream_verb_3p = "screams" var/male_scream_sound //= 'sound/goonstation/voice/male_scream.ogg' Removed due to licensing, replace! var/female_scream_sound //= 'sound/goonstation/voice/female_scream.ogg' Removed due to licensing, replace! var/male_cough_sounds = list('sound/effects/mob_effects/m_cougha.ogg','sound/effects/mob_effects/m_coughb.ogg', 'sound/effects/mob_effects/m_coughc.ogg') diff --git a/code/modules/mob/living/carbon/human/species/species_getters.dm b/code/modules/mob/living/carbon/human/species/species_getters.dm index 0eeea4f9d4c..7b635613ea1 100644 --- a/code/modules/mob/living/carbon/human/species/species_getters.dm +++ b/code/modules/mob/living/carbon/human/species/species_getters.dm @@ -44,7 +44,7 @@ if(config.show_human_death_message) return ((H && H.isSynthetic()) ? "gives one shrill beep before falling lifeless." : death_message) else - return "no message" + return DEATHGASP_NO_MESSAGE /datum/species/proc/get_ssd(var/mob/living/carbon/human/H) if(H) diff --git a/code/modules/mob/living/carbon/human/species/species_vr.dm b/code/modules/mob/living/carbon/human/species/species_vr.dm index 06c9d2bdf38..486264e2c81 100644 --- a/code/modules/mob/living/carbon/human/species/species_vr.dm +++ b/code/modules/mob/living/carbon/human/species/species_vr.dm @@ -23,6 +23,8 @@ var/silk_color = "#FFFFFF" var/list/traits = list() + //Vars that need to be copied when producing a copy of species. + var/list/copy_vars = list("base_species", "icobase", "deform", "tail", "tail_animation", "icobase_tail", "color_mult", "primitive_form", "appearance_flags", "flesh_color", "base_color", "blood_mask", "damage_mask", "damage_overlays", "move_trail", "has_floating_eyes") /datum/species/proc/give_numbing_bite() //Holy SHIT this is hacky, but it works. Updating a mob's attacks mid game is insane. unarmed_attacks = list() @@ -42,31 +44,20 @@ nif.nifsofts = nifsofts else ..() -/datum/species/proc/produceCopy(var/list/traits,var/mob/living/carbon/human/H, var/custom_base) - var/datum/species/S - //If species allows custom base, and custom base is set, apply it, otherwise use default. - if(selects_bodytype && custom_base) - S = GLOB.all_species[custom_base] - else - S = GLOB.all_species[src.name] - ASSERT(S) +/datum/species/proc/produceCopy(var/list/traits, var/mob/living/carbon/human/H, var/custom_base) + ASSERT(src) ASSERT(istype(H)) - var/datum/species/new_copy = new S.type() + var/datum/species/new_copy = new src.type() - for(var/i in S.vars) //Thorough copy of species. - if(new_copy.vars[i] != S.vars[i]) - //Skipping lists because they may contain more lists, copy those manually. - //Also ignoring type var since it's read-only and will runtime. - if(islist(vars[i])) - continue - new_copy.vars[i] = S.vars[i] + if(selects_bodytype && custom_base) //If race selects a bodytype, retrieve the custom_base species and copy needed variables. + var/datum/species/S = GLOB.all_species[custom_base] + S.copy_variables(new_copy, copy_vars) - for(var/organ in S.has_limbs) //Copy important organ data generated by species. - var/list/organ_data = S.has_limbs[organ] + for(var/organ in has_limbs) //Copy important organ data generated by species. + var/list/organ_data = has_limbs[organ] new_copy.has_limbs[organ] = organ_data.Copy() new_copy.traits = traits - //If you had traits, apply them if(new_copy.traits) for(var/trait in new_copy.traits) @@ -85,6 +76,19 @@ return new_copy +/datum/species/proc/copy_variables(var/datum/species/S, var/list/whitelist) + //List of variables to ignore, trying to copy type will runtime. + var/list/blacklist = list("type", "loc", "client", "ckey") + //Makes thorough copy of species datum. + for(var/i in vars) + if(S.vars[i] != vars[i] && !islist(vars[i])) //If vars are same, no point in copying. + if(i in blacklist) + continue + if(whitelist)//If whitelist is provided, only vars in the list will be copied. + if(i in whitelist) + S.vars[i] = vars[i] + continue + S.vars[i] = vars[i] /datum/species/get_bodytype() - return base_species \ No newline at end of file + return base_species diff --git a/code/modules/mob/living/carbon/human/species/station/blank_vr.dm b/code/modules/mob/living/carbon/human/species/station/blank_vr.dm index c358fda022c..72e49694d38 100644 --- a/code/modules/mob/living/carbon/human/species/station/blank_vr.dm +++ b/code/modules/mob/living/carbon/human/species/station/blank_vr.dm @@ -46,8 +46,8 @@ var/datum/species/real = GLOB.all_species[base_species] return real.race_key -/datum/species/custom/produceCopy(var/list/traits,var/mob/living/carbon/human/H) - . = ..() +/datum/species/custom/produceCopy(var/list/traits, var/mob/living/carbon/human/H, var/custom_base) + . = ..(traits, H, custom_base) H.maxHealth = H.species.total_health H.hunger_rate = H.species.hunger_factor diff --git a/code/modules/mob/living/carbon/human/species/station/prometheans.dm b/code/modules/mob/living/carbon/human/species/station/prometheans.dm index bfb1b7d5e3d..8ec116221ed 100644 --- a/code/modules/mob/living/carbon/human/species/station/prometheans.dm +++ b/code/modules/mob/living/carbon/human/species/station/prometheans.dm @@ -119,6 +119,15 @@ var/datum/species/shapeshifter/promethean/prometheans var/heal_rate = 0.5 // Temp. Regen per tick. + default_emotes = list( + /decl/emote/audible/squish, + /decl/emote/audible/chirp, + /decl/emote/visible/bounce, + /decl/emote/visible/jiggle, + /decl/emote/visible/lightup, + /decl/emote/visible/vibrate + ) + /datum/species/shapeshifter/promethean/New() ..() prometheans = src diff --git a/code/modules/mob/living/carbon/human/species/station/protean_vr/protean_blob.dm b/code/modules/mob/living/carbon/human/species/station/protean_vr/protean_blob.dm index ec0bab797cb..a0a505d61aa 100644 --- a/code/modules/mob/living/carbon/human/species/station/protean_vr/protean_blob.dm +++ b/code/modules/mob/living/carbon/human/species/station/protean_vr/protean_blob.dm @@ -163,12 +163,14 @@ return ..() /mob/living/simple_mob/protean_blob/adjustBruteLoss(var/amount) + amount *= 1.5 if(humanform) return humanform.adjustBruteLoss(amount) else return ..() /mob/living/simple_mob/protean_blob/adjustFireLoss(var/amount) + amount *= 1.5 if(humanform) return humanform.adjustFireLoss(amount) else diff --git a/code/modules/mob/living/carbon/human/species/station/protean_vr/protean_species.dm b/code/modules/mob/living/carbon/human/species/station/protean_vr/protean_species.dm index 087338fd739..8bd2192be8c 100755 --- a/code/modules/mob/living/carbon/human/species/station/protean_vr/protean_species.dm +++ b/code/modules/mob/living/carbon/human/species/station/protean_vr/protean_species.dm @@ -313,8 +313,8 @@ material_name = MAT_STEEL /datum/modifier/protean/steel/tick() - holder.adjustBruteLoss(-2,include_robo = TRUE) //Looks high, but these ARE modified by species resistances, so this is really 20% of this - holder.adjustFireLoss(-1,include_robo = TRUE) //And this is really double this + holder.adjustBruteLoss(-1,include_robo = TRUE) //Modified by species resistances + holder.adjustFireLoss(-0.5,include_robo = TRUE) //Modified by species resistances var/mob/living/carbon/human/H = holder for(var/organ in H.internal_organs) var/obj/item/organ/O = organ diff --git a/code/modules/mob/living/carbon/human/species/station/station.dm b/code/modules/mob/living/carbon/human/species/station/station.dm index f74505e770b..21e19f68d43 100644 --- a/code/modules/mob/living/carbon/human/species/station/station.dm +++ b/code/modules/mob/living/carbon/human/species/station/station.dm @@ -160,6 +160,16 @@ /datum/mob_descriptor/build = 2 ) + default_emotes = list( + /decl/emote/human/swish, + /decl/emote/human/wag, + /decl/emote/human/sway, + /decl/emote/human/qwag, + /decl/emote/human/fastsway, + /decl/emote/human/swag, + /decl/emote/human/stopsway + ) + /datum/species/unathi/equip_survival_gear(var/mob/living/carbon/human/H) ..() H.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(H),slot_shoes) @@ -250,6 +260,16 @@ O_INTESTINE = /obj/item/organ/internal/intestine ) + default_emotes = list( + /decl/emote/human/swish, + /decl/emote/human/wag, + /decl/emote/human/sway, + /decl/emote/human/qwag, + /decl/emote/human/fastsway, + /decl/emote/human/swag, + /decl/emote/human/stopsway + ) + /datum/species/tajaran/equip_survival_gear(var/mob/living/carbon/human/H) ..() H.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(H),slot_shoes) @@ -533,6 +553,11 @@ genders = list(PLURAL) + default_emotes = list( + /decl/emote/audible/chirp, + /decl/emote/audible/multichirp + ) + /datum/species/diona/can_understand(var/mob/other) if(istype(other, /mob/living/carbon/alien/diona)) return TRUE diff --git a/code/modules/mob/living/carbon/human/species/station/teshari.dm b/code/modules/mob/living/carbon/human/species/station/teshari.dm index 3a282707c35..42afbbdbfcb 100644 --- a/code/modules/mob/living/carbon/human/species/station/teshari.dm +++ b/code/modules/mob/living/carbon/human/species/station/teshari.dm @@ -139,7 +139,7 @@ descriptors = list( /datum/mob_descriptor/height = -3, /datum/mob_descriptor/build = -3 - ) + ) var/static/list/flight_bodyparts = list( BP_L_ARM, @@ -152,6 +152,12 @@ /obj/item/clothing/suit/straight_jacket ) + default_emotes = list( + /decl/emote/audible/teshsqueak, + /decl/emote/audible/teshchirp, + /decl/emote/audible/teshtrill + ) + /datum/species/teshari/equip_survival_gear(var/mob/living/carbon/human/H) ..() H.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(H),slot_shoes) @@ -159,7 +165,7 @@ /datum/species/teshari/handle_falling(mob/living/carbon/human/H, atom/hit_atom, damage_min, damage_max, silent, planetary) // Tesh can glide to save themselves from some falls. Basejumping bird - // without parachute, or falling bird without free wings goes splat. + // without parachute, or falling bird without free wings, goes splat. // Are we landing from orbit, or handcuffed/unconscious/tied to something? if(planetary || !istype(H) || H.incapacitated(INCAPACITATION_DEFAULT|INCAPACITATION_DISABLED)) diff --git a/code/modules/mob/living/carbon/human/species/station/traits_vr/neutral.dm b/code/modules/mob/living/carbon/human/species/station/traits_vr/neutral.dm index 011059a9e04..df7edc45af2 100644 --- a/code/modules/mob/living/carbon/human/species/station/traits_vr/neutral.dm +++ b/code/modules/mob/living/carbon/human/species/station/traits_vr/neutral.dm @@ -1,6 +1,8 @@ #define ORGANICS 1 #define SYNTHETICS 2 +/datum/trait/neutral + /datum/trait/neutral/metabolism_up name = "Fast Metabolism" desc = "You process ingested and injected reagents faster, but get hungry faster (Teshari speed)." diff --git a/code/modules/mob/living/carbon/human/species/station/xenochimera_trait_vr.dm b/code/modules/mob/living/carbon/human/species/station/xenochimera_trait_vr.dm index be1783d9dff..19e274306b4 100644 --- a/code/modules/mob/living/carbon/human/species/station/xenochimera_trait_vr.dm +++ b/code/modules/mob/living/carbon/human/species/station/xenochimera_trait_vr.dm @@ -3,39 +3,44 @@ ** These are only traits that they should reasonably be able to evolve to acquire themselves. ** I won't add the resistances though because those are kinda lame for a 'chimera to take! */ -/datum/trait/weaver/xenochimera +/datum/trait/positive/weaver/xenochimera allowed_species = list(SPECIES_XENOCHIMERA) name = "Xenochimera: Weaver" desc = "You've evolved your body to produce silk that you can fashion into articles of clothing and other objects." cost = 0 + category = 0 custom_only = FALSE -/datum/trait/hardfeet/xenochimera +/datum/trait/positive/hardfeet/xenochimera allowed_species = list(SPECIES_XENOCHIMERA) name = "Xenochimera: Hard Feet" desc = "Your body has adapted to make your feet immune to glass shards, whether by developing hooves, chitin, or just horrible callous." cost = 0 + category = 0 custom_only = FALSE // Why put this on Xenochimera of all species? I have no idea, but someone may be enough of a lunatic to take it. -/datum/trait/neural_hypersensitivity/xenochimera +/datum/trait/negative/neural_hypersensitivity/xenochimera allowed_species = list(SPECIES_XENOCHIMERA) name = "Xenochimera: Neural Hypersensitivity" desc = "Despite your evolutionary efforts, you are unusually sensitive to pain. \ Given your species' typical reactions to pain, this can only end well for you!" cost = 0 + category = 0 custom_only = FALSE -/datum/trait/melee_attack_fangs/xenochimera +/datum/trait/positive/melee_attack_fangs/xenochimera allowed_species = list(SPECIES_XENOCHIMERA) name = "Xenochimera: Sharp Melee & Numbing Fangs" desc = "Your hunting instincts manifest in earnest! You have grown numbing fangs alongside your naturally grown hunting weapons." cost = 0 + category = 0 custom_only = FALSE -/datum/trait/snowwalker/xenochimera +/datum/trait/positive/snowwalker/xenochimera allowed_species = list(SPECIES_XENOCHIMERA) name = "Xenochimera: Snow Walker" desc = "You've adapted to traversing snowy terrain. Snow does not slow you down!" cost = 0 + category = 0 custom_only = FALSE diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index bfb4856017b..d5f51aece28 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -147,7 +147,11 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon() anim_time = 1 //Thud if(lying && !species.prone_icon) //Only rotate them if we're not drawing a specific icon for being prone. - M.Turn(90) + var/randn = rand(1, 2) + if(randn <= 1) // randomly choose a rotation + M.Turn(-90) + else + M.Turn(90) M.Scale(desired_scale_y, desired_scale_x)//VOREStation Edit if(species.icon_height == 64)//VOREStation Edit M.Translate(13,-22) diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index 877e8542767..ae1b09ae714 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -433,38 +433,5 @@ proc/get_radio_key_from_channel(var/channel) /mob/proc/GetVoice() return name -/mob/living/emote(var/act, var/type, var/message) //emote code is terrible, this is so that anything that isn't - if(stat) //already snowflaked to shit can call the parent and handle emoting sanely - return FALSE - - if(..(act, type, message)) - return TRUE - - if(act && type && message) - log_emote(message, src) - - for(var/mob/M in dead_mob_list) - if(!M.client) - continue - - if(isnewplayer(M)) - continue - - if(isobserver(M) && M.is_preference_enabled(/datum/client_preference/ghost_sight)) - M.show_message(message) - - switch(type) - if(1) // Visible - visible_message(message) - return TRUE - if(2) // Audible - audible_message(message) - return TRUE - else - if(act == "help") - return // Mobs handle this individually - to_chat(src, "Unusable emote '[act]'. Say *help for a list.") - - /mob/proc/speech_bubble_appearance() return "normal" diff --git a/code/modules/mob/living/silicon/emote.dm b/code/modules/mob/living/silicon/emote.dm index 00a5e429932..6aa6ae2150f 100644 --- a/code/modules/mob/living/silicon/emote.dm +++ b/code/modules/mob/living/silicon/emote.dm @@ -1,113 +1,13 @@ -/mob/living/silicon/emote(var/act, var/m_type = 1,var/message = null) - var/param = null - if(findtext(act, "-", 1, null)) - var/t1 = findtext(act, "-", 1, null) - param = copytext(act, t1 + 1, length(act) + 1) - act = copytext(act, 1, t1) +var/list/_silicon_default_emotes = list( + /decl/emote/audible/synth, + /decl/emote/audible/synth/ping, + /decl/emote/audible/synth/buzz, + /decl/emote/audible/synth/confirm, + /decl/emote/audible/synth/deny, + /decl/emote/audible/synth/dwoop, + /decl/emote/audible/synth/security, + /decl/emote/audible/synth/security/halt +) - if(findtext(act, "s", -1) && !findtext(act, "_", -2))//Removes ending s's unless they are prefixed with a '_' - act = copytext(act, 1, length(act)) - - switch(act) - if("beep") - var/M = null - if(param) - for (var/mob/A in view(null, null)) - if (param == A.name) - M = A - break - if(!M) - param = null - - if (param) - message = "[src] beeps at [param]." - else - message = "[src] beeps." - playsound(src, 'sound/machines/twobeep.ogg', 50, 0) - m_type = 1 - - if("ping") - var/M = null - if(param) - for (var/mob/A in view(null, null)) - if (param == A.name) - M = A - break - if(!M) - param = null - - if (param) - message = "[src] pings at [param]." - else - message = "[src] pings." - playsound(src, 'sound/machines/ping.ogg', 50, 0) - m_type = 1 - - if("buzz") - var/M = null - if(param) - for (var/mob/A in view(null, null)) - if (param == A.name) - M = A - break - if(!M) - param = null - - if (param) - message = "[src] buzzes at [param]." - else - message = "[src] buzzes." - playsound(src, 'sound/machines/buzz-sigh.ogg', 50, 0) - m_type = 1 - - if("yes", "ye") - var/M = null - if(param) - for (var/mob/A in view(null, null)) - if (param == A.name) - M = A - break - if(!M) - param = null - - if (param) - message = "[src] emits an affirmative blip at [param]." - else - message = "[src] emits an affirmative blip." - playsound(src, 'sound/machines/synth_yes.ogg', 50, 0) - m_type = 1 - - if("dwoop") - var/M = null - if(param) - for (var/mob/A in view(null, null)) - M = A - break - if(!M) - param = null - - if (param) - message = "[src] chirps happily at [param]" - else - message = "[src] chirps happily." - playsound(src, 'sound/machines/dwoop.ogg', 50, 0) - m_type = 1 - - if("no") - var/M = null - if(param) - for (var/mob/A in view(null, null)) - if (param == A.name) - M = A - break - if(!M) - param = null - - if (param) - message = "[src] emits a negative blip at [param]." - else - message = "[src] emits a negative blip." - playsound(src, 'sound/machines/synth_no.ogg', 50, 0) - m_type = 1 - - ..(act, m_type, message) \ No newline at end of file +/mob/living/silicon/get_default_emotes() + return global._silicon_default_emotes diff --git a/code/modules/mob/living/silicon/robot/emote.dm b/code/modules/mob/living/silicon/robot/emote.dm index 9560c6b528e..2b83568e7bf 100644 --- a/code/modules/mob/living/silicon/robot/emote.dm +++ b/code/modules/mob/living/silicon/robot/emote.dm @@ -1,155 +1,33 @@ -/mob/living/silicon/robot/emote(var/act,var/m_type=1,var/message = null) - var/param = null - if(findtext(act, "-", 1, null)) - var/t1 = findtext(act, "-", 1, null) - param = copytext(act, t1 + 1, length(act) + 1) - act = copytext(act, 1, t1) +var/list/_robot_default_emotes = list( + /decl/emote/audible/clap, + /decl/emote/visible/bow, + /decl/emote/visible/salute, + /decl/emote/visible/flap, + /decl/emote/visible/aflap, + /decl/emote/visible/twitch, + /decl/emote/visible/twitch_v, + /decl/emote/visible/dance, + /decl/emote/visible/nod, + /decl/emote/visible/shake, + /decl/emote/visible/glare, + /decl/emote/visible/look, + /decl/emote/visible/stare, + /decl/emote/visible/deathgasp_robot, + /decl/emote/visible/spin, + /decl/emote/visible/sidestep, + /decl/emote/audible/synth, + /decl/emote/audible/synth/ping, + /decl/emote/audible/synth/buzz, + /decl/emote/audible/synth/confirm, + /decl/emote/audible/synth/deny, + /decl/emote/audible/synth/dwoop, + /decl/emote/audible/synth/security, + /decl/emote/audible/synth/security/halt, + //VOREStation Add + /decl/emote/visible/mlem, + /decl/emote/visible/blep + //VOREStation Add End +) - if(findtext(act,"s",-1) && !findtext(act,"_",-2))//Removes ending s's unless they are prefixed with a '_' - act = copytext(act,1,length(act)) - - switch(act) - if("salute") - if(!src.buckled) - var/M = null - if(param) - for (var/mob/A in view(null, null)) - if(param == A.name) - M = A - break - if(!M) - param = null - - if(param) - message = "[src] salutes to [param]." - else - message = "[src] salutes." - m_type = 1 - if("bow") - if(!src.buckled) - var/M = null - if(param) - for (var/mob/A in view(null, null)) - if(param == A.name) - M = A - break - if(!M) - param = null - - if(param) - message = "[src] bows to [param]." - else - message = "[src] bows." - m_type = 1 - - if("clap") - if(!src.restrained()) - message = "[src] claps." - m_type = 2 - if("flap") - if(!src.restrained()) - message = "[src] flaps its wings." - m_type = 2 - - if("aflap") - if(!src.restrained()) - message = "[src] flaps its wings ANGRILY!" - m_type = 2 - - if("twitch") - message = "[src] twitches." - m_type = 1 - - if("twitch_v") - message = "[src] twitches violently." - m_type = 1 - - if("nod") - message = "[src] nods." - m_type = 1 - - if("deathgasp") - message = "[src] shudders violently for a moment, then becomes motionless, its eyes slowly darkening." - m_type = 1 - - if("glare") - var/M = null - if(param) - for (var/mob/A in view(null, null)) - if(param == A.name) - M = A - break - if(!M) - param = null - - if(param) - message = "[src] glares at [param]." - else - message = "[src] glares." - - if("stare") - var/M = null - if(param) - for (var/mob/A in view(null, null)) - if(param == A.name) - M = A - break - if(!M) - param = null - - if(param) - message = "[src] stares at [param]." - else - message = "[src] stares." - - if("look") - var/M = null - if(param) - for (var/mob/A in view(null, null)) - if(param == A.name) - M = A - break - - if(!M) - param = null - - if(param) - message = "[src] looks at [param]." - else - message = "[src] looks." - m_type = 1 - - if("law") - if(istype(module,/obj/item/weapon/robot_module/robot/security) || istype(module,/obj/item/weapon/robot_module/robot/knine)) //VOREStation Add - K9 - message = "[src] shows its legal authorization barcode." - - playsound(src, 'sound/voice/biamthelaw.ogg', 50, 0) - m_type = 2 - else - to_chat(src, "You are not THE LAW, pal.") - - if("halt") - if(istype(module,/obj/item/weapon/robot_module/robot/security) || istype(module,/obj/item/weapon/robot_module/robot/knine)) //VOREStation Add - K9 - message = "[src] 's speakers skreech, \"Halt! Security!\"." - - playsound(src, 'sound/voice/halt.ogg', 50, 0) - m_type = 2 - else - to_chat(src, "You are not security.") - //Vorestation addition start - if("bark") - if (istype(module,/obj/item/weapon/robot_module/robot/knine) || istype(module,/obj/item/weapon/robot_module/robot/medihound) || istype(module,/obj/item/weapon/robot_module/robot/scrubpup) || istype(module,/obj/item/weapon/robot_module/robot/ert) || istype(module,/obj/item/weapon/robot_module/robot/science) || istype(module,/obj/item/weapon/robot_module/robot/engiedog) || istype(module,/obj/item/weapon/robot_module/robot/clerical/brodog) || istype(module,/obj/item/weapon/robot_module/robot/kmine) ) - message = "[src] lets out a bark." - - playsound(src, 'sound/voice/bark2.ogg', 50, 1, -1, preference = /datum/client_preference/emote_noises) - m_type = 2 - else - to_chat(src, "You're not a dog!") - //Vorestation addition end - - - - if("help") - to_chat(src, "salute, bow-(none)/mob, clap, flap, aflap, twitch, twitch_s, nod, deathgasp, glare-(none)/mob, stare-(none)/mob, look, beep, ping, \nbuzz, law, halt, yes, dwoop, no") - - ..(act, m_type, message) +/mob/living/silicon/robot/get_default_emotes() + return global._robot_default_emotes diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 229aa7b66a9..82bc2e24989 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -209,12 +209,12 @@ /mob/living/silicon/robot/proc/setup_PDA() if (!rbPDA) rbPDA = new/obj/item/device/pda/ai(src) - rbPDA.set_name_and_job(custom_name,"[modtype] [braintype]") + rbPDA.set_name_and_job(name,"[modtype] [braintype]") /mob/living/silicon/robot/proc/setup_communicator() if (!communicator) communicator = new/obj/item/device/communicator/integrated(src) - communicator.register_device(src.name, "[modtype] [braintype]") + communicator.register_device(name, "[modtype] [braintype]") //If there's an MMI in the robot, have it ejected when the mob goes away. --NEO //Improved /N diff --git a/code/modules/mob/living/silicon/say.dm b/code/modules/mob/living/silicon/say.dm index ef870cb1f35..34f6096ede0 100644 --- a/code/modules/mob/living/silicon/say.dm +++ b/code/modules/mob/living/silicon/say.dm @@ -114,7 +114,7 @@ return 0 return 1 -/mob/living/silicon/ai/emote(var/act, var/type, var/message) +/mob/living/silicon/ai/emote(var/act, var/m_type, var/message) var/obj/machinery/hologram/holopad/T = holo if(T && T.masters[src]) //Is the AI using a holopad? . = holopad_emote(message) diff --git a/code/modules/mob/living/simple_mob/simple_mob_vr.dm b/code/modules/mob/living/simple_mob/simple_mob_vr.dm index b51577ce078..f18a745486b 100644 --- a/code/modules/mob/living/simple_mob/simple_mob_vr.dm +++ b/code/modules/mob/living/simple_mob/simple_mob_vr.dm @@ -84,6 +84,7 @@ icon_state = "[icon_dead]-[vore_fullness]" else if(((stat == UNCONSCIOUS) || resting || incapacitated(INCAPACITATION_DISABLED) ) && icon_rest && (vore_icons & SA_ICON_REST)) icon_state = "[icon_rest]-[vore_fullness]" + update_transform() /mob/living/simple_mob/proc/will_eat(var/mob/living/M) if(client) //You do this yourself, dick! diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/giant_spider_vr.dm b/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/giant_spider_vr.dm index a12a76a6796..45ce8eb9ad5 100644 --- a/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/giant_spider_vr.dm +++ b/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/giant_spider_vr.dm @@ -50,3 +50,9 @@ pixel_y = -16 old_x = -16 old_y = -16 + +/mob/living/simple_mob/animal/giant_spider/nurse/eggless/lay_eggs(turf/T) + return FALSE + +/mob/living/simple_mob/animal/giant_spider/nurse/queen/eggless/lay_eggs(turf/T) + return FALSE \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/pets/cat.dm b/code/modules/mob/living/simple_mob/subtypes/animal/pets/cat.dm index 9db6a6bffa0..c48f94bf277 100644 --- a/code/modules/mob/living/simple_mob/subtypes/animal/pets/cat.dm +++ b/code/modules/mob/living/simple_mob/subtypes/animal/pets/cat.dm @@ -1,3 +1,32 @@ +var/list/_cat_default_emotes = list( + /decl/emote/visible, + /decl/emote/visible/scratch, + /decl/emote/visible/drool, + /decl/emote/visible/nod, + /decl/emote/visible/sway, + /decl/emote/visible/sulk, + /decl/emote/visible/twitch, + /decl/emote/visible/twitch_v, + /decl/emote/visible/dance, + /decl/emote/visible/roll, + /decl/emote/visible/shake, + /decl/emote/visible/jump, + /decl/emote/visible/shiver, + /decl/emote/visible/collapse, + /decl/emote/visible/spin, + /decl/emote/visible/sidestep, + /decl/emote/audible, + /decl/emote/audible/hiss, + /decl/emote/audible/whimper, + /decl/emote/audible/gasp, + /decl/emote/audible/scretch, + /decl/emote/audible/choke, + /decl/emote/audible/moan, + /decl/emote/audible/gnarl, + /decl/emote/audible/purr, + /decl/emote/audible/purrlong +) + /mob/living/simple_mob/animal/passive/cat name = "cat" desc = "A domesticated, feline pet. Has a tendency to adopt crewmembers." @@ -28,6 +57,9 @@ update_icon() return ..() +/mob/living/simple_mob/animal/passive/cat/get_default_emotes() + return global._cat_default_emotes + /mob/living/simple_mob/animal/passive/cat/handle_special() if(!stat && prob(2)) // spooky var/mob/observer/dead/spook = locate() in range(src, 5) diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/space/snake_vr.dm b/code/modules/mob/living/simple_mob/subtypes/animal/space/snake_vr.dm index 903f4b9ce61..c30dd4be5ae 100644 --- a/code/modules/mob/living/simple_mob/subtypes/animal/space/snake_vr.dm +++ b/code/modules/mob/living/simple_mob/subtypes/animal/space/snake_vr.dm @@ -1,6 +1,24 @@ +/datum/category_item/catalogue/fauna/snake + name = "Wildlife - Snake" + desc = "Classification: Reptilia Serpentes\ +

\ + Snakes are elongated, limbless, carnivorous reptiles of the suborder Serpentes \ + Like all other squamates, snakes are ectothermic, amniote vertebrates covered in overlapping scales. \ + Many species of snakes have skulls with several more joints than their lizard ancestors, \ + enabling them to swallow prey much larger than their heads with their highly mobile jaws. \ +
\ + This species of snake is nonvenomous and use their large bodies to primarily subdue their prey. \ + Nonvenomous snakes either swallow prey alive or kill them by constriction - this is dependant on the prey. \ +
\ + This specific snake is nonvenomous and is mostly passive - however they will attack if threatened - it is \ + recommended that persons keep their distance as to not provoke these animals." + value = CATALOGUER_REWARD_TRIVIAL + /mob/living/simple_mob/animal/passive/snake name = "snake" desc = "A big thick snake." + tt_desc = "Reptilia Serpentes" + catalogue_data = list(/datum/category_item/catalogue/fauna/snake) icon_state = "snake" icon_living = "snake" diff --git a/code/modules/mob/living/simple_mob/subtypes/slime/slime.dm b/code/modules/mob/living/simple_mob/subtypes/slime/slime.dm index a5419bc5599..f8d47a4b2dc 100644 --- a/code/modules/mob/living/simple_mob/subtypes/slime/slime.dm +++ b/code/modules/mob/living/simple_mob/subtypes/slime/slime.dm @@ -1,5 +1,21 @@ -// The top-level slime defines. Xenobio slimes and feral slimes will inherit from this. +var/list/_slime_default_emotes = list( + /decl/emote/audible/moan, + /decl/emote/visible/twitch, + /decl/emote/visible/sway, + /decl/emote/visible/shiver, + /decl/emote/visible/bounce, + /decl/emote/visible/jiggle, + /decl/emote/visible/lightup, + /decl/emote/visible/vibrate, + /decl/emote/slime, + /decl/emote/slime/pout, + /decl/emote/slime/sad, + /decl/emote/slime/angry, + /decl/emote/slime/frown, + /decl/emote/slime/smile +) +// The top-level slime defines. Xenobio slimes and feral slimes will inherit from this. /mob/living/simple_mob/slime name = "slime" desc = "It's a slime." @@ -64,6 +80,9 @@ can_enter_vent_with = list(/obj/item/clothing/head) +/mob/living/simple_mob/slime/get_default_emotes() + return global._slime_default_emotes + /datum/say_list/slime speak = list("Blorp...", "Blop...") emote_see = list("bounces", "jiggles", "sways") diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/deathclaw.dm b/code/modules/mob/living/simple_mob/subtypes/vore/deathclaw.dm index 5b96ab7ee8f..66e38f6a8f9 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/deathclaw.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/deathclaw.dm @@ -1,13 +1,28 @@ -/datum/category_item/catalogue/fauna/deathclaw //TODO: VIRGO_LORE_WRITING_WIP +/datum/category_item/catalogue/fauna/deathclaw name = "Creature - Deathclaw" - desc = "A massive beast, tall as three standard-size humans, with massive, terrifying claws, \ - and dark, black fangs. It's entire body is yellowish, like sand, and it's skin is leathery and tough. \ - It seems to have adapted to the harsh desert environment on Virgo 4, and makes it's home inside the caves." + desc = "Classification: Trioceros dominus\ +

\ + Originally the Deathclaw was a top secret genetics project that was run by ancestral Zorren which was \ + lost to time. While it is not immediately evident in their body structure, these creatures bare a \ + subtle genetic connection to Zorren, however, this connection is marred by the other genes that \ + have been grafted onto the DNA strucutre of the Deathclaw. The creatures are known to attack humans \ + and other animals regularly to protect their territory or to hunt for food. It is speculated that \ + they escaped roughly around the time as whatever calamity befell the Zorren many centuries ago \ + as sighting of these beasts in the wild began around that time according to recovered Zorren texts. \ +
\ + Deathclaws are a large, carnivorous, bipedal reptile species, designed for maximum lethality. \ + Deathclaws are made even more dangerous by their reproductive instincts. deathclaws are an oviparous species, \ + female deathclaws will lay eggs in clusters, sired by the strongest male deathclaws in the pack, typically the alpha male.\ +
\ + These creatures are considered an invasive species, and thus hunters are encouraged to hunt them \ + although they are cautioned when doing so due to the danger that the creature poses." value = CATALOGUER_REWARD_HARD /mob/living/simple_mob/vore/aggressive/deathclaw name = "deathclaw" desc = "Big! Big! The size of three men! Claws as long as my forearm! Ripped apart! Ripped apart!" + tt_desc = "Trioceros dominus" + catalogue_data = list(/datum/category_item/catalogue/fauna/deathclaw) icon_dead = "deathclaw-dead" icon_living = "deathclaw" diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/fennec.dm b/code/modules/mob/living/simple_mob/subtypes/vore/fennec.dm index c35e421fab2..ec8a8f2f65a 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/fennec.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/fennec.dm @@ -1,15 +1,31 @@ -/datum/category_item/catalogue/fauna/fennec //TODO: VIRGO_LORE_WRITING_WIP +/datum/category_item/catalogue/fauna/fennec name = "Wildlife - Fennec" - desc = "A small, dusty, big-eared sandfox, native to Virgo 4. It looks like a Zorren that's on all fours, \ - and it's easy to see the resemblance to the little dunefox-like critters the Zorren are. However, the fennecs \ - lack the sentience the Zorren have, and are therefore naught more than cute little critters, with a hungry \ - attitude, willing to eat damn near anything they come across or can bump into. Bapping them will make them stop." + desc = "Classification: Vulpes zerda maxima\ +

\ + The Fennec fox is a small crepuscular fox native to Earth in Sol that nearly went extinct in the 2030s.\ + Through conservation efforts and the rise of space colonies, the Fennec was brought back from the brink \ + and is now labeled as 'Least Concern'. During the great Sol Expansion Period, Fennec were brought with \ + colonist as a means of companionship and as a ecosystem balance for desert worlds such as Virgo 4. \ + Their presence on Virgo 4 is largely due to convergent evolution. While their genetics are closely \ + related to their Sol counterparts, they are in fact a totally different species of fennec that have followed. \ + a separate evolutional path. Virgo Fennec are upwards of five times larger than their Sol cousins and consequently \ + have a larger appetite. Their diet mainly consists of whatever small creatures that they manage to scrounge from \ + the sands of Virgo 4, however they have been known to hunt larger prey in desperate times.\ +
\ + Fennec foxes reach sexual maturity at around nine months and mate between January and April \ + They usually breed only once per year. After mating, the male becomes very aggressive and protects \ + the female, provides her with food during pregnancy and lactation.\ +
\ + Virgo Fennecs have been observed to be passive and do not actively hunt large prey as their bodies have \ + grown accustomed to less available food sources. However, travellers are still cautioned on approaching \ + them as Virgo Fennec have been known to swallow prey whole depending on the prey's size." value = CATALOGUER_REWARD_TRIVIAL /mob/living/simple_mob/vore/fennec name = "fennec" //why isn't this in the fox file, fennecs are foxes silly. desc = "It's a dusty big-eared sandfox! Adorable!" - tt_desc = "Vulpes zerda" + tt_desc = "Vulpes zerda maxima" + catalogue_data = list(/datum/category_item/catalogue/fauna/fennec) icon_state = "fennec" icon_living = "fennec" diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/frog.dm b/code/modules/mob/living/simple_mob/subtypes/vore/frog.dm index 9e1609336d5..c6ea3efbc16 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/frog.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/frog.dm @@ -1,7 +1,27 @@ +/datum/category_item/catalogue/fauna/frog + name = "Wildlife - Giant Frog" + desc = "Classification: Anura gigantus\ +

\ + A frog is any member of a diverse and largely carnivorous group of short-bodied, tailless amphibians composing \ + the order Anura. This specific species - Anura gigantus - is a mutated form of Frogs, largely due to exposure to mutagen chemicals. \ + These Giant Frogs are descendants from scientific frogs that were used for study during the great Sol Expansion Period. \ + Modern day Giant Frogs have reverted to a more feral state compared to their original ancestors and are hostile \ + towards humans and other small wildlife - hunting them for food.\ +
\ + The particular breed of Frog that was originally used in the scientific experiments were known as explosive breeders.\ + With explosive breeders, mature adult frogs arrive at breeding sites in response to certain trigger factors such as rainfall \ + occurring in an arid area. In these frogs, mating and spawning take place promptly and the speed of larval growth is rapid in \ + order to make use of the ephemeral pools before they dry up. Because of this, the Frog population is through the roof and has \ + become a major issue for various colonies and stations.\ +
\ + These animals, are considered an invasive species, and thus hunters are encouraged to hunt them." + value = CATALOGUER_REWARD_TRIVIAL + /mob/living/simple_mob/vore/aggressive/frog name = "giant frog" desc = "You've heard of having a frog in your throat, now get ready for the reverse." tt_desc = "Anura gigantus" + catalogue_data = list(/datum/category_item/catalogue/fauna/frog) icon_dead = "frog-dead" icon_living = "frog" diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/mimic.dm b/code/modules/mob/living/simple_mob/subtypes/vore/mimic.dm index 5307a05cd03..8572416cd09 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/mimic.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/mimic.dm @@ -1,8 +1,18 @@ -/datum/category_item/catalogue/fauna/mimic //TODO: VIRGO_LORE_WRITING_WIP +/datum/category_item/catalogue/fauna/mimic name = "Aberration - Mimic" - desc = "A being that seems to take the form of a crate, for whatever reason. \ - It seems to lie in wait for it's prey, and then pounce once the unsuspecting person attempts to open it. \ - For whatever reason, they seem native to underground areas, and they're very tough, and hard to kill, able to pounce fast." + desc = "Classification: Mimus vorare\ +

\ + Mimics are morph creatures that share properties with the likes of Prometheans. They could assume any shape, \ + provided that they retained the same volume. In order to most effectively lure prey, they most commonly \ + take the shape of chests and other objects likely to be touched by someone - though the latter is rarer \ + than the former. \ +
\ + Mimics prefer consuming large prey such as humans or humanoid species, however, for means of survival they \ + might resort to eating smaller prey. A meal of one or two humanoids could sustain a mimic for several \ + months at a time - the main reason that they prey on humanoids to begin with. They reproduced asexually \ + by splitting their mass, the young growing to adulthood within a few years time.\ +
\ + Mimics have no concerns beyond surviving and acquiring food." value = CATALOGUER_REWARD_HARD /obj/structure/closet/crate/mimic @@ -63,9 +73,11 @@ /mob/living/simple_mob/vore/aggressive/mimic name = "crate" desc = "A rectangular steel crate." + + icon_state = "crate" icon_living = "crate" - icon = 'icons/obj/storage_vr.dmi' + icon = 'icons/obj/storage.dmi' faction = "mimic" @@ -101,6 +113,8 @@ showvoreprefs = 0 //Hides mechanical vore prefs for mimics. You can't see their gaping maws when they're just sitting idle. /mob/living/simple_mob/vore/aggressive/mimic + tt_desc = "Mimus vorare" + catalogue_data = list(/datum/category_item/catalogue/fauna/mimic) vore_active = 1 vore_pounce_chance = 10 swallowTime = 3 SECONDS diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/rabbit.dm b/code/modules/mob/living/simple_mob/subtypes/vore/rabbit.dm index a49309e7138..4d268567b8f 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/rabbit.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/rabbit.dm @@ -34,7 +34,6 @@ // Vore vars vore_active = 1 - vore_bump_chance = 10 vore_bump_emote = "playfully lunges at" vore_pounce_chance = 40 vore_pounce_maxhealth = 100 // They won't pounce by default, as they're passive. This is just so the nom check succeeds. :u @@ -140,6 +139,7 @@ movement_cooldown = 0.5 // very fast bunbun. + vore_bump_chance = 10 vore_pounce_chance = 100 vore_pounce_falloff = 0.2 @@ -149,4 +149,4 @@ ai_holder_type = /datum/ai_holder/simple_mob/melee/evasive /mob/living/simple_mob/vore/rabbit/killer/ex_act() - gib() \ No newline at end of file + gib() diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/rat.dm b/code/modules/mob/living/simple_mob/subtypes/vore/rat.dm index d708f265bb3..a1afb7bbb20 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/rat.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/rat.dm @@ -1,14 +1,28 @@ -/datum/category_item/catalogue/fauna/rat //TODO: VIRGO_LORE_WRITING_WIP +/datum/category_item/catalogue/fauna/rat name = "Creature - Rat" - desc = "A massive rat, some sort of mutated descendant of normal Earth rats. These ones seem particularly hungry, \ - and are able to pounce and stun their targets - presumably to eat them. Their bodies are long and greyfurred, \ - with a pink nose and large teeth, just like their regular-sized counterparts." + desc = "Classification: Mus muscular\ +

\ + Rats are various medium-sized, long-tailed rodents. Species of rats are found throughout the order Rodentia, \ + but stereotypical rats are found in the genus Rattus. This specific species of rat is a mutated descendant from lab rats. \ + It is unclear what experiment caused this species to grow to such an unnatural size, however it hasn't affected the rat's \ + general docile nature. When encountered by humans or other species it generally ignores them unless provoked.\ +
\ + Rats become sexually mature at age 6 weeks, but reach social maturity at about 5 to 6 months of age. \ + The average lifespan of rats varies by species, but many only live about a year due to predation. \ + However, due to the large nature of this particular species of rat, predation is usually not that much of an issue. \ + This doesn't mean that there is an overpopulation, though, quite the opposite. Giant Rats are rare and this is usually \ + due to small litter sizes and lack of proper food sources. Areas that one would typically see a Giant Rat is large garbage \ + disposals or areas that have large amounts of live food (other rats, mice, etc.) such as maintenance tunnels. \ +
\ + Male rats are called bucks; unmated females, does, pregnant or parent females, dams; and infants, kittens or pups. \ + A group of rats is referred to as a mischief." value = CATALOGUER_REWARD_MEDIUM /mob/living/simple_mob/vore/aggressive/rat name = "giant rat" desc = "In what passes for a hierarchy among verminous rodents, this one is king." tt_desc = "Mus muscular" + catalogue_data = list(/datum/category_item/catalogue/fauna/rat) icon_state = "rous" icon_living = "rous" diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/sect_drone.dm b/code/modules/mob/living/simple_mob/subtypes/vore/sect_drone.dm index 619e0acad0f..3c7aabfca4a 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/sect_drone.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/sect_drone.dm @@ -1,12 +1,28 @@ /datum/category_item/catalogue/fauna/sect_drone name = "Creature - Sect Drone" - desc = "Database Update Pending" //TODO: Virgo Lore Writing WIP + desc = "Classification: V Insecta gigantus\ +

\ + A massively-sized insect that is native to Virgo 3B. Much like its queen, it bears the combined physical traits \ + of several of Earth's insects. Its forelegs have claws bearing serrated edges much like a Mantis, which it uses \ + in both self-defense and during its hunts. On it's back are two large semi transparent wings like a beetle that it \ + uses for increased mobility. Covering its body is a layer of light, thick, and protective chitin, resilient enough to absorb \ + most physical damage while being light enough for the Sect Drone to hover. \ +
\ + It is not uncommon for a Sect Drone to go out alone to search for potential prey to bring back to the nest. \ + Regardless of reason, it is cautioned against approaching a Sect Drone as, like their queen, their behaviour is wildly \ + inconsistent. A Sect Drone can vary from hostile to docile depending on certain factors that scientists have \ + yet to uncover. \ +
\ + The lack of chitin on the underside of its abdomen is deliberate, as the flesh is very elastic and stretchable, \ + allowing the drone to carry multiple large prey inside of its stomach with relative ease." value = CATALOGUER_REWARD_MEDIUM /mob/living/simple_mob/vore/sect_drone name = "sect drone" desc = "A large, chitin-plated insectoid whose multiple cyan eyes cast a frightful blue light. Its \ abdomen has an unusually soft and... flexible-looking underbelly..." + tt_desc = "V Insecta gigantus" + catalogue_data = list(/datum/category_item/catalogue/fauna/sect_drone) icon_dead = "sect_drone_dead" icon_living = "sect_drone" @@ -64,4 +80,4 @@ say_list_type = /datum/say_list/sect_drone /datum/say_list/sect_drone - say_got_target = list("chitters threateningly!") \ No newline at end of file + say_got_target = list("chitters threateningly!") diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/sect_queen.dm b/code/modules/mob/living/simple_mob/subtypes/vore/sect_queen.dm index bb0933dd862..649062e8733 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/sect_queen.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/sect_queen.dm @@ -2,20 +2,30 @@ /datum/category_item/catalogue/fauna/sect_queen name = "Creature - Sect Queen" - desc = "A massively-sized insect that is native, although rarely spotted outside of its colony, to Virgo 3B. \ + desc = "Classification: V Insecta maximus gigantus\ +

\ + A massively-sized insect that is native - although rarely spotted outside of its colony - to Virgo 3B. \ It bears the combined physical traits of several of Earth's insects. Its forelegs have claws bearing serrated \ - edges, which it uses in both self-defense and during its hunts. Covering its body is a layer of thick and \ - protective chitin, resilient enough to absorb most physical damage. It is not uncommon for a queen to go out \ - alone to search for potential new nesting grounds... or perhaps it does so to seek bigger prey that its much \ - smaller drones might be unable to acquire. The lack of chitin on the underside of its abdomen is deliberate, \ - as the flesh is very elastic and stretchable, allowing the queen to carry multiple large prey inside of its \ - stomach with ease." + edges much like a Mantis, which it uses in both self-defense and during its hunts. Covering its body is a layer \ + of thick and protective chitin, resilient enough to absorb most physical damage. \ +
\ + Though rarely seen, it is not uncommon for a queen to go out alone to search for potential new nesting grounds \ + or perhaps it does so to seek bigger prey that its much smaller drones might be unable to acquire. \ + Regardless of reason, it is cautioned against approaching a Sect Queen as their behaviour is wildly \ + inconsistent. A Sect Queen can vary from hostile to docile depending on certain factors that scientists have \ + yet to uncover. \ +
\ + The lack of chitin on the underside of its abdomen is deliberate, as the flesh is very elastic and stretchable, \ + allowing the queen to carry multiple large prey inside of its stomach with ease. There is no know limit to home much \ + prey a single specimen can carry and scientists are wary to find said limit." value = CATALOGUER_REWARD_MEDIUM /mob/living/simple_mob/vore/sect_queen name = "sect queen" desc = "A titanic, chitin-plated insectoid whose multiple crimson eyes cast a frightful red light. Its \ abdomen has an unusually soft and... flexible-looking underbelly..." + tt_desc = "V Insecta maximus gigantus" + catalogue_data = list(/datum/category_item/catalogue/fauna/sect_queen) icon_dead = "sect_queen_dead" icon_living = "sect_queen" @@ -72,4 +82,4 @@ say_list_type = /datum/say_list/sect_queen /datum/say_list/sect_queen - say_got_target = list("chitters angrily!") \ No newline at end of file + say_got_target = list("chitters angrily!") diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/snake.dm b/code/modules/mob/living/simple_mob/subtypes/vore/snake.dm index de2139fd1a8..651599e3525 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/snake.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/snake.dm @@ -1,6 +1,29 @@ +/datum/category_item/catalogue/fauna/giant_snake + name = "Creature - Giant Snake" + desc = "Classification: Serpentes gigantus\ +

\ + Snakes are elongated, limbless, carnivorous reptiles of the suborder Serpentes \ + Like all other squamates, snakes are ectothermic, amniote vertebrates covered in overlapping scales. \ + Many species of snakes have skulls with several more joints than their lizard ancestors, \ + enabling them to swallow prey much larger than their heads with their highly mobile jaws. \ + This particular species of snake has likely been mutated by deliberate gene manipulation of some sort and as a \ + result has grown to unnatural size. Biologically this snake is no different than that of the common snake, \ + but this species has been known to have increased hostility towards wildlife. Scientists are still studying \ + this new species for any differences in behavior or biology beyond the increase in size. \ +
\ + This species of snake is nonvenomous and use their large bodies to primarily subdue their prey. \ + Nonvenomous snakes either swallow prey alive or kill them by constriction - this is dependant on the prey. \ +
\ + This snake is extremely hostile to all wildlife and living beings and should be avoided at all costs. \ + People who spot these creatures are urged to inform the nearest militant entity so that they can be \ + dealt with in a professional manner." + value = CATALOGUER_REWARD_HARD + /mob/living/simple_mob/vore/aggressive/giant_snake name = "giant snake" desc = "Snakes. Why did it have to be snakes?" + tt_desc = "Serpentes gigantus" + catalogue_data = list(/datum/category_item/catalogue/fauna/giant_snake) icon_dead = "snake-dead" icon_living = "snake" diff --git a/code/modules/mob/living/voice/voice.dm b/code/modules/mob/living/voice/voice.dm index 2d070d1a298..9caa58cb33d 100644 --- a/code/modules/mob/living/voice/voice.dm +++ b/code/modules/mob/living/voice/voice.dm @@ -137,6 +137,6 @@ return TRUE return ..() -/mob/living/voice/custom_emote(var/m_type=1,var/message = null,var/range=world.view) +/mob/living/voice/custom_emote(var/m_type = VISIBLE_MESSAGE, var/message = null, var/range = world.view) if(!comm) return ..(m_type,message,comm.video_range) diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm index d6f04cd0d59..1c1321a715d 100644 --- a/code/modules/mob/login.dm +++ b/code/modules/mob/login.dm @@ -44,6 +44,7 @@ disconnect_time = null //VOREStation Addition: clear the disconnect time sight |= SEE_SELF ..() + SEND_SIGNAL(src, COMSIG_MOB_LOGIN) if(loc && !isturf(loc)) client.eye = loc @@ -81,4 +82,5 @@ update_client_z(T.z) if(cloaked && cloaked_selfimage) - client.images += cloaked_selfimage \ No newline at end of file + client.images += cloaked_selfimage + SEND_SIGNAL(src, COMSIG_MOB_CLIENT_LOGIN, client) \ No newline at end of file diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 3b4b478a7eb..c41691a8575 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -42,6 +42,7 @@ lastarea = get_area(src) hook_vr("mob_new",list(src)) //VOREStation Code update_transform() // Some mobs may start bigger or smaller than normal. + update_emotes() return ..() /mob/proc/show_message(msg, type, alt, alt_type)//Message, type of message (1 or 2), alternative message, alt message type (1 or 2) @@ -49,19 +50,19 @@ if(!client && !teleop) return if (type) - if((type & 1) && (is_blind() || paralysis) )//Vision related + if((type & VISIBLE_MESSAGE) && (is_blind() || paralysis) )//Vision related if (!( alt )) return else msg = alt type = alt_type - if ((type & 2) && is_deaf())//Hearing related + if ((type & AUDIBLE_MESSAGE) && is_deaf())//Hearing related if (!( alt )) return else msg = alt type = alt_type - if ((type & 1) && (sdisabilities & BLIND)) + if ((type & VISIBLE_MESSAGE) && (sdisabilities & BLIND)) return // Added voice muffling for Issue 41. if(stat == UNCONSCIOUS || sleeping > 0) @@ -77,14 +78,17 @@ // message is the message output to anyone who can see e.g. "[src] does something!" // self_message (optional) is what the src mob sees e.g. "You do something!" // blind_message (optional) is what blind people will hear e.g. "You hear something!" -/mob/visible_message(var/message, var/self_message, var/blind_message, var/list/exclude_mobs = null) +/mob/visible_message(var/message, var/self_message, var/blind_message, var/list/exclude_mobs = null, var/range = world.view) if(self_message) if(LAZYLEN(exclude_mobs)) exclude_mobs |= src else exclude_mobs = list(src) src.show_message(self_message, 1, blind_message, 2) - . = ..(message, blind_message, exclude_mobs) + // Transfer messages about what we are doing to upstairs + if(shadow) + shadow.visible_message(message, self_message, blind_message, exclude_mobs, range) + . = ..(message, blind_message, exclude_mobs, range) // Really not ideal that atom/visible_message has different arg numbering :( // Returns an amount of power drawn from the object (-1 if it's not viable). // If drain_check is set it will not actually drain power, just return a value. @@ -99,7 +103,7 @@ // self_message (optional) is what the src mob hears. // deaf_message (optional) is what deaf people will see. // hearing_distance (optional) is the range, how many tiles away the message can be heard. -/mob/audible_message(var/message, var/deaf_message, var/hearing_distance, var/self_message) +/mob/audible_message(var/message, var/deaf_message, var/hearing_distance, var/self_message, var/radio_message) var/range = hearing_distance || world.view var/list/hear = get_mobs_and_objs_in_view_fast(get_turf(src),range,remote_ghosts = FALSE) @@ -107,16 +111,21 @@ var/list/hearing_mobs = hear["mobs"] var/list/hearing_objs = hear["objs"] - for(var/obj in hearing_objs) - var/obj/O = obj - O.show_message(message, 2, deaf_message, 1) + if(radio_message) + for(var/obj in hearing_objs) + var/obj/O = obj + O.hear_talk(src, list(new /datum/multilingual_say_piece(GLOB.all_languages["Noise"], radio_message)), null) + else + for(var/obj in hearing_objs) + var/obj/O = obj + O.show_message(message, AUDIBLE_MESSAGE, deaf_message, VISIBLE_MESSAGE) for(var/mob in hearing_mobs) var/mob/M = mob var/msg = message if(self_message && M==src) msg = self_message - M.show_message(msg, 2, deaf_message, 1) + M.show_message(msg, AUDIBLE_MESSAGE, deaf_message, VISIBLE_MESSAGE) /mob/proc/findname(msg) for(var/mob/M in mob_list) @@ -576,9 +585,6 @@ /mob/proc/get_gender() return gender -/mob/proc/get_visible_gender() - return gender - /mob/proc/see(message) if(!is_active()) return 0 diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index ebcc9cf35a2..259aaf75c85 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -477,19 +477,26 @@ /mob/proc/update_gravity() return +#define DO_MOVE(this_dir) var/final_dir = turn(this_dir, -dir2angle(dir)); Move(get_step(mob, final_dir), final_dir); + /client/verb/moveup() set name = ".moveup" set instant = 1 - Move(get_step(mob, NORTH), NORTH) + DO_MOVE(NORTH) + /client/verb/movedown() set name = ".movedown" set instant = 1 - Move(get_step(mob, SOUTH), SOUTH) + DO_MOVE(SOUTH) + /client/verb/moveright() set name = ".moveright" set instant = 1 - Move(get_step(mob, EAST), EAST) + DO_MOVE(EAST) + /client/verb/moveleft() set name = ".moveleft" set instant = 1 - Move(get_step(mob, WEST), WEST) + DO_MOVE(WEST) + +#undef DO_MOVE diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index 64ffdbed901..959b0ad99e3 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -28,8 +28,10 @@ /mob/new_player/proc/new_player_panel_proc() var/output = "
" + /* VOREStation Removal output += "[using_map.get_map_info()]" output +="
" + VOREStation Removal End */ output += "

Character Setup

" if(!ticker || ticker.current_state <= GAME_STATE_PREGAME) @@ -79,7 +81,7 @@ if(GLOB.news_data.station_newspaper && !client.seen_news) show_latest_news(GLOB.news_data.station_newspaper) - panel = new(src, "Welcome","Welcome", 500, 480, src) + panel = new(src, "Welcome","Welcome", 210, 300, src) // VOREStation Edit panel.set_window_options("can_close=0") panel.set_content(output) panel.open() diff --git a/code/modules/mob/new_player/sprite_accessories.dm b/code/modules/mob/new_player/sprite_accessories.dm index f04cde9c4cf..1a13a7ed621 100644 --- a/code/modules/mob/new_player/sprite_accessories.dm +++ b/code/modules/mob/new_player/sprite_accessories.dm @@ -28,7 +28,7 @@ // Determines if the accessory will be skipped or included in random hair generations var/gender = NEUTER - // Restrict some styles to specific species + // Restrict some styles to specific species. Set to null to perform no checking. var/list/species_allowed = list(SPECIES_HUMAN,SPECIES_PROMETHEAN,SPECIES_HUMAN_VATBORN) // Whether or not the accessory can be affected by colouration @@ -38,7 +38,6 @@ // Ckey of person allowed to use this, if defined. var/list/ckeys_allowed = null - var/apply_restrictions = FALSE //whether to apply restrictions for specific tails/ears/wings /* //////////////////////////// diff --git a/code/modules/mob/new_player/sprite_accessories_ear.dm b/code/modules/mob/new_player/sprite_accessories_ear.dm index 6262b8ba606..24e82043e41 100644 --- a/code/modules/mob/new_player/sprite_accessories_ear.dm +++ b/code/modules/mob/new_player/sprite_accessories_ear.dm @@ -23,7 +23,7 @@ icon_state = "shadekin" do_colouration = 1 color_blend_mode = ICON_MULTIPLY - apply_restrictions = TRUE + species_allowed = list() // SPECIES_SHADEKIN, SPECIES_SHADEKIN_CREW /datum/sprite_accessory/ears/taj_ears name = "Tajaran Ears" diff --git a/code/modules/mob/new_player/sprite_accessories_ear_vr.dm b/code/modules/mob/new_player/sprite_accessories_ear_vr.dm index 7705e1a8217..fd82cac5b2e 100644 --- a/code/modules/mob/new_player/sprite_accessories_ear_vr.dm +++ b/code/modules/mob/new_player/sprite_accessories_ear_vr.dm @@ -20,7 +20,6 @@ icon_state = "shadekin" do_colouration = 1 color_blend_mode = ICON_MULTIPLY - apply_restrictions = TRUE species_allowed = list(SPECIES_SHADEKIN, SPECIES_SHADEKIN_CREW) // Ears avaliable to anyone diff --git a/code/modules/mob/new_player/sprite_accessories_tail.dm b/code/modules/mob/new_player/sprite_accessories_tail.dm index 0b8d75b84e3..dec95139744 100644 --- a/code/modules/mob/new_player/sprite_accessories_tail.dm +++ b/code/modules/mob/new_player/sprite_accessories_tail.dm @@ -922,7 +922,6 @@ icon_state = "shadekin-short" do_colouration = 1 color_blend_mode = ICON_MULTIPLY - //apply_restrictions = TRUE //species_allowed = list(SPECIES_SHADEKIN, SPECIES_SHADEKIN_CREW) /datum/sprite_accessory/tail/wartacosushi_tail //brightened +20RGB from matching roboparts diff --git a/code/modules/mob/new_player/sprite_accessories_taur.dm b/code/modules/mob/new_player/sprite_accessories_taur.dm index db2394f84af..dad54ed188c 100644 --- a/code/modules/mob/new_player/sprite_accessories_taur.dm +++ b/code/modules/mob/new_player/sprite_accessories_taur.dm @@ -333,7 +333,6 @@ hide_body_parts = null clip_mask_icon = null clip_mask_state = null - //apply_restrictions = TRUE //species_allowed = list(SPECIES_SHADEKIN, SPECIES_SHADEKIN_CREW) /datum/sprite_accessory/tail/taur/shadekin_tail/shadekin_tail_2c diff --git a/code/modules/mob/new_player/sprite_accessories_taur_vr.dm b/code/modules/mob/new_player/sprite_accessories_taur_vr.dm index 4bc79e1629b..fc3994b528f 100644 --- a/code/modules/mob/new_player/sprite_accessories_taur_vr.dm +++ b/code/modules/mob/new_player/sprite_accessories_taur_vr.dm @@ -83,6 +83,12 @@ extra_overlay2 = "synthwolf_glow" //icon_sprite_tag = "synthwolf" +/datum/sprite_accessory/tail/taur/ch/wolf/fatsynthwolf + name = "Fat SynthWolf dual-color (Taur)" + icon_state = "fatsynthwolf_s" + extra_overlay = "fatsynthwolf_markings" + extra_overlay2 = "fatsynthwolf_glow" + /datum/sprite_accessory/tail/taur/skunk name = "Skunk (Taur)" icon_state = "skunk_s" @@ -213,6 +219,15 @@ extra_overlay = "lizard_markings" //icon_sprite_tag = "lizard2c" +/datum/sprite_accessory/tail/taur/ch/lizard/fat + name = "Fat Lizard (Taur)" + icon_state = "fatlizard_s" + +/datum/sprite_accessory/tail/taur/ch/lizard/fat_2c + name = "Fat Lizard (Taur, dual-color)" + icon_state = "fatlizard_s" + extra_overlay= "fatlizard_markings" + /datum/sprite_accessory/tail/taur/lizard/synthlizard name = "SynthLizard dual-color (Taur)" icon_state = "synthlizard_s" @@ -220,6 +235,12 @@ extra_overlay2 = "synthlizard_glow" //icon_sprite_tag = "synthlizard" +/datum/sprite_accessory/tail/taur/ch/lizard/fatsynthlizard + name = "Fat SynthLizard dual-color (Taur)" + icon_state = "fatsynthlizard_s" + extra_overlay = "fatsynthlizard_markings" + extra_overlay2 = "fatsynthlizard_glow" + /datum/sprite_accessory/tail/taur/spider name = "Spider (Taur)" icon_state = "spider_s" @@ -305,6 +326,12 @@ extra_overlay2 = "synthfeline_glow" //icon_sprite_tag = "synthfeline" +/datum/sprite_accessory/tail/taur/ch/feline/fatsynthfeline + name = "Fat SynthFeline dual-color (Taur)" + icon_state = "fatsynthfeline_s" + extra_overlay = "fatsynthfeline_markings" + extra_overlay2 = "fatsynthfeline_glow" + /datum/sprite_accessory/tail/taur/slug name = "Slug (Taur)" icon_state = "slug_s" diff --git a/code/modules/mob/say.dm b/code/modules/mob/say.dm index 52e843a9eeb..c30d256c596 100644 --- a/code/modules/mob/say.dm +++ b/code/modules/mob/say.dm @@ -105,11 +105,6 @@ verb = "asks" return verb - -/mob/proc/emote(var/act, var/type, var/message) - if(act == "me") - return custom_emote(type, message) - /mob/proc/get_ear() // returns an atom representing a location on the map from which this // mob can hear things diff --git a/code/modules/multiz/zshadow.dm b/code/modules/multiz/zshadow.dm index fcc5ecad650..e43ab219395 100644 --- a/code/modules/multiz/zshadow.dm +++ b/code/modules/multiz/zshadow.dm @@ -113,12 +113,6 @@ if(shadow) shadow.set_dir(new_dir) -// Transfer messages about what we are doing to upstairs -/mob/visible_message(var/message, var/self_message, var/blind_message, var/list/exclude_mobs = null) - . = ..() - if(shadow) - shadow.visible_message(message, self_message, blind_message, exclude_mobs) - /mob/zshadow/set_typing_indicator(var/state) if(!typing_indicator) init_typing_indicator("typing") diff --git a/code/modules/nifsoft/nif.dm b/code/modules/nifsoft/nif.dm index a1027d60179..c185283b0e7 100644 --- a/code/modules/nifsoft/nif.dm +++ b/code/modules/nifsoft/nif.dm @@ -88,8 +88,9 @@ You can also set the stat of a NIF to NIF_TEMPFAIL without any issues to disable qdel(src) return FALSE else - //Free commlink for return customers + //Free commlink and soulcatcher for return customers new /datum/nifsoft/commlink(src) + new /datum/nifsoft/soulcatcher(src) //Free civilian AR included new /datum/nifsoft/ar_civ(src) diff --git a/code/modules/nifsoft/nif_softshop.dm b/code/modules/nifsoft/nif_softshop.dm index 5cfae594c4c..836ab612337 100644 --- a/code/modules/nifsoft/nif_softshop.dm +++ b/code/modules/nifsoft/nif_softshop.dm @@ -94,6 +94,7 @@ product.price = initial(NS.cost) product.amount = 10 product.category = category + product.item_desc = initial(NS.desc) product_records.Add(product) diff --git a/code/modules/nifsoft/software/01_vision.dm b/code/modules/nifsoft/software/01_vision.dm index 7a792009f45..c68a6feb0cc 100644 --- a/code/modules/nifsoft/software/01_vision.dm +++ b/code/modules/nifsoft/software/01_vision.dm @@ -34,9 +34,9 @@ /datum/nifsoft/ar_eng name = "AR Overlay (Eng)" - desc = "Like the civilian model, but provides station alert notices." + desc = "Like the civilian model, but provides ... well, nothing. For now." list_pos = NIF_ENGINE_AR - cost = 375 + cost = 250 access = access_engine a_drain = 0.01 planes_enabled = list(VIS_CH_ID,VIS_CH_HEALTH_VR,VIS_AUGMENTED) @@ -47,7 +47,7 @@ name = "AR Overlay (Sci)" desc = "Like the civilian model, but provides ... well, nothing. For now." list_pos = NIF_SCIENCE_AR - cost = 375 + cost = 250 access = access_research a_drain = 0.01 planes_enabled = list(VIS_CH_ID,VIS_CH_HEALTH_VR,VIS_AUGMENTED) diff --git a/code/modules/nifsoft/software/13_soulcatcher.dm b/code/modules/nifsoft/software/13_soulcatcher.dm index c1de0855326..ce9dfccf444 100644 --- a/code/modules/nifsoft/software/13_soulcatcher.dm +++ b/code/modules/nifsoft/software/13_soulcatcher.dm @@ -14,10 +14,10 @@ desc = "A mind storage and processing system capable of capturing and supporting human-level minds in a small VR space." list_pos = NIF_SOULCATCHER cost = 100 //If I wanna trap people's minds and lood them, then by god I'll do so. - wear = 1 + wear = 0 p_drain = 0.01 - var/setting_flags = (NIF_SC_CATCHING_OTHERS|NIF_SC_ALLOW_EARS|NIF_SC_ALLOW_EYES|NIF_SC_BACKUPS|NIF_SC_PROJECTING) + var/setting_flags = (NIF_SC_ALLOW_EARS|NIF_SC_ALLOW_EYES|NIF_SC_BACKUPS|NIF_SC_PROJECTING) var/list/brainmobs = list() var/inside_flavor = "A small completely white room with a couch, and a window to what seems to be the outside world. A small sign in the corner says 'Configure Me'." @@ -45,14 +45,14 @@ /datum/nifsoft/soulcatcher/install() if((. = ..())) nif.set_flag(NIF_O_SCOTHERS,NIF_FLAGS_OTHER) //Required on install, because other_flags aren't sufficient for our complicated settings. - nif.human.verbs |= /mob/living/carbon/human/proc/nsay - nif.human.verbs |= /mob/living/carbon/human/proc/nme + nif.human.verbs |= /mob/living/carbon/human/nsay + nif.human.verbs |= /mob/living/carbon/human/nme /datum/nifsoft/soulcatcher/uninstall() QDEL_LIST_NULL(brainmobs) if((. = ..()) && nif && nif.human) //Sometimes NIFs are deleted outside of a human - nif.human.verbs -= /mob/living/carbon/human/proc/nsay - nif.human.verbs -= /mob/living/carbon/human/proc/nme + nif.human.verbs -= /mob/living/carbon/human/nsay + nif.human.verbs -= /mob/living/carbon/human/nme /datum/nifsoft/soulcatcher/proc/save_settings() if(!nif) @@ -476,20 +476,26 @@ /////////////////// //Verbs for humans -/mob/living/carbon/human/proc/nsay(message as text|null) +/mob/proc/nsay(message as text|null) set name = "NSay" set desc = "Speak into your NIF's Soulcatcher." set category = "IC" + to_chat(src, SPAN_WARNING("You must be a humanoid with a NIF implanted to use that.")) + +/mob/living/carbon/human/nsay(message as text|null) + if(stat != CONSCIOUS) + to_chat(src,SPAN_WARNING("You can't use NSay while unconscious.")) + return if(!nif) - to_chat(src,"You can't use NSay without a NIF.") + to_chat(src,SPAN_WARNING("You can't use NSay without a NIF.")) return var/datum/nifsoft/soulcatcher/SC = nif.imp_check(NIF_SOULCATCHER) if(!SC) - to_chat(src,"You need the Soulcatcher software to use NSay.") + to_chat(src,SPAN_WARNING("You need the Soulcatcher software to use NSay.")) return if(!SC.brainmobs.len) - to_chat(src,"You need a loaded mind to use NSay.") + to_chat(src,SPAN_WARNING("You need a loaded mind to use NSay.")) return if(!message) message = input("Type a message to say.","Speak into Soulcatcher") as text|null @@ -497,20 +503,26 @@ var/sane_message = sanitize(message) SC.say_into(sane_message,src) -/mob/living/carbon/human/proc/nme(message as text|null) +/mob/proc/nme(message as text|null) set name = "NMe" set desc = "Emote into your NIF's Soulcatcher." set category = "IC" + + to_chat(src, SPAN_WARNING("You must be a humanoid with a NIF implanted to use that.")) +/mob/living/carbon/human/nme(message as text|null) + if(stat != CONSCIOUS) + to_chat(src,SPAN_WARNING("You can't use NMe while unconscious.")) + return if(!nif) - to_chat(src,"You can't use NMe without a NIF.") + to_chat(src,SPAN_WARNING("You can't use NMe without a NIF.")) return var/datum/nifsoft/soulcatcher/SC = nif.imp_check(NIF_SOULCATCHER) if(!SC) - to_chat(src,"You need the Soulcatcher software to use NMe.") + to_chat(src,SPAN_WARNING("You need the Soulcatcher software to use NMe.")) return if(!SC.brainmobs.len) - to_chat(src,"You need a loaded mind to use NMe.") + to_chat(src,SPAN_WARNING("You need a loaded mind to use NMe.")) return if(!message) @@ -563,7 +575,7 @@ QDEL_NULL(eyeobj) soulcatcher.notify_into("[src] ended AR projection.") -/mob/living/carbon/brain/caught_soul/verb/nsay(message as text|null) +/mob/living/carbon/brain/caught_soul/verb/nsay_brain(message as text|null) set name = "NSay" set desc = "Speak into the NIF's Soulcatcher (circumventing AR speaking)." set category = "Soulcatcher" @@ -574,7 +586,7 @@ var/sane_message = sanitize(message) soulcatcher.say_into(sane_message,src,null) -/mob/living/carbon/brain/caught_soul/verb/nme(message as text|null) +/mob/living/carbon/brain/caught_soul/verb/nme_brain(message as text|null) set name = "NMe" set desc = "Emote into the NIF's Soulcatcher (circumventing AR speaking)." set category = "Soulcatcher" diff --git a/code/modules/organs/internal/appendix.dm b/code/modules/organs/internal/appendix.dm index 553c542529b..047602ec4b5 100644 --- a/code/modules/organs/internal/appendix.dm +++ b/code/modules/organs/internal/appendix.dm @@ -30,11 +30,11 @@ if(inflamed == 1) if(prob(5)) to_chat(owner, "You feel a stinging pain in your abdomen!") - owner.emote("me", 1, "winces slightly.") + owner.custom_emote(VISIBLE_MESSAGE, "winces slightly.") if(inflamed > 1) if(prob(3)) to_chat(owner, "You feel a stabbing pain in your abdomen!") - owner.emote("me", 1, "winces painfully.") + owner.custom_emote(VISIBLE_MESSAGE, "winces painfully.") owner.adjustToxLoss(1) if(inflamed > 2) if(prob(1)) diff --git a/code/modules/organs/internal/brain.dm b/code/modules/organs/internal/brain.dm index c334a3a2829..3a4717224ee 100644 --- a/code/modules/organs/internal/brain.dm +++ b/code/modules/organs/internal/brain.dm @@ -276,19 +276,19 @@ GLOBAL_LIST_BOILERPLATE(all_brain_organs, /obj/item/organ/internal/brain) qdel(src) return 1 -/datum/chemical_reaction/promethean_brain_revival +/decl/chemical_reaction/instant/promethean_brain_revival name = "Promethean Revival" id = "prom_revival" result = null required_reagents = list("phoron" = 40) result_amount = 1 -/datum/chemical_reaction/promethean_brain_revival/can_happen(var/datum/reagents/holder) +/decl/chemical_reaction/instant/promethean_brain_revival/can_happen(var/datum/reagents/holder) if(holder.my_atom && istype(holder.my_atom, /obj/item/organ/internal/brain/slime)) return ..() return FALSE -/datum/chemical_reaction/promethean_brain_revival/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/promethean_brain_revival/on_reaction(var/datum/reagents/holder) var/obj/item/organ/internal/brain/slime/brain = holder.my_atom if(brain.reviveBody()) brain.visible_message("[brain] bubbles, surrounding itself with a rapidly expanding mass of slime!") diff --git a/code/modules/organs/internal/lungs.dm b/code/modules/organs/internal/lungs.dm index f123ea127b6..34d2c258b62 100644 --- a/code/modules/organs/internal/lungs.dm +++ b/code/modules/organs/internal/lungs.dm @@ -15,17 +15,17 @@ if(is_bruised()) if(prob(4)) - spawn owner?.emote("me", 1, "coughs up blood!") + spawn owner?.custom_emote(VISIBLE_MESSAGE, "coughs up blood!") owner.drip(10) if(prob(8)) - spawn owner?.emote("me", 1, "gasps for air!") + spawn owner?.custom_emote(VISIBLE_MESSAGE, "gasps for air!") owner.AdjustLosebreath(15) if(owner.internal_organs_by_name[O_BRAIN]) // As the brain starts having Trouble, the lungs start malfunctioning. var/obj/item/organ/internal/brain/Brain = owner.internal_organs_by_name[O_BRAIN] if(Brain.get_control_efficiency() <= 0.8) if(prob(4 / max(0.1,Brain.get_control_efficiency()))) - spawn owner?.emote("me", 1, "gasps for air!") + spawn owner?.custom_emote(VISIBLE_MESSAGE, "gasps for air!") owner.AdjustLosebreath(round(3 / max(0.1,Brain.get_control_efficiency()))) /obj/item/organ/internal/lungs/proc/rupture() diff --git a/code/modules/pda/messenger.dm b/code/modules/pda/messenger.dm index a902bec3aa4..efb87577d56 100644 --- a/code/modules/pda/messenger.dm +++ b/code/modules/pda/messenger.dm @@ -181,6 +181,7 @@ SStgui.update_user_uis(U, P) // Update the sending user's PDA UI so that they can see the new message log_pda("(PDA: [src.name]) sent \"[t]\" to [P.name]", usr) + to_chat(U, "[bicon(pda)] Sent message to [P.owner] ([P.ownjob]), \"[t]\"") else to_chat(U, "ERROR: Messaging server is not responding.") diff --git a/code/modules/persistence/noticeboard.dm b/code/modules/persistence/noticeboard.dm index c37e084ce8f..2677977253e 100644 --- a/code/modules/persistence/noticeboard.dm +++ b/code/modules/persistence/noticeboard.dm @@ -104,7 +104,7 @@ /obj/structure/noticeboard/examine(mob/user) tgui_interact(user) - return list() + return ..() /obj/structure/noticeboard/tgui_interact(mob/user, datum/tgui/ui) ui = SStgui.try_update_ui(user, src, ui) diff --git a/code/modules/planet/sif.dm b/code/modules/planet/sif.dm index 798cebcaac2..cefc549d2a6 100644 --- a/code/modules/planet/sif.dm +++ b/code/modules/planet/sif.dm @@ -156,6 +156,9 @@ var/datum/planet/sif/planet_sif = null sky_visible = TRUE observed_message = "The sky is clear." + outdoor_sounds_type = /datum/looping_sound/weather/wind/gentle + indoor_sounds_type = /datum/looping_sound/weather/wind/gentle/indoors + /datum/weather/sif/overcast name = "overcast" light_modifier = 0.8 @@ -174,6 +177,9 @@ var/datum/planet/sif/planet_sif = null "It's very cloudy." ) + outdoor_sounds_type = /datum/looping_sound/weather/wind/gentle + indoor_sounds_type = /datum/looping_sound/weather/wind/gentle/indoors + /datum/weather/sif/light_snow name = "light snow" icon_state = "snowfall_light" @@ -192,6 +198,9 @@ var/datum/planet/sif/planet_sif = null "It begins to snow lightly.", ) + outdoor_sounds_type = /datum/looping_sound/weather/wind/gentle + indoor_sounds_type = /datum/looping_sound/weather/wind/gentle/indoors + /datum/weather/sif/snow name = "moderate snow" icon_state = "snowfall_med" @@ -282,8 +291,8 @@ var/datum/planet/sif/planet_sif = null transition_messages = list( "The sky is dark, and rain falls down upon you." ) -// outdoor_sounds_type = /datum/looping_sound/weather/rain -// indoor_sounds_type = /datum/looping_sound/weather/rain/indoors + outdoor_sounds_type = /datum/looping_sound/weather/rain + indoor_sounds_type = /datum/looping_sound/weather/rain/indoors /datum/weather/sif/rain/process_effects() ..() @@ -327,8 +336,8 @@ var/datum/planet/sif/planet_sif = null "Loud thunder is heard in the distance.", "A bright flash heralds the approach of a storm." ) -// outdoor_sounds_type = /datum/looping_sound/weather/rain -// indoor_sounds_type = /datum/looping_sound/weather/rain/indoors + outdoor_sounds_type = /datum/looping_sound/weather/rain/heavy + indoor_sounds_type = /datum/looping_sound/weather/rain/heavy/indoors transition_chances = list( diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index 77a81defaf0..cfc8a9de5a9 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -510,6 +510,7 @@ obj/structure/cable/proc/cableColor(var/colorC) stacktype = /obj/item/stack/cable_coil drop_sound = 'sound/items/drop/accessory.ogg' pickup_sound = 'sound/items/pickup/accessory.ogg' + tool_qualities = list(TOOL_CABLE_COIL) /obj/item/stack/cable_coil/cyborg name = "cable coil synthesizer" diff --git a/code/modules/power/fusion/fuel_assembly/fuel_compressor.dm b/code/modules/power/fusion/fuel_assembly/fuel_compressor.dm index 91c08513a58..89b11da6c10 100644 --- a/code/modules/power/fusion/fuel_assembly/fuel_compressor.dm +++ b/code/modules/power/fusion/fuel_assembly/fuel_compressor.dm @@ -1,3 +1,4 @@ +#define FUSION_ROD_SHEET_AMT 15 /obj/machinery/fusion_fuel_compressor name = "fuel compressor" icon = 'icons/obj/machines/power/fusion.dmi' @@ -53,15 +54,17 @@ if(!mat.is_fusion_fuel) to_chat(user, "It would be pointless to make a fuel rod out of [mat.use_name].") return - if(M.get_amount() < 15) + if(M.get_amount() < FUSION_ROD_SHEET_AMT) to_chat(user, "You need at least 25 [mat.sheet_plural_name] to make a fuel rod.") return var/obj/item/weapon/fuel_assembly/F = new(get_turf(src), mat.name) visible_message("\The [src] compresses the [mat.use_name] into a new fuel assembly.") - M.use(15) + M.use(FUSION_ROD_SHEET_AMT) user.put_in_hands(F) else if(do_special_fuel_compression(thing, user)) return - return ..() \ No newline at end of file + return ..() + +#undef FUSION_ROD_SHEET_AMT \ No newline at end of file diff --git a/code/modules/power/fusion/fusion_reagents.dm b/code/modules/power/fusion/fusion_reagents.dm deleted file mode 100644 index 80b1cbb3361..00000000000 --- a/code/modules/power/fusion/fusion_reagents.dm +++ /dev/null @@ -1,18 +0,0 @@ -//Additional fusion reagents. These likely don't have any other use aside from the RUST, but if you want to make stuff with 'em, be my guest. - -/datum/reagent/helium3 - name = "helium-3" - description = "A colorless, odorless, tasteless and generally inert gas used in fusion reactors. Non-radioactive." - id = "helium-3" - reagent_state = GAS - color = "#808080" - -/obj/structure/reagent_dispensers/he3 - name = "fueltank" - desc = "A fueltank." - icon = 'icons/obj/objects.dmi' - icon_state = "weldtank" - amount_per_transfer_from_this = 10 - New() - ..() - reagents.add_reagent("helium-3",1000) \ No newline at end of file diff --git a/code/modules/power/gravitygenerator_vr.dm b/code/modules/power/gravitygenerator_vr.dm index 3e4767a9a9b..cce22b705af 100644 --- a/code/modules/power/gravitygenerator_vr.dm +++ b/code/modules/power/gravitygenerator_vr.dm @@ -210,7 +210,7 @@ GLOBAL_LIST_EMPTY(gravity_generators) update_icon() return if(GRAV_NEEDS_WELDING) - if(I.is_welder()) + if(I.has_tool_quality(TOOL_WELDER)) var/obj/item/weapon/weldingtool/W = I if(W.remove_fuel(0,user)) to_chat(user, "You mend the damaged framework.") diff --git a/code/modules/projectiles/broken.dm b/code/modules/projectiles/broken.dm index f972d1f6bdb..f46f7f34e50 100644 --- a/code/modules/projectiles/broken.dm +++ b/code/modules/projectiles/broken.dm @@ -80,7 +80,7 @@ material_needs[component_needed] = rand(1,3) if(ispath(my_guntype, /obj/item/weapon/gun/launcher) && prob(50)) - var/component_needed = pick(/obj/item/weapon/tape_roll, /obj/item/weapon/material/wirerod) + var/component_needed = pick(/obj/item/weapon/tape_roll, /obj/item/stack/rods, /obj/item/weapon/handcuffs/cable) material_needs[component_needed] = 1 if(ispath(my_guntype, /obj/item/weapon/gun/magnetic) && prob(70)) diff --git a/code/modules/projectiles/guns/energy/laser_vr.dm b/code/modules/projectiles/guns/energy/laser_vr.dm index fe29c85f0ee..4256cb50d45 100644 --- a/code/modules/projectiles/guns/energy/laser_vr.dm +++ b/code/modules/projectiles/guns/energy/laser_vr.dm @@ -189,12 +189,14 @@ return 0 return ..() -//Expedition Frontier Phaser +////////////////Expedition Frontier Phaser//////////////// + /obj/item/weapon/gun/energy/locked/frontier name = "frontier phaser" desc = "An extraordinarily rugged laser weapon, built to last and requiring effectively no maintenance. Includes a built-in crank charger for recharging away from civilization. This one has a safety interlock that prevents firing while in proximity to the facility." + description_fluff = "The NT Brand Model E2 Secured Phaser System, a specialty phaser that has an intergrated chip that prevents the user from opperating the weapon within the vicinity of any NanoTrasen opperated outposts/stations/bases. However, this chip can be disabled so the weapon CAN BE used in the vicinity of any NanoTrasen opperated outposts/stations/bases. The weapon doesn't use traditional weapon power cells and instead works via a pump action that recharges the internal cells. It is a staple amongst exploration personell who usually don't have the license to opperate a lethal weapon through NT and provides them with a weapon that can be recharged away from civilization." icon = 'icons/obj/gun_vr.dmi' - icon_state = "phaser" + icon_state = "phaserkill" item_state = "phaser" item_icons = list(slot_l_hand_str = 'icons/mob/items/lefthand_guns_vr.dmi', slot_r_hand_str = 'icons/mob/items/righthand_guns_vr.dmi', "slot_belt" = 'icons/mob/belt_vr.dmi') fire_sound = 'sound/weapons/laser2.ogg' @@ -208,9 +210,11 @@ var/phase_power = 75 projectile_type = /obj/item/projectile/beam/blue + + modifystate = "phaserkill" firemodes = list( - list(mode_name="lethal", fire_delay=12, projectile_type=/obj/item/projectile/beam/blue, charge_cost = 300), - list(mode_name="low-power", fire_delay=8, projectile_type=/obj/item/projectile/beam/weaklaser/blue, charge_cost = 80), + list(mode_name="lethal", fire_delay=12, projectile_type=/obj/item/projectile/beam/blue, modifystate="phaserkill", charge_cost = 300), + list(mode_name="low-power", fire_delay=8, projectile_type=/obj/item/projectile/beam/weaklaser/blue, modifystate="phaserstun", charge_cost = 80), ) /obj/item/weapon/gun/energy/locked/frontier/unload_ammo(var/mob/user) @@ -249,19 +253,22 @@ locked = 0 lockable = 0 -//Phaser Carbine - Reskinned phaser +////////////////Phaser Carbine//////////////// + /obj/item/weapon/gun/energy/locked/frontier/carbine name = "frontier carbine" desc = "An ergonomically improved version of the venerable frontier phaser, the carbine is a fairly new weapon, and has only been produced in limited numbers so far. Includes a built-in crank charger for recharging away from civilization. This one has a safety interlock that prevents firing while in proximity to the facility." + description_fluff = "The NT Brand Model AT2 Secured Phaser System, a specialty phaser that has an intergrated chip that prevents the user from opperating the weapon within the vicinity of any NanoTrasen opperated outposts/stations/bases. However, this chip can be disabled so the weapon CAN BE used in the vicinity of any NanoTrasen opperated outposts/stations/bases. The weapon doesn't use traditional weapon power cells and instead works via a pump action that recharges the internal cells. It is a staple amongst exploration personell who usually don't have the license to opperate a lethal weapon through NT and provides them with a weapon that can be recharged away from civilization." icon = 'icons/obj/gun_vr.dmi' icon_state = "carbinekill" - item_state = "retro" + item_state = "energykill" item_icons = list(slot_l_hand_str = 'icons/mob/items/lefthand_guns.dmi', slot_r_hand_str = 'icons/mob/items/righthand_guns.dmi') + phase_power = 150 modifystate = "carbinekill" firemodes = list( - list(mode_name="lethal", fire_delay=12, projectile_type=/obj/item/projectile/beam/blue, modifystate="carbinekill", charge_cost = 300), - list(mode_name="low-power", fire_delay=8, projectile_type=/obj/item/projectile/beam/weaklaser/blue, modifystate="carbinestun", charge_cost = 80), + list(mode_name="lethal", fire_delay=8, projectile_type=/obj/item/projectile/beam/blue, modifystate="carbinekill", charge_cost = 300), + list(mode_name="low-power", fire_delay=5, projectile_type=/obj/item/projectile/beam/weaklaser/blue, modifystate="carbinestun", charge_cost = 80), ) /obj/item/weapon/gun/energy/locked/frontier/carbine/update_icon() @@ -272,12 +279,13 @@ ..() /obj/item/weapon/gun/energy/locked/frontier/carbine/unlocked - desc = "An ergonomically improved version of the venerable frontier phaser, the carbine is a fairly new weapon, and has only been produced in limited numbers so far." + desc = "An ergonomically improved version of the venerable frontier phaser, the carbine is a fairly new weapon, and has only been produced in limited numbers so far. Includes a built-in crank charger for recharging away from civilization." req_access = newlist() //for toggling safety locked = 0 lockable = 0 -//Expeditionary Holdout Phaser Pistol +////////////////Expeditionary Holdout Phaser Pistol//////////////// + /obj/item/weapon/gun/energy/locked/frontier/holdout name = "holdout frontier phaser" desc = "An minaturized weapon designed for the purpose of expeditionary support to defend themselves on the field. Includes a built-in crank charger for recharging away from civilization. This one has a safety interlock that prevents firing while in proximity to the facility." @@ -300,3 +308,51 @@ req_access = newlist() //for toggling safety locked = 0 lockable = 0 + +////////////////Phaser Rifle//////////////// + +/obj/item/weapon/gun/energy/locked/frontier/rifle + name = "frontier marksman rifle" + desc = "A much larger, heavier weapon than the typical frontier-type weapons, this DMR can be fired both from the hip, and in scope. Includes a built-in crank charger for recharging away from civilization. This one has a safety interlock that prevents firing while in proximity to the facility." + icon = 'icons/obj/gun_vr.dmi' + icon_state = "riflekill" + item_state = "sniper" + item_state_slots = list(slot_r_hand_str = "lsniper", slot_l_hand_str = "lsniper") + wielded_item_state = "lsniper-wielded" + action_button_name = "Use Scope" + w_class = ITEMSIZE_LARGE + item_icons = list(slot_l_hand_str = 'icons/mob/items/lefthand_guns.dmi', slot_r_hand_str = 'icons/mob/items/righthand_guns.dmi') + accuracy = -15 //better than most snipers but still has penalty + scoped_accuracy = 40 + one_handed_penalty = 50 // The weapon itself is heavy, and the long barrel makes it hard to hold steady with just one hand. + phase_power = 150 //efficient crank charger + + projectile_type = /obj/item/projectile/beam/sniper + modifystate = "riflekill" + firemodes = list( + list(mode_name="sniper", fire_delay=35, projectile_type=/obj/item/projectile/beam/sniper, modifystate="riflekill", charge_cost = 600), + list(mode_name="lethal", fire_delay=12, projectile_type=/obj/item/projectile/beam, modifystate="riflestun", charge_cost = 200), + ) + +/obj/item/weapon/gun/energy/locked/frontier/rifle/ui_action_click() + scope() + +/obj/item/weapon/gun/energy/locked/frontier/rifle/verb/scope() + set category = "Object" + set name = "Use Scope" + set popup_menu = 1 + + toggle_scope(2.0) + +/obj/item/weapon/gun/energy/locked/frontier/rifle/update_icon() + if(recharging) + icon_state = "[modifystate]_pump" + update_held_icon() + return + ..() + +/obj/item/weapon/gun/energy/locked/frontier/rifle/unlocked + desc = "A much larger, heavier weapon than the typical frontier-type weapons, this DMR can be fired both from the hip, and in scope. Includes a built-in crank charger for recharging away from civilization." + req_access = newlist() //for toggling safety + locked = 0 + lockable = 0 diff --git a/code/modules/projectiles/guns/energy/stun_vr.dm b/code/modules/projectiles/guns/energy/stun_vr.dm index b0bfd53e463..db038e58fde 100644 --- a/code/modules/projectiles/guns/energy/stun_vr.dm +++ b/code/modules/projectiles/guns/energy/stun_vr.dm @@ -3,4 +3,5 @@ fire_delay = 4 /obj/item/weapon/gun/energy/stunrevolver + icon = 'icons/obj/gun_vr.dmi' charge_cost = 400 \ No newline at end of file diff --git a/code/modules/projectiles/guns/modular_guns.dm b/code/modules/projectiles/guns/modular_guns.dm index 4eb990c0cae..f384c7975d0 100644 --- a/code/modules/projectiles/guns/modular_guns.dm +++ b/code/modules/projectiles/guns/modular_guns.dm @@ -37,7 +37,8 @@ CheckParts() FireModeModify() -/obj/item/weapon/gun/energy/modular/proc/CheckParts() //What parts do we have inside us, and how good are they? +/obj/item/weapon/gun/energy/modular/CheckParts() //What parts do we have inside us, and how good are they? + ..() capacitor_rating = 0 laser_rating = 0 manipulator_rating = 0 diff --git a/code/modules/projectiles/guns/projectile/automatic.dm b/code/modules/projectiles/guns/projectile/automatic.dm index 626dfe56843..e9fce291a34 100644 --- a/code/modules/projectiles/guns/projectile/automatic.dm +++ b/code/modules/projectiles/guns/projectile/automatic.dm @@ -389,9 +389,18 @@ ) /obj/item/weapon/gun/projectile/automatic/tommygun/update_icon() - ..() - icon_state = (ammo_magazine)? "tommygun" : "tommygun-empty" -// update_held_icon() + //VOREStation Edit Start - vr sprite + if(istype(ammo_magazine,/obj/item/ammo_magazine/m45tommy)) + icon_state = "tommygun-mag" + item_state = icon_state + else if(istype(ammo_magazine,/obj/item/ammo_magazine/m45tommydrum)) + icon_state = "tommygun-drum" + item_state = icon_state + else + icon_state = "tommygun-empty" + item_state = icon_state + update_held_icon() + //VOREStation Edit End /obj/item/weapon/gun/projectile/automatic/bullpup // Admin abuse assault rifle. ToDo: Make this less shit. Maybe remove its autofire, and make it spawn with only 10 rounds at start. name = "bullpup rifle" diff --git a/code/modules/projectiles/guns/projectile/automatic_vr.dm b/code/modules/projectiles/guns/projectile/automatic_vr.dm index 5d4cd08eafc..148045b562e 100644 --- a/code/modules/projectiles/guns/projectile/automatic_vr.dm +++ b/code/modules/projectiles/guns/projectile/automatic_vr.dm @@ -1,6 +1,9 @@ /obj/item/weapon/gun/projectile/automatic/wt550/lethal magazine_type = /obj/item/ammo_magazine/m9mmt +/obj/item/weapon/gun/projectile/automatic/tommygun + icon = 'icons/obj/gun_vr.dmi' + //////////////////////////////////////////////////////////// //////////////////// Projectile Weapons //////////////////// //////////////////////////////////////////////////////////// diff --git a/code/modules/projectiles/guns/projectile/boltaction.dm b/code/modules/projectiles/guns/projectile/boltaction.dm index 1aa8e839575..52e8c17ca96 100644 --- a/code/modules/projectiles/guns/projectile/boltaction.dm +++ b/code/modules/projectiles/guns/projectile/boltaction.dm @@ -16,7 +16,7 @@ action_sound = 'sound/weapons/riflebolt.ogg' pump_animation = null -/obj/item/weapon/gun/projectile/shotgun/pump/rifle/practice // For target practice +/obj/item/weapon/gun/projectile/shotgun/pump/rifle/practice //For target practice desc = "A bolt-action rifle with a lightweight synthetic wood stock, designed for competitive shooting. Comes shipped with practice rounds pre-loaded into the gun. Popular among professional marksmen. Uses 7.62mm rounds." ammo_type = /obj/item/ammo_casing/a762/practice diff --git a/code/modules/projectiles/guns/projectile/boltaction_vr.dm b/code/modules/projectiles/guns/projectile/boltaction_vr.dm new file mode 100644 index 00000000000..3e538adf4ee --- /dev/null +++ b/code/modules/projectiles/guns/projectile/boltaction_vr.dm @@ -0,0 +1,55 @@ +/obj/item/weapon/gun/projectile/shotgun/pump/rifle + desc = "The Weissen Company Type-19 is a modern interpretation of an almost ancient weapon design. The model is popular among hunters and collectors due to its reliability. Uses 7.62mm rounds." + description_fluff = "The frontier’s largest home-grown firearms manufacturer, the APEX Arms Company offers a range of high-quality, high-cost hunting rifles and shotguns designed with the wild frontier wilderness - and its wildlife - in mind. \ + The company operates just one production plant in the Mytis system, but their weapons have found popularity on garden worlds as far afield as the Tajaran homeworld due to their excellent build quality, precision, and stopping power." + icon = 'icons/obj/gun_vr.dmi' + +/obj/item/weapon/gun/projectile/shotgun/pump/rifle/practice //For target practice + name = "practice rifle" + icon = 'icons/obj/gun_vr.dmi' + icon_state = "boltaction_p" + item_state = "boltaction_p" + item_icons = list(slot_l_hand_str = 'icons/mob/items/lefthand_guns_vr.dmi', slot_r_hand_str = 'icons/mob/items/righthand_guns_vr.dmi') + max_shells = 4 + +/obj/item/weapon/gun/projectile/shotgun/pump/rifle/ceremonial + max_shells = 5 + +/obj/item/weapon/gun/projectile/shotgun/pump/rifle/lever + desc = "The Weissen Company Thunderking is the latest version of an almost ancient weapon design from the 19th century, popular with some due to its simplistic design. This one uses a lever-action to move new rounds into the chamber. Uses 7.62mm rounds." + description_fluff = "The frontier’s largest home-grown firearms manufacturer, the Weissen Company offers a range of high-quality, high-cost hunting rifles and shotguns designed with the wild frontier wilderness - and its wildlife - in mind. \ + The company operates just one production plant in the Mytis system, but their weapons have found popularity on garden worlds as far afield as the Tajaran homeworld due to their excellent build quality, precision, and stopping power." + icon = 'icons/obj/gun_vr.dmi' + icon_state = "levergun" + max_shells = 6 + +/obj/item/weapon/gun/projectile/shotgun/pump/rifle/lever/vintage + desc = "The Weissen Company's version of an iconic manually operated lever action rifle, the Bushhog, offering adequate stopping power due to it's still powerful cartridge while at the same time having a rather respectable firing rate due to it's mechanism. It is very probable this is a replica instead of a museum piece, but rifles of this pattern still see usage as colonist guns in some far off regions. Uses 7.62mm rounds." + description_fluff = "The frontier’s largest home-grown firearms manufacturer, the Weissen Company offers a range of high-quality, high-cost hunting rifles and shotguns designed with the wild frontier wilderness - and its wildlife - in mind. \ + The company operates just one production plant in the Mytis system, but their weapons have found popularity on garden worlds as far afield as the Tajaran homeworld due to their excellent build quality, precision, and stopping power." + icon = 'icons/obj/gun_vr.dmi' + icon_state = "levergunv" + item_state = "leveraction" + max_shells = 5 + caliber = "7.62mm" + load_method = SINGLE_CASING + pump_animation = null + +////////////////////////surplus gun - for derelicts (04/26/2021)//////////////////////// + +/obj/item/weapon/gun/projectile/shotgun/pump/surplus + name = "surplus rifle" + desc = "An ancient weapon from an era long pas, crude in design, but still just as effective as any modern interpretation. Uses 7.62mm rounds." + icon = 'icons/obj/gun_vr.dmi' + icon_state = "boltaction_s" + item_state = "boltaction_p" + item_icons = list(slot_l_hand_str = 'icons/mob/items/lefthand_guns_vr.dmi', slot_r_hand_str = 'icons/mob/items/righthand_guns_vr.dmi') + fire_sound = 'sound/weapons/Gunshot_generic_rifle.ogg' + max_shells = 4 + slot_flags = null + caliber = "7.62mm" + origin_tech = list(TECH_COMBAT = 1) // Old(er) as shit rifle doesn't have very good tech. + ammo_type = /obj/item/ammo_casing/a762 + load_method = SINGLE_CASING|SPEEDLOADER + action_sound = 'sound/weapons/riflebolt.ogg' + pump_animation = null diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm index 12f2cf09e60..734d14c63ad 100644 --- a/code/modules/projectiles/projectile/beams.dm +++ b/code/modules/projectiles/projectile/beams.dm @@ -27,6 +27,7 @@ name = "laser" icon_state = "laser" damage = 0 + excavation_amount = 0 damage_type = BURN check_armour = "laser" eyeblur = 2 @@ -43,7 +44,7 @@ damage = 30 armor_penetration = 10 - + /obj/item/projectile/beam/midlaser damage = 40 armor_penetration = 10 @@ -159,6 +160,7 @@ name = "lasertag beam" damage = 0 eyeblur = 0 + excavation_amount = 0 no_attack_log = 1 damage_type = BURN check_armour = "laser" diff --git a/code/modules/projectiles/projectile/beams_vr.dm b/code/modules/projectiles/projectile/beams_vr.dm index f4aa2522de5..a3a149502cd 100644 --- a/code/modules/projectiles/projectile/beams_vr.dm +++ b/code/modules/projectiles/projectile/beams_vr.dm @@ -43,6 +43,9 @@ impact_type = /obj/effect/projectile/impact/laser_blue /obj/item/projectile/beam/weaklaser/blue + icon_state = "bluelaser" + light_color = "#0066FF" + muzzle_type = /obj/effect/projectile/muzzle/laser_blue tracer_type = /obj/effect/projectile/tracer/laser_blue impact_type = /obj/effect/projectile/impact/laser_blue @@ -79,4 +82,4 @@ M.adjustFireLoss(-15) M.adjustToxLoss(-5) M.adjustOxyLoss(-5) - return 1 \ No newline at end of file + return 1 diff --git a/code/modules/reagents/Chemistry-Logging.dm b/code/modules/reagents/Chemistry-Logging.dm index cccf37bb6fd..4c7b2343ad8 100644 --- a/code/modules/reagents/Chemistry-Logging.dm +++ b/code/modules/reagents/Chemistry-Logging.dm @@ -1,7 +1,7 @@ /var/list/chemical_reaction_logs = list() -/proc/log_chemical_reaction(atom/A, datum/chemical_reaction/R, multiplier) +/proc/log_chemical_reaction(atom/A, decl/chemical_reaction/R, multiplier) if(!A || !R) return diff --git a/code/modules/reagents/Chemistry-Recipes.dm b/code/modules/reagents/Chemistry-Recipes.dm deleted file mode 100644 index a49751fa956..00000000000 --- a/code/modules/reagents/Chemistry-Recipes.dm +++ /dev/null @@ -1,2684 +0,0 @@ -//helper that ensures the reaction rate holds after iterating -//Ex. REACTION_RATE(0.3) means that 30% of the reagents will react each chemistry tick (~2 seconds by default). -#define REACTION_RATE(rate) (1.0 - (1.0-rate)**(1.0/PROCESS_REACTION_ITER)) - -//helper to define reaction rate in terms of half-life -//Ex. -//HALF_LIFE(0) -> Reaction completes immediately (default chems) -//HALF_LIFE(1) -> Half of the reagents react immediately, the rest over the following ticks. -//HALF_LIFE(2) -> Half of the reagents are consumed after 2 chemistry ticks. -//HALF_LIFE(3) -> Half of the reagents are consumed after 3 chemistry ticks. -#define HALF_LIFE(ticks) (ticks? 1.0 - (0.5)**(1.0/(ticks*PROCESS_REACTION_ITER)) : 1.0) - -/datum/chemical_reaction - var/name = null - var/id = null - var/result = null - var/list/required_reagents = list() - var/list/catalysts = list() - var/list/inhibitors = list() - var/result_amount = 0 - - //how far the reaction proceeds each time it is processed. Used with either REACTION_RATE or HALF_LIFE macros. - var/reaction_rate = HALF_LIFE(0) - - //if less than 1, the reaction will be inhibited if the ratio of products/reagents is too high. - //0.5 = 50% yield -> reaction will only proceed halfway until products are removed. - var/yield = 1.0 - - //If limits on reaction rate would leave less than this amount of any reagent (adjusted by the reaction ratios), - //the reaction goes to completion. This is to prevent reactions from going on forever with tiny reagent amounts. - var/min_reaction = 2 - - var/mix_message = "The solution begins to bubble." - var/reaction_sound = 'sound/effects/bubbles.ogg' - - var/log_is_important = 0 // If this reaction should be considered important for logging. Important recipes message admins when mixed, non-important ones just log to file. - -/datum/chemical_reaction/proc/can_happen(var/datum/reagents/holder) - //check that all the required reagents are present - if(!holder.has_all_reagents(required_reagents)) - return 0 - - //check that all the required catalysts are present in the required amount - if(!holder.has_all_reagents(catalysts)) - return 0 - - //check that none of the inhibitors are present in the required amount - if(holder.has_any_reagent(inhibitors)) - return 0 - - return 1 - -/datum/chemical_reaction/proc/calc_reaction_progress(var/datum/reagents/holder, var/reaction_limit) - var/progress = reaction_limit * reaction_rate //simple exponential progression - - //calculate yield - if(1-yield > 0.001) //if yield ratio is big enough just assume it goes to completion - /* - Determine the max amount of product by applying the yield condition: - (max_product/result_amount) / reaction_limit == yield/(1-yield) - - We make use of the fact that: - reaction_limit = (holder.get_reagent_amount(reactant) / required_reagents[reactant]) of the limiting reagent. - */ - var/yield_ratio = yield/(1-yield) - var/max_product = yield_ratio * reaction_limit * result_amount //rearrange to obtain max_product - var/yield_limit = max(0, max_product - holder.get_reagent_amount(result))/result_amount - - progress = min(progress, yield_limit) //apply yield limit - - //apply min reaction progress - wasn't sure if this should go before or after applying yield - //I guess people can just have their miniscule reactions go to completion regardless of yield. - for(var/reactant in required_reagents) - var/remainder = holder.get_reagent_amount(reactant) - progress*required_reagents[reactant] - if(remainder <= min_reaction*required_reagents[reactant]) - progress = reaction_limit - break - - return progress - -/datum/chemical_reaction/process(var/datum/reagents/holder) - //determine how far the reaction can proceed - var/list/reaction_limits = list() - for(var/reactant in required_reagents) - reaction_limits += holder.get_reagent_amount(reactant) / required_reagents[reactant] - - //determine how far the reaction proceeds - var/reaction_limit = min(reaction_limits) - var/progress_limit = calc_reaction_progress(holder, reaction_limit) - - var/reaction_progress = min(reaction_limit, progress_limit) //no matter what, the reaction progress cannot exceed the stoichiometric limit. - - //need to obtain the new reagent's data before anything is altered - var/data = send_data(holder, reaction_progress) - - //remove the reactants - for(var/reactant in required_reagents) - var/amt_used = required_reagents[reactant] * reaction_progress - holder.remove_reagent(reactant, amt_used, safety = 1) - - //add the product - var/amt_produced = result_amount * reaction_progress - if(result) - holder.add_reagent(result, amt_produced, data, safety = 1) - - on_reaction(holder, amt_produced) - - return reaction_progress - -//called when a reaction processes -/datum/chemical_reaction/proc/on_reaction(var/datum/reagents/holder, var/created_volume) - return - -//called after processing reactions, if they occurred -/datum/chemical_reaction/proc/post_reaction(var/datum/reagents/holder) - var/atom/container = holder.my_atom - if(mix_message && container && !ismob(container)) - var/turf/T = get_turf(container) - var/list/seen = viewers(4, T) - for(var/mob/M in seen) - M.show_message("[bicon(container)] [mix_message]", 1) - playsound(T, reaction_sound, 80, 1) - -//obtains any special data that will be provided to the reaction products -//this is called just before reactants are removed. -/datum/chemical_reaction/proc/send_data(var/datum/reagents/holder, var/reaction_limit) - return null - -/* Common reactions */ - -/datum/chemical_reaction/inaprovaline - name = "Inaprovaline" - id = "inaprovaline" - result = "inaprovaline" - required_reagents = list("oxygen" = 1, "carbon" = 1, "sugar" = 1) - result_amount = 3 - -/datum/chemical_reaction/dylovene - name = "Dylovene" - id = "anti_toxin" - result = "anti_toxin" - required_reagents = list("silicon" = 1, "potassium" = 1, "nitrogen" = 1) - result_amount = 3 - -/datum/chemical_reaction/carthatoline - name = "Carthatoline" - id = "carthatoline" - result = "carthatoline" - required_reagents = list("anti_toxin" = 1, "carbon" = 2, "phoron" = 0.1) - catalysts = list("phoron" = 1) - result_amount = 2 - -/datum/chemical_reaction/paracetamol - name = "Paracetamol" - id = "paracetamol" - result = "paracetamol" - required_reagents = list("inaprovaline" = 1, "nitrogen" = 1, "water" = 1) - result_amount = 2 - -/datum/chemical_reaction/tramadol - name = "Tramadol" - id = "tramadol" - result = "tramadol" - required_reagents = list("paracetamol" = 1, "ethanol" = 1, "oxygen" = 1) - result_amount = 3 - -/datum/chemical_reaction/oxycodone - name = "Oxycodone" - id = "oxycodone" - result = "oxycodone" - required_reagents = list("ethanol" = 1, "tramadol" = 1) - catalysts = list("phoron" = 5) - result_amount = 1 - -/datum/chemical_reaction/sterilizine - name = "Sterilizine" - id = "sterilizine" - result = "sterilizine" - required_reagents = list("ethanol" = 1, "anti_toxin" = 1, "chlorine" = 1) - result_amount = 3 - -/datum/chemical_reaction/silicate - name = "Silicate" - id = "silicate" - result = "silicate" - required_reagents = list("aluminum" = 1, "silicon" = 1, "oxygen" = 1) - result_amount = 3 - -/datum/chemical_reaction/mutagen - name = "Unstable mutagen" - id = "mutagen" - result = "mutagen" - required_reagents = list("radium" = 1, "phosphorus" = 1, "chlorine" = 1) - result_amount = 3 - -/datum/chemical_reaction/water - name = "Water" - id = "water" - result = "water" - required_reagents = list("oxygen" = 1, "hydrogen" = 2) - result_amount = 1 - -/datum/chemical_reaction/thermite - name = "Thermite" - id = "thermite" - result = "thermite" - required_reagents = list("aluminum" = 1, "iron" = 1, "oxygen" = 1) - result_amount = 3 - -/datum/chemical_reaction/space_drugs - name = "Space Drugs" - id = "space_drugs" - result = "space_drugs" - required_reagents = list("mercury" = 1, "sugar" = 1, "lithium" = 1) - result_amount = 3 - -/datum/chemical_reaction/lube - name = "Space Lube" - id = "lube" - result = "lube" - required_reagents = list("water" = 1, "silicon" = 1, "oxygen" = 1) - result_amount = 4 - -/datum/chemical_reaction/pacid - name = "Polytrinic acid" - id = "pacid" - result = "pacid" - required_reagents = list("sacid" = 1, "chlorine" = 1, "potassium" = 1) - result_amount = 3 - -/datum/chemical_reaction/synaptizine - name = "Synaptizine" - id = "synaptizine" - result = "synaptizine" - required_reagents = list("sugar" = 1, "lithium" = 1, "water" = 1) - result_amount = 3 - -/datum/chemical_reaction/hyronalin - name = "Hyronalin" - id = "hyronalin" - result = "hyronalin" - required_reagents = list("radium" = 1, "anti_toxin" = 1) - result_amount = 2 - -/datum/chemical_reaction/arithrazine - name = "Arithrazine" - id = "arithrazine" - result = "arithrazine" - required_reagents = list("hyronalin" = 1, "hydrogen" = 1) - result_amount = 2 - -/datum/chemical_reaction/impedrezene - name = "Impedrezene" - id = "impedrezene" - result = "impedrezene" - required_reagents = list("mercury" = 1, "oxygen" = 1, "sugar" = 1) - result_amount = 2 - -/datum/chemical_reaction/kelotane - name = "Kelotane" - id = "kelotane" - result = "kelotane" - required_reagents = list("silicon" = 1, "carbon" = 1) - result_amount = 2 - log_is_important = 1 - -/datum/chemical_reaction/peridaxon - name = "Peridaxon" - id = "peridaxon" - result = "peridaxon" - required_reagents = list("bicaridine" = 2, "clonexadone" = 2) - catalysts = list("phoron" = 5) - result_amount = 2 - -/datum/chemical_reaction/osteodaxon - name = "Osteodaxon" - id = "osteodaxon" - result = "osteodaxon" - required_reagents = list("bicaridine" = 2, "phoron" = 0.1, "carpotoxin" = 1) - catalysts = list("phoron" = 5) - inhibitors = list("clonexadone" = 1) // Messes with cryox - result_amount = 2 - -/datum/chemical_reaction/respirodaxon - name = "Respirodaxon" - id = "respirodaxon" - result = "respirodaxon" - required_reagents = list("dexalinp" = 2, "biomass" = 2, "phoron" = 1) - catalysts = list("phoron" = 5) - inhibitors = list("dexalin" = 1) - result_amount = 2 - -/datum/chemical_reaction/gastirodaxon - name = "Gastirodaxon" - id = "gastirodaxon" - result = "gastirodaxon" - required_reagents = list("carthatoline" = 1, "biomass" = 2, "tungsten" = 2) - catalysts = list("phoron" = 5) - inhibitors = list("lithium" = 1) - result_amount = 3 - -/datum/chemical_reaction/hepanephrodaxon - name = "Hepanephrodaxon" - id = "hepanephrodaxon" - result = "hepanephrodaxon" - required_reagents = list("carthatoline" = 2, "biomass" = 2, "lithium" = 1) - catalysts = list("phoron" = 5) - inhibitors = list("tungsten" = 1) - result_amount = 2 - -/datum/chemical_reaction/cordradaxon - name = "Cordradaxon" - id = "cordradaxon" - result = "cordradaxon" - required_reagents = list("potassium_chlorophoride" = 1, "biomass" = 2, "bicaridine" = 2) - catalysts = list("phoron" = 5) - inhibitors = list("clonexadone" = 1) - result_amount = 2 - -/datum/chemical_reaction/virus_food - name = "Virus Food" - id = "virusfood" - result = "virusfood" - required_reagents = list("water" = 1, "milk" = 1) - result_amount = 5 - -/datum/chemical_reaction/leporazine - name = "Leporazine" - id = "leporazine" - result = "leporazine" - required_reagents = list("silicon" = 1, "copper" = 1) - catalysts = list("phoron" = 5) - result_amount = 2 - -/datum/chemical_reaction/cryptobiolin - name = "Cryptobiolin" - id = "cryptobiolin" - result = "cryptobiolin" - required_reagents = list("potassium" = 1, "oxygen" = 1, "sugar" = 1) - result_amount = 3 - -/datum/chemical_reaction/tricordrazine - name = "Tricordrazine" - id = "tricordrazine" - result = "tricordrazine" - required_reagents = list("inaprovaline" = 1, "anti_toxin" = 1) - result_amount = 2 - -/datum/chemical_reaction/alkysine - name = "Alkysine" - id = "alkysine" - result = "alkysine" - required_reagents = list("chlorine" = 1, "nitrogen" = 1, "anti_toxin" = 1) - result_amount = 2 - -/datum/chemical_reaction/dexalin - name = "Dexalin" - id = "dexalin" - result = "dexalin" - required_reagents = list("oxygen" = 2, "phoron" = 0.1) - catalysts = list("phoron" = 1) - inhibitors = list("water" = 1) // Messes with cryox - result_amount = 1 - -/datum/chemical_reaction/dermaline - name = "Dermaline" - id = "dermaline" - result = "dermaline" - required_reagents = list("oxygen" = 1, "phosphorus" = 1, "kelotane" = 1) - result_amount = 3 - -/datum/chemical_reaction/dexalinp - name = "Dexalin Plus" - id = "dexalinp" - result = "dexalinp" - required_reagents = list("dexalin" = 1, "carbon" = 1, "iron" = 1) - result_amount = 3 - -/datum/chemical_reaction/bicaridine - name = "Bicaridine" - id = "bicaridine" - result = "bicaridine" - required_reagents = list("inaprovaline" = 1, "carbon" = 1) - inhibitors = list("sugar" = 1) // Messes up with inaprovaline - result_amount = 2 - -/datum/chemical_reaction/myelamine - name = "Myelamine" - id = "myelamine" - result = "myelamine" - required_reagents = list("bicaridine" = 1, "iron" = 2, "spidertoxin" = 1) - result_amount = 2 - -/datum/chemical_reaction/hyperzine - name = "Hyperzine" - id = "hyperzine" - result = "hyperzine" - required_reagents = list("sugar" = 1, "phosphorus" = 1, "sulfur" = 1) - result_amount = 3 - -/datum/chemical_reaction/stimm - name = "Stimm" - id = "stimm" - result = "stimm" - required_reagents = list("left4zed" = 1, "fuel" = 1) - catalysts = list("fuel" = 5) - result_amount = 2 - -/datum/chemical_reaction/ryetalyn - name = "Ryetalyn" - id = "ryetalyn" - result = "ryetalyn" - required_reagents = list("arithrazine" = 1, "carbon" = 1) - result_amount = 2 - -/datum/chemical_reaction/cryoxadone - name = "Cryoxadone" - id = "cryoxadone" - result = "cryoxadone" - required_reagents = list("dexalin" = 1, "water" = 1, "oxygen" = 1) - result_amount = 3 - -/datum/chemical_reaction/clonexadone - name = "Clonexadone" - id = "clonexadone" - result = "clonexadone" - required_reagents = list("cryoxadone" = 1, "sodium" = 1, "phoron" = 0.1) - catalysts = list("phoron" = 5) - result_amount = 2 - -/datum/chemical_reaction/mortiferin - name = "Mortiferin" - id = "mortiferin" - result = "mortiferin" - required_reagents = list("cryptobiolin" = 1, "clonexadone" = 1, "corophizine" = 1) - result_amount = 2 - catalysts = list("phoron" = 5) - -/datum/chemical_reaction/spaceacillin - name = "Spaceacillin" - id = "spaceacillin" - result = "spaceacillin" - required_reagents = list("cryptobiolin" = 1, "inaprovaline" = 1) - result_amount = 2 - -/datum/chemical_reaction/corophizine - name = "Corophizine" - id = "corophizine" - result = "corophizine" - required_reagents = list("spaceacillin" = 1, "carbon" = 1, "phoron" = 0.1) - catalysts = list("phoron" = 5) - result_amount = 2 - -/datum/chemical_reaction/immunosuprizine - name = "Immunosuprizine" - id = "immunosuprizine" - result = "immunosuprizine" - required_reagents = list("corophizine" = 1, "tungsten" = 1, "sacid" = 1) - catalysts = list("phoron" = 5) - result_amount = 2 - -/datum/chemical_reaction/imidazoline - name = "imidazoline" - id = "imidazoline" - result = "imidazoline" - required_reagents = list("carbon" = 1, "hydrogen" = 1, "anti_toxin" = 1) - result_amount = 2 - -/datum/chemical_reaction/ethylredoxrazine - name = "Ethylredoxrazine" - id = "ethylredoxrazine" - result = "ethylredoxrazine" - required_reagents = list("oxygen" = 1, "anti_toxin" = 1, "carbon" = 1) - result_amount = 3 - -/datum/chemical_reaction/calciumcarbonate - name = "Calcium Carbonate" - id = "calciumcarbonate" - result = "calciumcarbonate" - required_reagents = list("oxygen" = 3, "calcium" = 1, "carbon" = 1) - result_amount = 2 - -/datum/chemical_reaction/soporific - name = "Soporific" - id = "stoxin" - result = "stoxin" - required_reagents = list("chloralhydrate" = 1, "sugar" = 4) - inhibitors = list("phosphorus") // Messes with the smoke - result_amount = 5 - -/datum/chemical_reaction/chloralhydrate - name = "Chloral Hydrate" - id = "chloralhydrate" - result = "chloralhydrate" - required_reagents = list("ethanol" = 1, "chlorine" = 3, "water" = 1) - result_amount = 1 - -/datum/chemical_reaction/potassium_chloride - name = "Potassium Chloride" - id = "potassium_chloride" - result = "potassium_chloride" - required_reagents = list("sodiumchloride" = 1, "potassium" = 1) - result_amount = 2 - -/datum/chemical_reaction/potassium_chlorophoride - name = "Potassium Chlorophoride" - id = "potassium_chlorophoride" - result = "potassium_chlorophoride" - required_reagents = list("potassium_chloride" = 1, "phoron" = 1, "chloralhydrate" = 1) - result_amount = 4 - -/datum/chemical_reaction/zombiepowder - name = "Zombie Powder" - id = "zombiepowder" - result = "zombiepowder" - required_reagents = list("carpotoxin" = 5, "stoxin" = 5, "copper" = 5) - result_amount = 2 - -/datum/chemical_reaction/carpotoxin - name = "Carpotoxin" - id = "carpotoxin" - result = "carpotoxin" - required_reagents = list("spidertoxin" = 2, "biomass" = 1, "sifsap" = 2) - catalysts = list("sifsap" = 10) - inhibitors = list("radium" = 1) - result_amount = 2 - -/datum/chemical_reaction/mindbreaker - name = "Mindbreaker Toxin" - id = "mindbreaker" - result = "mindbreaker" - required_reagents = list("silicon" = 1, "hydrogen" = 1, "anti_toxin" = 1) - result_amount = 3 - -/datum/chemical_reaction/lipozine - name = "Lipozine" - id = "Lipozine" - result = "lipozine" - required_reagents = list("sodiumchloride" = 1, "ethanol" = 1, "radium" = 1) - result_amount = 3 - -/datum/chemical_reaction/surfactant - name = "Foam surfactant" - id = "foam surfactant" - result = "fluorosurfactant" - required_reagents = list("fluorine" = 2, "carbon" = 2, "sacid" = 1) - result_amount = 5 - -/datum/chemical_reaction/ammonia - name = "Ammonia" - id = "ammonia" - result = "ammonia" - required_reagents = list("hydrogen" = 3, "nitrogen" = 1) - inhibitors = list("phoron" = 1) // Messes with lexorin - result_amount = 3 - -/datum/chemical_reaction/diethylamine - name = "Diethylamine" - id = "diethylamine" - result = "diethylamine" - required_reagents = list ("ammonia" = 1, "ethanol" = 1) - result_amount = 2 - -/datum/chemical_reaction/left4zed - name = "Left4Zed" - id = "left4zed" - result = "left4zed" - required_reagents = list ("diethylamine" = 2, "mutagen" = 1) - result_amount = 3 - -/datum/chemical_reaction/robustharvest - name = "RobustHarvest" - id = "robustharvest" - result = "robustharvest" - required_reagents = list ("ammonia" = 1, "calcium" = 1, "neurotoxic_protein" = 1) - result_amount = 3 - -/datum/chemical_reaction/space_cleaner - name = "Space cleaner" - id = "cleaner" - result = "cleaner" - required_reagents = list("ammonia" = 1, "water" = 1) - result_amount = 2 - -/datum/chemical_reaction/plantbgone - name = "Plant-B-Gone" - id = "plantbgone" - result = "plantbgone" - required_reagents = list("toxin" = 1, "water" = 4) - result_amount = 5 - -/datum/chemical_reaction/foaming_agent - name = "Foaming Agent" - id = "foaming_agent" - result = "foaming_agent" - required_reagents = list("lithium" = 1, "hydrogen" = 1) - result_amount = 1 - -/datum/chemical_reaction/glycerol - name = "Glycerol" - id = "glycerol" - result = "glycerol" - required_reagents = list("cornoil" = 3, "sacid" = 1) - result_amount = 1 - -/datum/chemical_reaction/sodiumchloride - name = "Sodium Chloride" - id = "sodiumchloride" - result = "sodiumchloride" - required_reagents = list("sodium" = 1, "chlorine" = 1) - result_amount = 2 - -/datum/chemical_reaction/condensedcapsaicin - name = "Condensed Capsaicin" - id = "condensedcapsaicin" - result = "condensedcapsaicin" - required_reagents = list("capsaicin" = 2) - catalysts = list("phoron" = 5) - result_amount = 1 - -/datum/chemical_reaction/coolant - name = "Coolant" - id = "coolant" - result = "coolant" - required_reagents = list("tungsten" = 1, "oxygen" = 1, "water" = 1) - result_amount = 3 - log_is_important = 1 - -/datum/chemical_reaction/rezadone - name = "Rezadone" - id = "rezadone" - result = "rezadone" - required_reagents = list("carpotoxin" = 1, "cryptobiolin" = 1, "copper" = 1) - result_amount = 3 - -/datum/chemical_reaction/lexorin - name = "Lexorin" - id = "lexorin" - result = "lexorin" - required_reagents = list("phoron" = 1, "hydrogen" = 1, "nitrogen" = 1) - result_amount = 3 - -/datum/chemical_reaction/methylphenidate - name = "Methylphenidate" - id = "methylphenidate" - result = "methylphenidate" - required_reagents = list("mindbreaker" = 1, "hydrogen" = 1) - result_amount = 3 - -/datum/chemical_reaction/citalopram - name = "Citalopram" - id = "citalopram" - result = "citalopram" - required_reagents = list("mindbreaker" = 1, "carbon" = 1) - result_amount = 3 - -/datum/chemical_reaction/paroxetine - name = "Paroxetine" - id = "paroxetine" - result = "paroxetine" - required_reagents = list("mindbreaker" = 1, "oxygen" = 1, "inaprovaline" = 1) - result_amount = 3 - -/datum/chemical_reaction/neurotoxin - name = "Neurotoxin" - id = "neurotoxin" - result = "neurotoxin" - required_reagents = list("gargleblaster" = 1, "stoxin" = 1) - result_amount = 2 - -/datum/chemical_reaction/luminol - name = "Luminol" - id = "luminol" - result = "luminol" - required_reagents = list("hydrogen" = 2, "carbon" = 2, "ammonia" = 2) - result_amount = 6 - -/* Solidification */ - -/datum/chemical_reaction/solidification - name = "Solid Iron" - id = "solidiron" - result = null - required_reagents = list("frostoil" = 5, "iron" = REAGENTS_PER_SHEET) - result_amount = 1 - var/sheet_to_give = /obj/item/stack/material/iron - -/datum/chemical_reaction/solidification/on_reaction(var/datum/reagents/holder, var/created_volume) - new sheet_to_give(get_turf(holder.my_atom), created_volume) - return - - -/datum/chemical_reaction/solidification/phoron - name = "Solid Phoron" - id = "solidphoron" - required_reagents = list("frostoil" = 5, "phoron" = REAGENTS_PER_SHEET) - sheet_to_give = /obj/item/stack/material/phoron - - -/datum/chemical_reaction/solidification/silver - name = "Solid Silver" - id = "solidsilver" - required_reagents = list("frostoil" = 5, "silver" = REAGENTS_PER_SHEET) - sheet_to_give = /obj/item/stack/material/silver - - -/datum/chemical_reaction/solidification/gold - name = "Solid Gold" - id = "solidgold" - required_reagents = list("frostoil" = 5, "gold" = REAGENTS_PER_SHEET) - sheet_to_give = /obj/item/stack/material/gold - - -/datum/chemical_reaction/solidification/platinum - name = "Solid Platinum" - id = "solidplatinum" - required_reagents = list("frostoil" = 5, "platinum" = REAGENTS_PER_SHEET) - sheet_to_give = /obj/item/stack/material/platinum - - -/datum/chemical_reaction/solidification/uranium - name = "Solid Uranium" - id = "soliduranium" - required_reagents = list("frostoil" = 5, "uranium" = REAGENTS_PER_SHEET) - sheet_to_give = /obj/item/stack/material/uranium - - -/datum/chemical_reaction/solidification/hydrogen - name = "Solid Hydrogen" - id = "solidhydrogen" - required_reagents = list("frostoil" = 100, "hydrogen" = REAGENTS_PER_SHEET) - sheet_to_give = /obj/item/stack/material/mhydrogen - - -// These are from Xenobio. -/datum/chemical_reaction/solidification/steel - name = "Solid Steel" - id = "solidsteel" - required_reagents = list("frostoil" = 5, "steel" = REAGENTS_PER_SHEET) - sheet_to_give = /obj/item/stack/material/steel - - -/datum/chemical_reaction/solidification/plasteel - name = "Solid Plasteel" - id = "solidplasteel" - required_reagents = list("frostoil" = 10, "plasteel" = REAGENTS_PER_SHEET) - sheet_to_give = /obj/item/stack/material/plasteel - - -/datum/chemical_reaction/plastication - name = "Plastic" - id = "solidplastic" - result = null - required_reagents = list("pacid" = 1, "plasticide" = 2) - result_amount = 1 - -/datum/chemical_reaction/plastication/on_reaction(var/datum/reagents/holder, var/created_volume) - new /obj/item/stack/material/plastic(get_turf(holder.my_atom), created_volume) - return - -/* Grenade reactions */ - -/datum/chemical_reaction/explosion_potassium - name = "Explosion" - id = "explosion_potassium" - result = null - required_reagents = list("water" = 1, "potassium" = 1) - result_amount = 2 - mix_message = null - -/datum/chemical_reaction/explosion_potassium/on_reaction(var/datum/reagents/holder, var/created_volume) - var/datum/effect/effect/system/reagents_explosion/e = new() - e.set_up(round (created_volume/10, 1), holder.my_atom, 0, 0) - if(isliving(holder.my_atom)) - e.amount *= 0.5 - var/mob/living/L = holder.my_atom - if(L.stat != DEAD) - e.amount *= 0.5 - //VOREStation Add Start - else - holder.clear_reagents() //No more powergaming by creating a tiny amount of this - //VORESTation Add End - e.start() - //holder.clear_reagents() //VOREStation Removal - return - -/datum/chemical_reaction/flash_powder - name = "Flash powder" - id = "flash_powder" - result = null - required_reagents = list("aluminum" = 1, "potassium" = 1, "sulfur" = 1 ) - result_amount = null - -/datum/chemical_reaction/flash_powder/on_reaction(var/datum/reagents/holder, var/created_volume) - var/location = get_turf(holder.my_atom) - var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread - s.set_up(2, 1, location) - s.start() - for(var/mob/living/carbon/M in viewers(world.view, location)) - switch(get_dist(M, location)) - if(0 to 3) - if(hasvar(M, "glasses")) - if(istype(M:glasses, /obj/item/clothing/glasses/sunglasses)) - continue - - M.flash_eyes() - M.Weaken(15) - - if(4 to 5) - if(hasvar(M, "glasses")) - if(istype(M:glasses, /obj/item/clothing/glasses/sunglasses)) - continue - - M.flash_eyes() - M.Stun(5) - -/datum/chemical_reaction/emp_pulse - name = "EMP Pulse" - id = "emp_pulse" - result = null - required_reagents = list("uranium" = 1, "iron" = 1) // Yes, laugh, it's the best recipe I could think of that makes a little bit of sense - result_amount = 2 - -/datum/chemical_reaction/emp_pulse/on_reaction(var/datum/reagents/holder, var/created_volume) - var/location = get_turf(holder.my_atom) - // 100 created volume = 4 heavy range & 7 light range. A few tiles smaller than traitor EMP grandes. - // 200 created volume = 8 heavy range & 14 light range. 4 tiles larger than traitor EMP grenades. - empulse(location, round(created_volume / 24), round(created_volume / 20), round(created_volume / 18), round(created_volume / 14), 1) - //VOREStation Edit Start - if(!isliving(holder.my_atom)) //No more powergaming by creating a tiny amount of this - holder.clear_reagents() - //VOREStation Edit End - return - -/datum/chemical_reaction/nitroglycerin - name = "Nitroglycerin" - id = "nitroglycerin" - result = "nitroglycerin" - required_reagents = list("glycerol" = 1, "pacid" = 1, "sacid" = 1) - result_amount = 2 - log_is_important = 1 - -/datum/chemical_reaction/nitroglycerin/on_reaction(var/datum/reagents/holder, var/created_volume) - var/datum/effect/effect/system/reagents_explosion/e = new() - e.set_up(round (created_volume/2, 1), holder.my_atom, 0, 0) - if(isliving(holder.my_atom)) - e.amount *= 0.5 - var/mob/living/L = holder.my_atom - if(L.stat!=DEAD) - e.amount *= 0.5 - //VOREStation Add Start - else - holder.clear_reagents() //No more powergaming by creating a tiny amount of this - //VOREStation Add End - e.start() - - //holder.clear_reagents() //VOREStation Removal - return - -/datum/chemical_reaction/napalm - name = "Napalm" - id = "napalm" - result = null - required_reagents = list("aluminum" = 1, "phoron" = 1, "sacid" = 1 ) - result_amount = 1 - -/datum/chemical_reaction/napalm/on_reaction(var/datum/reagents/holder, var/created_volume) - var/turf/location = get_turf(holder.my_atom.loc) - for(var/turf/simulated/floor/target_tile in range(0,location)) - target_tile.assume_gas("volatile_fuel", created_volume, 400+T0C) - spawn (0) target_tile.hotspot_expose(700, 400) - holder.del_reagent("napalm") - return - -/datum/chemical_reaction/chemsmoke - name = "Chemsmoke" - id = "chemsmoke" - result = null - required_reagents = list("potassium" = 1, "sugar" = 1, "phosphorus" = 1) - result_amount = 0.4 - -/datum/chemical_reaction/chemsmoke/on_reaction(var/datum/reagents/holder, var/created_volume) - var/location = get_turf(holder.my_atom) - var/datum/effect/effect/system/smoke_spread/chem/S = new /datum/effect/effect/system/smoke_spread/chem - S.attach(location) - S.set_up(holder, created_volume, 0, location) - playsound(location, 'sound/effects/smoke.ogg', 50, 1, -3) - spawn(0) - S.start() - //VOREStation Edit Start - if(!isliving(holder.my_atom)) //No more powergaming by creating a tiny amount of this - holder.clear_reagents() - //VOREStation Edit End - return - -/datum/chemical_reaction/foam - name = "Foam" - id = "foam" - result = null - required_reagents = list("fluorosurfactant" = 1, "water" = 1) - result_amount = 2 - mix_message = "The solution violently bubbles!" - -/datum/chemical_reaction/foam/on_reaction(var/datum/reagents/holder, var/created_volume) - var/location = get_turf(holder.my_atom) - - for(var/mob/M in viewers(5, location)) - to_chat(M, "The solution spews out foam!") - - var/datum/effect/effect/system/foam_spread/s = new() - s.set_up(created_volume, location, holder, 0) - s.start() - //VOREStation Edit Start - if(!isliving(holder.my_atom)) //No more powergaming by creating a tiny amount of this - holder.clear_reagents() - //VOREStation Edit End - return - -/datum/chemical_reaction/metalfoam - name = "Metal Foam" - id = "metalfoam" - result = null - required_reagents = list("aluminum" = 3, "foaming_agent" = 1, "pacid" = 1) - result_amount = 5 - -/datum/chemical_reaction/metalfoam/on_reaction(var/datum/reagents/holder, var/created_volume) - var/location = get_turf(holder.my_atom) - - for(var/mob/M in viewers(5, location)) - to_chat(M, "The solution spews out a metalic foam!") - - var/datum/effect/effect/system/foam_spread/s = new() - s.set_up(created_volume, location, holder, 1) - s.start() - return - -/datum/chemical_reaction/ironfoam - name = "Iron Foam" - id = "ironlfoam" - result = null - required_reagents = list("iron" = 3, "foaming_agent" = 1, "pacid" = 1) - result_amount = 5 - -/datum/chemical_reaction/ironfoam/on_reaction(var/datum/reagents/holder, var/created_volume) - var/location = get_turf(holder.my_atom) - - for(var/mob/M in viewers(5, location)) - to_chat(M, "The solution spews out a metalic foam!") - - var/datum/effect/effect/system/foam_spread/s = new() - s.set_up(created_volume, location, holder, 2) - s.start() - return - -/* Paint */ - -/datum/chemical_reaction/red_paint - name = "Red paint" - id = "red_paint" - result = "paint" - required_reagents = list("plasticide" = 1, "water" = 3, "marker_ink_red" = 1) - result_amount = 5 - -/datum/chemical_reaction/red_paint/send_data() - return "#FE191A" - -/datum/chemical_reaction/orange_paint - name = "Orange paint" - id = "orange_paint" - result = "paint" - required_reagents = list("plasticide" = 1, "water" = 3, "marker_ink_orange" = 1) - result_amount = 5 - -/datum/chemical_reaction/orange_paint/send_data() - return "#FFBE4F" - -/datum/chemical_reaction/yellow_paint - name = "Yellow paint" - id = "yellow_paint" - result = "paint" - required_reagents = list("plasticide" = 1, "water" = 3, "marker_ink_yellow" = 1) - result_amount = 5 - -/datum/chemical_reaction/yellow_paint/send_data() - return "#FDFE7D" - -/datum/chemical_reaction/green_paint - name = "Green paint" - id = "green_paint" - result = "paint" - required_reagents = list("plasticide" = 1, "water" = 3, "marker_ink_green" = 1) - result_amount = 5 - -/datum/chemical_reaction/green_paint/send_data() - return "#18A31A" - -/datum/chemical_reaction/blue_paint - name = "Blue paint" - id = "blue_paint" - result = "paint" - required_reagents = list("plasticide" = 1, "water" = 3, "marker_ink_blue" = 1) - result_amount = 5 - -/datum/chemical_reaction/blue_paint/send_data() - return "#247CFF" - -/datum/chemical_reaction/purple_paint - name = "Purple paint" - id = "purple_paint" - result = "paint" - required_reagents = list("plasticide" = 1, "water" = 3, "marker_ink_purple" = 1) - result_amount = 5 - -/datum/chemical_reaction/purple_paint/send_data() - return "#CC0099" - -/datum/chemical_reaction/grey_paint //mime - name = "Grey paint" - id = "grey_paint" - result = "paint" - required_reagents = list("plasticide" = 1, "water" = 3, "marker_ink_grey" = 1) - result_amount = 5 - -/datum/chemical_reaction/grey_paint/send_data() - return "#808080" - -/datum/chemical_reaction/brown_paint - name = "Brown paint" - id = "brown_paint" - result = "paint" - required_reagents = list("plasticide" = 1, "water" = 3, "marker_ink_brown" = 1) - result_amount = 5 - -/datum/chemical_reaction/brown_paint/send_data() - return "#846F35" - -/datum/chemical_reaction/blood_paint - name = "Blood paint" - id = "blood_paint" - result = "paint" - required_reagents = list("plasticide" = 1, "water" = 3, "blood" = 2) - result_amount = 5 - -/datum/chemical_reaction/blood_paint/send_data(var/datum/reagents/T) - var/t = T.get_data("blood") - if(t && t["blood_colour"]) - return t["blood_colour"] - return "#FE191A" // Probably red - -/datum/chemical_reaction/milk_paint - name = "Milk paint" - id = "milk_paint" - result = "paint" - required_reagents = list("plasticide" = 1, "water" = 3, "milk" = 5) - result_amount = 5 - -/datum/chemical_reaction/milk_paint/send_data() - return "#F0F8FF" - -/datum/chemical_reaction/orange_juice_paint - name = "Orange juice paint" - id = "orange_juice_paint" - result = "paint" - required_reagents = list("plasticide" = 1, "water" = 3, "orangejuice" = 5) - result_amount = 5 - -/datum/chemical_reaction/orange_juice_paint/send_data() - return "#E78108" - -/datum/chemical_reaction/tomato_juice_paint - name = "Tomato juice paint" - id = "tomato_juice_paint" - result = "paint" - required_reagents = list("plasticide" = 1, "water" = 3, "tomatojuice" = 5) - result_amount = 5 - -/datum/chemical_reaction/tomato_juice_paint/send_data() - return "#731008" - -/datum/chemical_reaction/lime_juice_paint - name = "Lime juice paint" - id = "lime_juice_paint" - result = "paint" - required_reagents = list("plasticide" = 1, "water" = 3, "limejuice" = 5) - result_amount = 5 - -/datum/chemical_reaction/lime_juice_paint/send_data() - return "#365E30" - -/datum/chemical_reaction/carrot_juice_paint - name = "Carrot juice paint" - id = "carrot_juice_paint" - result = "paint" - required_reagents = list("plasticide" = 1, "water" = 3, "carrotjuice" = 5) - result_amount = 5 - -/datum/chemical_reaction/carrot_juice_paint/send_data() - return "#973800" - -/datum/chemical_reaction/berry_juice_paint - name = "Berry juice paint" - id = "berry_juice_paint" - result = "paint" - required_reagents = list("plasticide" = 1, "water" = 3, "berryjuice" = 5) - result_amount = 5 - -/datum/chemical_reaction/berry_juice_paint/send_data() - return "#990066" - -/datum/chemical_reaction/grape_juice_paint - name = "Grape juice paint" - id = "grape_juice_paint" - result = "paint" - required_reagents = list("plasticide" = 1, "water" = 3, "grapejuice" = 5) - result_amount = 5 - -/datum/chemical_reaction/grape_juice_paint/send_data() - return "#863333" - -/datum/chemical_reaction/poisonberry_juice_paint - name = "Poison berry juice paint" - id = "poisonberry_juice_paint" - result = "paint" - required_reagents = list("plasticide" = 1, "water" = 3, "poisonberryjuice" = 5) - result_amount = 5 - -/datum/chemical_reaction/poisonberry_juice_paint/send_data() - return "#863353" - -/datum/chemical_reaction/watermelon_juice_paint - name = "Watermelon juice paint" - id = "watermelon_juice_paint" - result = "paint" - required_reagents = list("plasticide" = 1, "water" = 3, "watermelonjuice" = 5) - result_amount = 5 - -/datum/chemical_reaction/watermelon_juice_paint/send_data() - return "#B83333" - -/datum/chemical_reaction/lemon_juice_paint - name = "Lemon juice paint" - id = "lemon_juice_paint" - result = "paint" - required_reagents = list("plasticide" = 1, "water" = 3, "lemonjuice" = 5) - result_amount = 5 - -/datum/chemical_reaction/lemon_juice_paint/send_data() - return "#AFAF00" - -/datum/chemical_reaction/banana_juice_paint - name = "Banana juice paint" - id = "banana_juice_paint" - result = "paint" - required_reagents = list("plasticide" = 1, "water" = 3, "banana" = 5) - result_amount = 5 - -/datum/chemical_reaction/banana_juice_paint/send_data() - return "#C3AF00" - -/datum/chemical_reaction/potato_juice_paint - name = "Potato juice paint" - id = "potato_juice_paint" - result = "paint" - required_reagents = list("plasticide" = 1, "water" = 3, "potatojuice" = 5) - result_amount = 5 - -/datum/chemical_reaction/potato_juice_paint/send_data() - return "#302000" - -/datum/chemical_reaction/carbon_paint - name = "Carbon paint" - id = "carbon_paint" - result = "paint" - required_reagents = list("plasticide" = 1, "water" = 3, "carbon" = 1) - result_amount = 5 - -/datum/chemical_reaction/carbon_paint/send_data() - return "#333333" - -/datum/chemical_reaction/aluminum_paint - name = "Aluminum paint" - id = "aluminum_paint" - result = "paint" - required_reagents = list("plasticide" = 1, "water" = 3, "aluminum" = 1) - result_amount = 5 - -/datum/chemical_reaction/aluminum_paint/send_data() - return "#F0F8FF" - -/* Food */ - -/datum/chemical_reaction/food/tofu - name = "Tofu" - id = "tofu" - result = null - required_reagents = list("soymilk" = 10) - catalysts = list("enzyme" = 5) - result_amount = 1 - -/datum/chemical_reaction/food/tofu/on_reaction(var/datum/reagents/holder, var/created_volume) - var/location = get_turf(holder.my_atom) - for(var/i = 1, i <= created_volume, i++) - new /obj/item/weapon/reagent_containers/food/snacks/tofu(location) - return - -/datum/chemical_reaction/food/chocolate_bar - name = "Chocolate Bar" - id = "chocolate_bar" - result = null - required_reagents = list("soymilk" = 2, "coco" = 2, "sugar" = 2) - result_amount = 1 - -/datum/chemical_reaction/food/chocolate_bar/on_reaction(var/datum/reagents/holder, var/created_volume) - var/location = get_turf(holder.my_atom) - for(var/i = 1, i <= created_volume, i++) - new /obj/item/weapon/reagent_containers/food/snacks/chocolatebar(location) - return - -/datum/chemical_reaction/food/chocolate_bar2 - name = "Chocolate Bar" - id = "chocolate_bar" - result = null - required_reagents = list("milk" = 2, "coco" = 2, "sugar" = 2) - result_amount = 1 - -/datum/chemical_reaction/food/chocolate_bar2/on_reaction(var/datum/reagents/holder, var/created_volume) - var/location = get_turf(holder.my_atom) - for(var/i = 1, i <= created_volume, i++) - new /obj/item/weapon/reagent_containers/food/snacks/chocolatebar(location) - return - -/datum/chemical_reaction/drinks/coffee - name = "Coffee" - id = "coffee" - result = "coffee" - required_reagents = list("water" = 5, "coffeepowder" = 1) - result_amount = 5 - -/datum/chemical_reaction/drinks/tea - name = "Black tea" - id = "tea" - result = "tea" - required_reagents = list("water" = 5, "teapowder" = 1) - result_amount = 5 - -/datum/chemical_reaction/drinks/hot_coco - name = "Hot Coco" - id = "hot_coco" - result = "hot_coco" - required_reagents = list("water" = 5, "coco" = 1) - result_amount = 5 - -/datum/chemical_reaction/food/soysauce - name = "Soy Sauce" - id = "soysauce" - result = "soysauce" - required_reagents = list("soymilk" = 4, "sacid" = 1) - result_amount = 5 - -/datum/chemical_reaction/drinks/grapejuice - name = "Grape Juice" - id = "grapejuice" - result = "grapejuice" - required_reagents = list("water" = 3, "instantgrape" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/orangejuice - name = "Orange Juice" - id = "orangejuice" - result = "orangejuice" - required_reagents = list("water" = 3, "instantorange" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/watermelonjuice - name = "Watermelon Juice" - id = "watermelonjuice" - result = "watermelonjuice" - required_reagents = list("water" = 3, "instantwatermelon" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/applejuice - name = "Apple Juice" - id = "applejuice" - result = "applejuice" - required_reagents = list("water" = 3, "instantapple" = 1) - result_amount = 3 - -/datum/chemical_reaction/food/ketchup - name = "Ketchup" - id = "ketchup" - result = "ketchup" - required_reagents = list("tomatojuice" = 2, "water" = 1, "sugar" = 1) - result_amount = 4 - -/datum/chemical_reaction/food/barbecue - name = "Barbeque Sauce" - id = "barbecue" - result = "barbecue" - required_reagents = list("tomatojuice" = 2, "applejuice" = 1, "sugar" = 1, "spacespice" = 1) - result_amount = 4 - -/datum/chemical_reaction/food/peanutbutter - name = "Peanut Butter" - id = "peanutbutter" - result = "peanutbutter" - required_reagents = list("peanutoil" = 2, "sugar" = 1, "sodiumchloride" = 1) - catalysts = list("enzyme" = 5) - result_amount = 3 - -/datum/chemical_reaction/food/mayonnaise - name = "mayonnaise" - id = "mayo" - result = "mayo" - required_reagents = list("egg" = 9, "cornoil" = 5, "lemonjuice" = 5, "sodiumchloride" = 1) - result_amount = 15 - -/datum/chemical_reaction/food/cheesewheel - name = "Cheesewheel" - id = "cheesewheel" - result = null - required_reagents = list("milk" = 40) - catalysts = list("enzyme" = 5) - result_amount = 1 - -/datum/chemical_reaction/food/cheesewheel/on_reaction(var/datum/reagents/holder, var/created_volume) - var/location = get_turf(holder.my_atom) - for(var/i = 1, i <= created_volume, i++) - new /obj/item/weapon/reagent_containers/food/snacks/sliceable/cheesewheel(location) - return - -/datum/chemical_reaction/food/meatball - name = "Meatball" - id = "meatball" - result = null - required_reagents = list("protein" = 3, "flour" = 5) - result_amount = 3 - -/datum/chemical_reaction/food/meatball/on_reaction(var/datum/reagents/holder, var/created_volume) - var/location = get_turf(holder.my_atom) - for(var/i = 1, i <= created_volume, i++) - new /obj/item/weapon/reagent_containers/food/snacks/meatball(location) - return - -/datum/chemical_reaction/food/dough - name = "Dough" - id = "dough" - result = null - required_reagents = list("egg" = 3, "flour" = 10) - inhibitors = list("water" = 1, "beer" = 1) //To prevent it messing with batter recipes - result_amount = 1 - -/datum/chemical_reaction/food/dough/on_reaction(var/datum/reagents/holder, var/created_volume) - var/location = get_turf(holder.my_atom) - for(var/i = 1, i <= created_volume, i++) - new /obj/item/weapon/reagent_containers/food/snacks/dough(location) - return - -/datum/chemical_reaction/food/syntiflesh - name = "Syntiflesh" - id = "syntiflesh" - result = null - required_reagents = list("blood" = 5, "clonexadone" = 5) - result_amount = 1 - -/datum/chemical_reaction/food/syntiflesh/on_reaction(var/datum/reagents/holder, var/created_volume) - var/location = get_turf(holder.my_atom) - for(var/i = 1, i <= created_volume, i++) - new /obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh(location) - return - -/datum/chemical_reaction/hot_ramen - name = "Hot Ramen" - id = "hot_ramen" - result = "hot_ramen" - required_reagents = list("water" = 1, "dry_ramen" = 3) - result_amount = 3 - -/datum/chemical_reaction/hell_ramen - name = "Hell Ramen" - id = "hell_ramen" - result = "hell_ramen" - required_reagents = list("capsaicin" = 1, "hot_ramen" = 6) - result_amount = 6 - -/* Alcohol */ - -/datum/chemical_reaction/drinks/goldschlager - name = "Goldschlager" - id = "goldschlager" - result = "goldschlager" - required_reagents = list("vodka" = 10, "gold" = 1) - result_amount = 10 - -/datum/chemical_reaction/drinks/patron - name = "Patron" - id = "patron" - result = "patron" - required_reagents = list("tequilla" = 10, "silver" = 1) - result_amount = 10 - -/datum/chemical_reaction/drinks/bilk - name = "Bilk" - id = "bilk" - result = "bilk" - required_reagents = list("milk" = 1, "beer" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/icetea - name = "Iced Tea" - id = "icetea" - result = "icetea" - required_reagents = list("ice" = 1, "tea" = 2) - result_amount = 3 - -/datum/chemical_reaction/drinks/icecoffee - name = "Iced Coffee" - id = "icecoffee" - result = "icecoffee" - required_reagents = list("ice" = 1, "coffee" = 2) - result_amount = 3 - -/datum/chemical_reaction/drinks/nuka_cola - name = "Nuclear Cola" - id = "nuka_cola" - result = "nuka_cola" - required_reagents = list("uranium" = 1, "cola" = 5) - result_amount = 5 - -/datum/chemical_reaction/drinks/moonshine - name = "Moonshine" - id = "moonshine" - result = "moonshine" - required_reagents = list("nutriment" = 10) - catalysts = list("enzyme" = 5) - result_amount = 10 - -/datum/chemical_reaction/drinks/grenadine - name = "Grenadine Syrup" - id = "grenadine" - result = "grenadine" - required_reagents = list("berryjuice" = 10) - catalysts = list("enzyme" = 5) - result_amount = 10 - -/datum/chemical_reaction/drinks/wine - name = "Wine" - id = "wine" - result = "wine" - required_reagents = list("grapejuice" = 10) - catalysts = list("enzyme" = 5) - result_amount = 10 - -/datum/chemical_reaction/drinks/pwine - name = "Poison Wine" - id = "pwine" - result = "pwine" - required_reagents = list("poisonberryjuice" = 10) - catalysts = list("enzyme" = 5) - result_amount = 10 - -/datum/chemical_reaction/drinks/melonliquor - name = "Melon Liquor" - id = "melonliquor" - result = "melonliquor" - required_reagents = list("watermelonjuice" = 10) - catalysts = list("enzyme" = 5) - result_amount = 10 - -/datum/chemical_reaction/drinks/bluecuracao - name = "Blue Curacao" - id = "bluecuracao" - result = "bluecuracao" - required_reagents = list("orangejuice" = 10) - catalysts = list("enzyme" = 5) - result_amount = 10 - -/datum/chemical_reaction/drinks/spacebeer - name = "Space Beer" - id = "spacebeer" - result = "beer" - required_reagents = list("cornoil" = 10) - catalysts = list("enzyme" = 5) - result_amount = 10 - -/datum/chemical_reaction/drinks/vodka - name = "Vodka" - id = "vodka" - result = "vodka" - required_reagents = list("potatojuice" = 10) - catalysts = list("enzyme" = 5) - result_amount = 10 - -/datum/chemical_reaction/drinks/cider - name = "Cider" - id = "cider" - result = "cider" - required_reagents = list("applejuice" = 10) - catalysts = list("enzyme" = 5) - result_amount = 10 - - -/datum/chemical_reaction/drinks/sake - name = "Sake" - id = "sake" - result = "sake" - required_reagents = list("rice" = 10) - catalysts = list("enzyme" = 5) - result_amount = 10 - -/datum/chemical_reaction/drinks/kahlua - name = "Kahlua" - id = "kahlua" - result = "kahlua" - required_reagents = list("coffee" = 5, "sugar" = 5) - catalysts = list("enzyme" = 5) - result_amount = 5 - -/datum/chemical_reaction/drinks/gin_tonic - name = "Gin and Tonic" - id = "gintonic" - result = "gintonic" - required_reagents = list("gin" = 2, "tonic" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/cuba_libre - name = "Cuba Libre" - id = "cubalibre" - result = "cubalibre" - required_reagents = list("rum" = 2, "cola" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/martini - name = "Classic Martini" - id = "martini" - result = "martini" - required_reagents = list("gin" = 2, "vermouth" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/vodkamartini - name = "Vodka Martini" - id = "vodkamartini" - result = "vodkamartini" - required_reagents = list("vodka" = 2, "vermouth" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/white_russian - name = "White Russian" - id = "whiterussian" - result = "whiterussian" - required_reagents = list("blackrussian" = 2, "cream" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/whiskey_cola - name = "Whiskey Cola" - id = "whiskeycola" - result = "whiskeycola" - required_reagents = list("whiskey" = 2, "cola" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/screwdriver - name = "Screwdriver" - id = "screwdrivercocktail" - result = "screwdrivercocktail" - required_reagents = list("vodka" = 2, "orangejuice" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/bloody_mary - name = "Bloody Mary" - id = "bloodymary" - result = "bloodymary" - required_reagents = list("vodka" = 2, "tomatojuice" = 3, "limejuice" = 1) - result_amount = 6 - -/datum/chemical_reaction/drinks/gargle_blaster - name = "Pan-Galactic Gargle Blaster" - id = "gargleblaster" - result = "gargleblaster" - required_reagents = list("vodka" = 2, "gin" = 1, "whiskey" = 1, "cognac" = 1, "limejuice" = 1) - result_amount = 6 - -/datum/chemical_reaction/drinks/brave_bull - name = "Brave Bull" - id = "bravebull" - result = "bravebull" - required_reagents = list("tequilla" = 2, "kahlua" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/tequilla_sunrise - name = "Tequilla Sunrise" - id = "tequillasunrise" - result = "tequillasunrise" - required_reagents = list("tequilla" = 2, "orangejuice" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/phoron_special - name = "Toxins Special" - id = "phoronspecial" - result = "phoronspecial" - required_reagents = list("rum" = 2, "vermouth" = 2, "phoron" = 2) - result_amount = 6 - -/datum/chemical_reaction/drinks/beepsky_smash - name = "Beepksy Smash" - id = "beepksysmash" - result = "beepskysmash" - required_reagents = list("limejuice" = 1, "whiskey" = 1, "iron" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/doctor_delight - name = "The Doctor's Delight" - id = "doctordelight" - result = "doctorsdelight" - required_reagents = list("limejuice" = 1, "tomatojuice" = 1, "orangejuice" = 1, "cream" = 2, "tricordrazine" = 1) - result_amount = 6 - -/datum/chemical_reaction/drinks/irish_cream - name = "Irish Cream" - id = "irishcream" - result = "irishcream" - required_reagents = list("whiskey" = 2, "cream" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/manly_dorf - name = "The Manly Dorf" - id = "manlydorf" - result = "manlydorf" - required_reagents = list ("beer" = 1, "ale" = 2) - result_amount = 3 - -/datum/chemical_reaction/drinks/hooch - name = "Hooch" - id = "hooch" - result = "hooch" - required_reagents = list ("sugar" = 1, "ethanol" = 2, "fuel" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/irish_coffee - name = "Irish Coffee" - id = "irishcoffee" - result = "irishcoffee" - required_reagents = list("irishcream" = 1, "coffee" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/b52 - name = "B-52" - id = "b52" - result = "b52" - required_reagents = list("irishcream" = 1, "kahlua" = 1, "cognac" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/atomicbomb - name = "Atomic Bomb" - id = "atomicbomb" - result = "atomicbomb" - required_reagents = list("b52" = 10, "uranium" = 1) - result_amount = 10 - -/datum/chemical_reaction/drinks/margarita - name = "Margarita" - id = "margarita" - result = "margarita" - required_reagents = list("tequilla" = 2, "limejuice" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/longislandicedtea - name = "Long Island Iced Tea" - id = "longislandicedtea" - result = "longislandicedtea" - required_reagents = list("vodka" = 1, "gin" = 1, "tequilla" = 1, "cubalibre" = 3) - result_amount = 6 - -/datum/chemical_reaction/drinks/icedtea - name = "Long Island Iced Tea" - id = "longislandicedtea" - result = "longislandicedtea" - required_reagents = list("vodka" = 1, "gin" = 1, "tequilla" = 1, "cubalibre" = 3) - result_amount = 6 - -/datum/chemical_reaction/drinks/threemileisland - name = "Three Mile Island Iced Tea" - id = "threemileisland" - result = "threemileisland" - required_reagents = list("longislandicedtea" = 10, "uranium" = 1) - result_amount = 10 - -/datum/chemical_reaction/drinks/whiskeysoda - name = "Whiskey Soda" - id = "whiskeysoda" - result = "whiskeysoda" - required_reagents = list("whiskey" = 2, "sodawater" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/black_russian - name = "Black Russian" - id = "blackrussian" - result = "blackrussian" - required_reagents = list("vodka" = 2, "kahlua" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/manhattan - name = "Manhattan" - id = "manhattan" - result = "manhattan" - required_reagents = list("whiskey" = 2, "vermouth" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/manhattan_proj - name = "Manhattan Project" - id = "manhattan_proj" - result = "manhattan_proj" - required_reagents = list("manhattan" = 10, "uranium" = 1) - result_amount = 10 - -/datum/chemical_reaction/drinks/vodka_tonic - name = "Vodka and Tonic" - id = "vodkatonic" - result = "vodkatonic" - required_reagents = list("vodka" = 2, "tonic" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/gin_fizz - name = "Gin Fizz" - id = "ginfizz" - result = "ginfizz" - required_reagents = list("gin" = 1, "sodawater" = 1, "limejuice" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/bahama_mama - name = "Bahama mama" - id = "bahama_mama" - result = "bahama_mama" - required_reagents = list("rum" = 2, "orangejuice" = 2, "limejuice" = 1, "ice" = 1) - result_amount = 6 - -/datum/chemical_reaction/drinks/singulo - name = "Singulo" - id = "singulo" - result = "singulo" - required_reagents = list("vodka" = 5, "radium" = 1, "wine" = 5) - result_amount = 10 - -/datum/chemical_reaction/drinks/alliescocktail - name = "Allies Cocktail" - id = "alliescocktail" - result = "alliescocktail" - required_reagents = list("martini" = 1, "vodka" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/demonsblood - name = "Demons Blood" - id = "demonsblood" - result = "demonsblood" - required_reagents = list("rum" = 3, "spacemountainwind" = 1, "blood" = 1, "dr_gibb" = 1) - result_amount = 6 - -/datum/chemical_reaction/drinks/booger - name = "Booger" - id = "booger" - result = "booger" - required_reagents = list("cream" = 2, "banana" = 1, "rum" = 1, "watermelonjuice" = 1) - result_amount = 5 - -/datum/chemical_reaction/drinks/antifreeze - name = "Anti-freeze" - id = "antifreeze" - result = "antifreeze" - required_reagents = list("vodka" = 1, "cream" = 1, "ice" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/barefoot - name = "Barefoot" - id = "barefoot" - result = "barefoot" - required_reagents = list("berryjuice" = 1, "cream" = 1, "vermouth" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/grapesoda - name = "Grape Soda" - id = "grapesoda" - result = "grapesoda" - required_reagents = list("grapejuice" = 2, "cola" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/sbiten - name = "Sbiten" - id = "sbiten" - result = "sbiten" - required_reagents = list("vodka" = 10, "capsaicin" = 1) - result_amount = 10 - -/datum/chemical_reaction/drinks/red_mead - name = "Red Mead" - id = "red_mead" - result = "red_mead" - required_reagents = list("blood" = 1, "mead" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/mead - name = "Mead" - id = "mead" - result = "mead" - required_reagents = list("sugar" = 1, "water" = 1) - catalysts = list("enzyme" = 5) - result_amount = 2 - -/datum/chemical_reaction/drinks/iced_beer - name = "Iced Beer" - id = "iced_beer" - result = "iced_beer" - required_reagents = list("beer" = 10, "frostoil" = 1) - result_amount = 10 - -/datum/chemical_reaction/drinks/iced_beer2 - name = "Iced Beer" - id = "iced_beer" - result = "iced_beer" - required_reagents = list("beer" = 5, "ice" = 1) - result_amount = 6 - -/datum/chemical_reaction/drinks/grog - name = "Grog" - id = "grog" - result = "grog" - required_reagents = list("rum" = 1, "water" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/soy_latte - name = "Soy Latte" - id = "soy_latte" - result = "soy_latte" - required_reagents = list("coffee" = 1, "soymilk" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/cafe_latte - name = "Cafe Latte" - id = "cafe_latte" - result = "cafe_latte" - required_reagents = list("coffee" = 1, "milk" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/acidspit - name = "Acid Spit" - id = "acidspit" - result = "acidspit" - required_reagents = list("sacid" = 1, "wine" = 5) - result_amount = 6 - -/datum/chemical_reaction/drinks/amasec - name = "Amasec" - id = "amasec" - result = "amasec" - required_reagents = list("iron" = 1, "wine" = 5, "vodka" = 5) - result_amount = 10 - -/datum/chemical_reaction/drinks/changelingsting - name = "Changeling Sting" - id = "changelingsting" - result = "changelingsting" - required_reagents = list("screwdrivercocktail" = 1, "limejuice" = 1, "lemonjuice" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/aloe - name = "Aloe" - id = "aloe" - result = "aloe" - required_reagents = list("cream" = 1, "whiskey" = 1, "watermelonjuice" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/andalusia - name = "Andalusia" - id = "andalusia" - result = "andalusia" - required_reagents = list("rum" = 1, "whiskey" = 1, "lemonjuice" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/snowwhite - name = "Snow White" - id = "snowwhite" - result = "snowwhite" - required_reagents = list("pineapplejuice" = 1, "rum" = 1, "lemon_lime" = 1, "egg" = 1, "kahlua" = 1, "sugar" = 1) //VoreStation Edit - result_amount = 2 - -/datum/chemical_reaction/drinks/irishcarbomb - name = "Irish Car Bomb" - id = "irishcarbomb" - result = "irishcarbomb" - required_reagents = list("ale" = 1, "irishcream" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/syndicatebomb - name = "Syndicate Bomb" - id = "syndicatebomb" - result = "syndicatebomb" - required_reagents = list("beer" = 1, "whiskeycola" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/erikasurprise - name = "Erika Surprise" - id = "erikasurprise" - result = "erikasurprise" - required_reagents = list("ale" = 2, "limejuice" = 1, "whiskey" = 1, "banana" = 1, "ice" = 1) - result_amount = 6 - -/datum/chemical_reaction/drinks/devilskiss - name = "Devils Kiss" - id = "devilskiss" - result = "devilskiss" - required_reagents = list("blood" = 1, "kahlua" = 1, "rum" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/hippiesdelight - name = "Hippies Delight" - id = "hippiesdelight" - result = "hippiesdelight" - required_reagents = list("psilocybin" = 1, "gargleblaster" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/bananahonk - name = "Banana Honk" - id = "bananahonk" - result = "bananahonk" - required_reagents = list("banana" = 1, "cream" = 1, "sugar" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/silencer - name = "Silencer" - id = "silencer" - result = "silencer" - required_reagents = list("nothing" = 1, "cream" = 1, "sugar" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/driestmartini - name = "Driest Martini" - id = "driestmartini" - result = "driestmartini" - required_reagents = list("nothing" = 1, "gin" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/lemonade - name = "Lemonade" - id = "lemonade" - result = "lemonade" - required_reagents = list("lemonjuice" = 1, "sugar" = 1, "water" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/melonade - name = "Melonade" - id = "melonade" - result = "melonade" - required_reagents = list("watermelonjuice" = 1, "sugar" = 1, "sodawater" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/appleade - name = "Appleade" - id = "appleade" - result = "appleade" - required_reagents = list("applejuice" = 1, "sugar" = 1, "sodawater" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/pineappleade - name = "Pineappleade" - id = "pineappleade" - result = "pineappleade" - required_reagents = list("pineapplejuice" = 2, "limejuice" = 1, "sodawater" = 2, "honey" = 1) - result_amount = 5 - -/datum/chemical_reaction/drinks/driverspunch - name = "Driver`s Punch" - id = "driverspunch" - result = "driverspunch" - required_reagents = list("appleade" = 2, "orangejuice" = 1, "mint" = 1, "sodawater" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/mintapplesparkle - name = "Mint Apple Sparkle" - id = "mintapplesparkle" - result = "mintapplesparkle" - required_reagents = list("appleade" = 2, "mint" = 1) - inhibitors = list("sodawater" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/berrycordial - name = "Berry Cordial" - id = "berrycordial" - result = "berrycordial" - required_reagents = list("berryjuice" = 4, "sugar" = 1, "lemonjuice" = 1) - result_amount = 5 - -/datum/chemical_reaction/drinks/tropicalfizz - name = "Tropical Fizz" - id = "tropicalfizz" - result = "tropicalfizz" - required_reagents = list("sodawater" = 6, "berryjuice" = 1, "mint" = 1, "limejuice" = 1, "lemonjuice" = 1, "pineapplejuice" = 1) - inhibitors = list("sugar" = 1) - result_amount = 8 - -/datum/chemical_reaction/drinks/melonspritzer - name = "Melon Spritzer" - id = "melonspritzer" - result = "melonspritzer" - required_reagents = list("watermelonjuice" = 2, "wine" = 2, "applejuice" = 1, "limejuice" = 1) - result_amount = 6 - -/datum/chemical_reaction/drinks/fauxfizz - name = "Faux Fizz" - id = "fauxfizz" - result = "fauxfizz" - required_reagents = list("sodawater" = 2, "berryjuice" = 1, "applejuice" = 1, "limejuice" = 1, "honey" = 1) - inhibitors = list("sugar" = 1) - result_amount = 6 - -/datum/chemical_reaction/drinks/firepunch - name = "Fire Punch" - id = "firepunch" - result = "firepunch" - required_reagents = list("sugar" = 1, "rum" = 2) - result_amount = 3 - -/datum/chemical_reaction/drinks/kiraspecial - name = "Kira Special" - id = "kiraspecial" - result = "kiraspecial" - required_reagents = list("orangejuice" = 1, "limejuice" = 1, "sodawater" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/brownstar - name = "Brown Star" - id = "brownstar" - result = "brownstar" - required_reagents = list("orangejuice" = 2, "cola" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/milkshake - name = "Milkshake" - id = "milkshake" - result = "milkshake" - required_reagents = list("cream" = 1, "ice" = 2, "milk" = 2) - result_amount = 5 - -/datum/chemical_reaction/drinks/peanutmilkshake - name = "Peanutbutter Milkshake" - id = "peanutmilkshake" - result = "peanutmilkshake" - required_reagents = list("cream" = 1, "ice" = 1, "peanutbutter" = 2, "milk" = 1) - result_amount = 5 - -/datum/chemical_reaction/drinks/rewriter - name = "Rewriter" - id = "rewriter" - result = "rewriter" - required_reagents = list("spacemountainwind" = 1, "coffee" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/suidream - name = "Sui Dream" - id = "suidream" - result = "suidream" - required_reagents = list("space_up" = 1, "bluecuracao" = 1, "melonliquor" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/shirleytemple - name = "Shirley Temple" - id = "shirley_temple" - result = "shirley_temple" - required_reagents = list("gingerale" = 4, "grenadine" = 1) - result_amount = 5 - -/datum/chemical_reaction/drinks/royrogers - name = "Roy Rogers" - id = "roy_rogers" - result = "roy_rogers" - required_reagents = list("shirley_temple" = 5, "lemon_lime" = 2) - result_amount = 7 - -/datum/chemical_reaction/drinks/collinsmix - name = "Collins Mix" - id = "collins_mix" - result = "collins_mix" - required_reagents = list("lemon_lime" = 3, "sodawater" = 1) - result_amount = 4 - -/datum/chemical_reaction/drinks/arnoldpalmer - name = "Arnold Palmer" - id = "arnold_palmer" - result = "arnold_palmer" - required_reagents = list("icetea" = 1, "lemonade" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/minttea - name = "Mint Tea" - id = "minttea" - result = "minttea" - required_reagents = list("tea" = 5, "mint" = 1) - result_amount = 6 - -/datum/chemical_reaction/drinks/lemontea - name = "Lemon Tea" - id = "lemontea" - result = "lemontea" - required_reagents = list("tea" = 5, "lemonjuice" = 1) - result_amount = 6 - -/datum/chemical_reaction/drinks/limetea - name = "Lime Tea" - id = "limetea" - result = "limetea" - required_reagents = list("tea" = 5, "limejuice" = 1) - result_amount = 6 - -/datum/chemical_reaction/drinks/orangetea - name = "Orange Tea" - id = "orangetea" - result = "orangetea" - required_reagents = list("tea" = 5, "orangejuice" = 1) - result_amount = 6 - -/datum/chemical_reaction/drinks/berrytea - name = "Berry Tea" - id = "berrytea" - result = "berrytea" - required_reagents = list("tea" = 5, "berryjuice" = 1) - result_amount = 6 - -/datum/chemical_reaction/drinks/sakebomb - name = "Sake Bomb" - id = "sakebomb" - result = "sakebomb" - required_reagents = list("beer" = 2, "sake" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/tamagozake - name = "Tamagozake" - id = "tamagozake" - result = "tamagozake" - required_reagents = list("sake" = 10, "sugar" = 5, "egg" = 3) - result_amount = 15 - -/datum/chemical_reaction/drinks/ginzamary - name = "Ginza Mary" - id = "ginzamary" - result = "ginzamary" - required_reagents = list("sake" = 2, "vodka" = 2, "tomatojuice" = 1) - result_amount = 5 - -/datum/chemical_reaction/drinks/tokyorose - name = "Tokyo Rose" - id = "tokyorose" - result = "tokyorose" - required_reagents = list("sake" = 1, "berryjuice" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/saketini - name = "Saketini" - id = "saketini" - result = "saketini" - required_reagents = list("sake" = 1, "gin" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/elysiumfacepunch - name = "Elysium Facepunch" - id = "elysiumfacepunch" - result = "elysiumfacepunch" - required_reagents = list("kahlua" = 1, "lemonjuice" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/erebusmoonrise - name = "Erebus Moonrise" - id = "erebusmoonrise" - result = "erebusmoonrise" - required_reagents = list("whiskey" = 1, "vodka" = 1, "tequilla" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/balloon - name = "Balloon" - id = "balloon" - result = "balloon" - required_reagents = list("cream" = 1, "bluecuracao" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/natunabrandy - name = "Natuna Brandy" - id = "natunabrandy" - result = "natunabrandy" - required_reagents = list("beer" = 1, "sodawater" = 2) - result_amount = 3 - -/datum/chemical_reaction/drinks/euphoria - name = "Euphoria" - id = "euphoria" - result = "euphoria" - required_reagents = list("specialwhiskey" = 1, "cognac" = 2) - result_amount = 3 - -/datum/chemical_reaction/drinks/xanaducannon - name = "Xanadu Cannon" - id = "xanaducannon" - result = "xanaducannon" - required_reagents = list("ale" = 1, "dr_gibb" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/debugger - name = "Debugger" - id = "debugger" - result = "debugger" - required_reagents = list("fuel" = 1, "sugar" = 2, "cornoil" = 2) - result_amount = 5 - -/datum/chemical_reaction/drinks/spacersbrew - name = "Spacer's Brew" - id = "spacersbrew" - result = "spacersbrew" - required_reagents = list("brownstar" = 4, "ethanol" = 1) - result_amount = 5 - -/datum/chemical_reaction/drinks/binmanbliss - name = "Binman Bliss" - id = "binmanbliss" - result = "binmanbliss" - required_reagents = list("sake" = 1, "tequilla" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/chrysanthemum - name = "Chrysanthemum" - id = "chrysanthemum" - result = "chrysanthemum" - required_reagents = list("sake" = 1, "melonliquor" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/deathbell - name = "Deathbell" - id = "deathbell" - result = "deathbell" - required_reagents = list("antifreeze" = 1, "gargleblaster" = 1, "syndicatebomb" =1) - result_amount = 3 - -/datum/chemical_reaction/bitters - name = "Bitters" - id = "bitters" - result = "bitters" - required_reagents = list("mint" = 5) - catalysts = list("enzyme" = 5) - result_amount = 5 - -/datum/chemical_reaction/drinks/soemmerfire - name = "Soemmer Fire" - id = "soemmerfire" - result = "soemmerfire" - required_reagents = list("manhattan" = 2, "condensedcapsaicin" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/winebrandy - name = "Wine brandy" - id = "winebrandy" - result = "winebrandy" - required_reagents = list("wine" = 10) - catalysts = list("enzyme" = 10) //10u enzyme so it requires more than is usually added. Stops overlap with wine recipe - result_amount = 5 - -/datum/chemical_reaction/drinks/lovepotion - name = "Love Potion" - id = "lovepotion" - result = "lovepotion" - required_reagents = list("cream" = 1, "berryjuice" = 1, "sugar" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/morningafter - name = "Morning After" - id = "morningafter" - result = "morningafter" - required_reagents = list("sbiten" = 1, "coffee" = 5) - result_amount = 6 - -/datum/chemical_reaction/drinks/vesper - name = "Vesper" - id = "vesper" - result = "vesper" - required_reagents = list("gin" = 3, "vodka" = 1, "wine" = 1) - result_amount = 4 - -/datum/chemical_reaction/drinks/rotgut - name = "Rotgut Fever Dream" - id = "rotgut" - result = "rotgut" - required_reagents = list("vodka" = 3, "rum" = 1, "whiskey" = 1, "cola" = 3) - result_amount = 8 - -/datum/chemical_reaction/drinks/entdraught - name = "Ent's Draught" - id = "entdraught" - result = "entdraught" - required_reagents = list("tonic" = 1, "holywater" = 1, "honey" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/voxdelight - name = "Vox's Delight" - id = "voxdelight" - result = "voxdelight" - required_reagents = list("phoron" = 3, "fuel" = 1, "water" = 1) - result_amount = 4 - -/datum/chemical_reaction/drinks/screamingviking - name = "Screaming Viking" - id = "screamingviking" - result = "screamingviking" - required_reagents = list("martini" = 2, "vodkatonic" = 2, "limejuice" = 1, "rum" = 1) - result_amount = 6 - -/datum/chemical_reaction/drinks/vilelemon - name = "Vile Lemon" - id = "vilelemon" - result = "vilelemon" - required_reagents = list("lemonade" = 5, "spacemountainwind" = 1) - result_amount = 6 - -/datum/chemical_reaction/drinks/dreamcream - name = "Dream Cream" - id = "dreamcream" - result = "dreamcream" - required_reagents = list("milk" = 2, "cream" = 1, "honey" = 1) - result_amount = 4 - -/datum/chemical_reaction/drinks/robustin - name = "Robustin" - id = "robustin" - result = "robustin" - required_reagents = list("antifreeze" = 1, "phoron" = 1, "fuel" = 1, "vodka" = 1) - result_amount = 4 - -/datum/chemical_reaction/drinks/virginsip - name = "Virgin Sip" - id = "virginsip" - result = "virginsip" - required_reagents = list("driestmartini" = 1, "water" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/chocoshake - name = "Chocolate Milkshake" - id = "chocoshake" - result = "chocoshake" - required_reagents = list("milkshake" = 1, "coco" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/berryshake - name = "Berry Milkshake" - id = "berryshake" - result = "berryshake" - required_reagents = list("milkshake" = 1, "berryjuice" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/coffeeshake - name = "Coffee Milkshake" - id = "coffeeshake" - result = "coffeeshake" - required_reagents = list("milkshake" = 1, "coffee" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/jellyshot - name = "Jelly Shot" - id = "jellyshot" - result = "jellyshot" - required_reagents = list("cherryjelly" = 4, "vodka" = 1) - result_amount = 5 - -/datum/chemical_reaction/drinks/slimeshot - name = "Named Bullet" - id = "slimeshot" - result = "slimeshot" - required_reagents = list("slimejelly" = 4, "vodka" = 1) - result_amount = 5 - -/datum/chemical_reaction/drinks/negroni - name = "Negroni" - id = "negroni" - result = "negroni" - required_reagents = list("gin" = 1, "bitters" = 1, "vermouth" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/cloverclub - name = "Clover Club" - id = "cloverclub" - result = "cloverclub" - required_reagents = list("berryjuice" = 1, "lemonjuice" = 1, "gin" = 3) - result_amount = 5 - -/datum/chemical_reaction/drinks/oldfashioned - name = "Old Fashioned" - id = "oldfashioned" - result = "oldfashioned" - required_reagents = list("whiskey" = 3, "bitters" = 1, "sugar" = 1) - result_amount = 5 - -/datum/chemical_reaction/drinks/whiskeysour - name = "Whiskey Sour" - id = "whiskeysour" - result = "whiskeysour" - required_reagents = list("whiskey" = 2, "lemonjuice" = 1, "sugar" = 1) - result_amount = 4 - -/datum/chemical_reaction/drinks/daiquiri - name = "Daiquiri" - id = "daiquiri" - result = "daiquiri" - required_reagents = list("rum" = 3, "limejuice" = 2, "sugar" = 1) - result_amount = 5 - -/datum/chemical_reaction/drinks/mintjulep - name = "Mint Julep" - id = "mintjulep" - result = "mintjulep" - required_reagents = list("whiskey" = 2, "water" = 1, "mint" = 1) - result_amount = 4 - -/datum/chemical_reaction/drinks/paloma - name = "Paloma" - id = "paloma" - result = "paloma" - required_reagents = list("orangejuice" = 1, "sodawater" = 1, "tequilla" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/mojito - name = "Mojito" - id = "mojito" - result = "mojito" - required_reagents = list("rum" = 3, "limejuice" = 1, "mint" = 1) - result_amount = 5 - -/datum/chemical_reaction/drinks/virginmojito - name = "Mojito" - id = "virginmojito" - result = "virginmojito" - required_reagents = list("sodawater" = 3, "limejuice" = 1, "mint" = 1, "sugar" = 1) - result_amount = 5 - -/datum/chemical_reaction/drinks/piscosour - name = "Pisco Sour" - id = "piscosour" - result = "piscosour" - required_reagents = list("winebrandy" = 1, "lemonjuice" = 1, "sugar" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/coldfront - name = "Cold Front" - id = "coldfront" - result = "coldfront" - required_reagents = list("icecoffee" = 1, "whiskey" = 1, "mint" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/godsake - name = "Gods Sake" - id = "godsake" - result = "godsake" - required_reagents = list("sake" = 2, "holywater" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/godka //Why you would put this in your body, I don't know. - name = "Godka" - id = "godka" - result = "godka" - required_reagents = list("vodka" = 1, "holywater" = 1, "ethanol" = 1, "carthatoline" = 1) - catalysts = list("enzyme" = 5, "holywater" = 5) - result_amount = 1 - -/datum/chemical_reaction/drinks/holywine - name = "Angel Ichor" - id = "holywine" - result = "holywine" - required_reagents = list("grapejuice" = 5, "gold" = 5) - catalysts = list("holywater" = 5) - result_amount = 10 - -/datum/chemical_reaction/drinks/holy_mary - name = "Holy Mary" - id = "holymary" - result = "holymary" - required_reagents = list("vodka" = 2, "holywine" = 3, "limejuice" = 1) - result_amount = 6 - -/datum/chemical_reaction/drinks/angelskiss - name = "Angels Kiss" - id = "angelskiss" - result = "angelskiss" - required_reagents = list("holywine" = 1, "kahlua" = 1, "rum" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/angelswrath - name = "Angels Wrath" - id = "angelswrath" - result = "angelswrath" - required_reagents = list("rum" = 3, "spacemountainwind" = 1, "holywine" = 1, "dr_gibb" = 1) - result_amount = 6 - -/datum/chemical_reaction/drinks/ichor_mead - name = "Ichor Mead" - id = "ichor_mead" - result = "ichor_mead" - required_reagents = list("holywine" = 1, "mead" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/oilslick - name = "Oil Slick" - id = "oilslick" - result = "oilslick" - required_reagents = list("cornoil" = 2, "honey" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/slimeslam - name = "Slick Slime Slammer" - id = "slimeslammer" - result = "slimeslammer" - required_reagents = list("cornoil" = 2, "peanutbutter" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/virginsexonthebeach - name = "Virgin Sex On The Beach" - id = "virginsexonthebeach" - result = "virginsexonthebeach" - required_reagents = list("orangejuice" = 3, "grenadine" = 2) - result_amount = 5 - -/datum/chemical_reaction/drinks/sexonthebeach - name = "Sex On The Beach" - id = "sexonthebeach" - result = "sexonthebeach" - required_reagents = list("virginsexonthebeach" = 5, "vodka" = 1) - result_amount = 6 - -/datum/chemical_reaction/drinks/eggnog - name = "Eggnog" - id = "eggnog" - result = "eggnog" - required_reagents = list("milk" = 5, "cream" = 5, "sugar" = 5, "egg" = 3) - result_amount = 15 - -/datum/chemical_reaction/drinks/nuclearwaste_radium - name = "Nuclear Waste" - id = "nuclearwasterad" - result = "nuclearwaste" - required_reagents = list("oilslick" = 1, "radium" = 1, "limejuice" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/nuclearwaste_uranium - name = "Nuclear Waste" - id = "nuclearwasteuran" - result = "nuclearwaste" - required_reagents = list("oilslick" = 2, "uranium" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/sodaoil - name = "Soda Oil" - id = "sodaoil" - result = "sodaoil" - required_reagents = list("cornoil" = 4, "sodawater" = 1, "carbon" = 1, "tricordrazine" = 1) - result_amount = 6 - -/datum/chemical_reaction/drinks/fusionnaire - name = "Fusionnaire" - id = "fusionnaire" - result = "fusionnaire" - required_reagents = list("lemonjuice" = 3, "vodka" = 2, "schnapps_pep" = 1, "schnapps_lem" = 1, "rum" = 1, "ice" = 1) - result_amount = 9 - -//R-UST Port -/datum/chemical_reaction/hyrdophoron - name = "Hydrophoron" - id = "hydrophoron" - result = "hydrophoron" - required_reagents = list("hydrogen" = 1, "phoron" = 1) - inhibitors = list("nitrogen" = 1) //So it doesn't mess with lexorin - result_amount = 2 - -/datum/chemical_reaction/deuterium - name = "Deuterium" - id = "deuterium" - result = null - required_reagents = list("hydrophoron" = 5, "water" = 10) - result_amount = 15 - -/datum/chemical_reaction/deuterium/on_reaction(var/datum/reagents/holder, var/created_volume) - var/turf/T = get_turf(holder.my_atom) - if(istype(T)) new /obj/item/stack/material/deuterium(T, created_volume) - return - -//Skrellian crap. -/datum/chemical_reaction/talum_quem - name = "Talum-quem" - id = "talum_quem" - result = "talum_quem" - required_reagents = list("space_drugs" = 2, "sugar" = 1, "amatoxin" = 1) - result_amount = 4 - -/datum/chemical_reaction/qerr_quem - name = "Qerr-quem" - id = "qerr_quem" - result = "qerr_quem" - required_reagents = list("nicotine" = 1, "carbon" = 1, "sugar" = 2) - result_amount = 4 - -/datum/chemical_reaction/malish_qualem - name = "Malish-Qualem" - id = "malish-qualem" - result = "malish-qualem" - required_reagents = list("immunosuprizine" = 1, "qerr_quem" = 1, "inaprovaline" = 1) - catalysts = list("phoron" = 5) - result_amount = 2 - -// Biomass, for cloning and bioprinters -/datum/chemical_reaction/biomass - name = "Biomass" - id = "biomass" - result = "biomass" - required_reagents = list("protein" = 1, "sugar" = 1, "phoron" = 1) - result_amount = 1 // Roughly 20u per phoron sheet - -// Neutralization. - -/datum/chemical_reaction/neutralize_neurotoxic_protein - name = "Neutralize Toxic Proteins" - id = "neurotoxic_protein_neutral" - result = "protein" - required_reagents = list("anti_toxin" = 1, "neurotoxic_protein" = 2) - result_amount = 2 - -/datum/chemical_reaction/neutralize_carpotoxin - name = "Neutralize Carpotoxin" - id = "carpotoxin_neutral" - result = "protein" - required_reagents = list("radium" = 1, "carpotoxin" = 1, "sifsap" = 1) - catalysts = list("sifsap" = 10) - result_amount = 2 - -/datum/chemical_reaction/neutralize_spidertoxin - name = "Neutralize Spidertoxin" - id = "spidertoxin_neutral" - result = "protein" - required_reagents = list("radium" = 1, "spidertoxin" = 1, "sifsap" = 1) - catalysts = list("sifsap" = 10) - result_amount = 2 - -/* -==================== - Aurora Food -==================== -*/ - -/datum/chemical_reaction/coating/batter - name = "Batter" - id = "batter" - result = "batter" - required_reagents = list("egg" = 3, "flour" = 10, "water" = 5, "sodiumchloride" = 2) - result_amount = 20 - -/datum/chemical_reaction/coating/beerbatter - name = "Beer Batter" - id = "beerbatter" - result = "beerbatter" - required_reagents = list("egg" = 3, "flour" = 10, "beer" = 5, "sodiumchloride" = 2) - result_amount = 20 - -/datum/chemical_reaction/browniemix - name = "Brownie Mix" - id = "browniemix" - result = "browniemix" - required_reagents = list("flour" = 5, "coco" = 5, "sugar" = 5) - result_amount = 15 - -/datum/chemical_reaction/butter - name = "Butter" - id = "butter" - result = null - required_reagents = list("cream" = 20, "sodiumchloride" = 1) - result_amount = 1 - -/datum/chemical_reaction/butter/on_reaction(var/datum/reagents/holder, var/created_volume) - var/location = get_turf(holder.my_atom) - for(var/i = 1, i <= created_volume, i++) - new /obj/item/weapon/reagent_containers/food/snacks/spreads/butter(location) - return - -/datum/chemical_reaction/browniemix - name = "Brownie Mix" - id = "browniemix" - result = "browniemix" - required_reagents = list("flour" = 5, "coco" = 5, "sugar" = 5) - result_amount = 15 diff --git a/code/modules/reagents/holder/distilling.dm b/code/modules/reagents/holder/distilling.dm new file mode 100644 index 00000000000..1599f395d91 --- /dev/null +++ b/code/modules/reagents/holder/distilling.dm @@ -0,0 +1,26 @@ +/datum/reagents/distilling/handle_reactions() + if(QDELETED(my_atom)) + return FALSE + if(my_atom.flags & NOREACT) + return FALSE + var/reaction_occurred + var/list/eligible_reactions = list() + var/list/effect_reactions = list() + do + reaction_occurred = FALSE + for(var/i in reagent_list) + var/datum/reagent/R = i + if(SSchemistry.distilled_reactions_by_reagent[R.id]) + eligible_reactions |= SSchemistry.distilled_reactions_by_reagent[R.id] + + for(var/i in eligible_reactions) + var/decl/chemical_reaction/C = i + if(C.can_happen(src) && C.process(src)) + effect_reactions |= C + reaction_occurred = TRUE + eligible_reactions.len = 0 + while(reaction_occurred) + for(var/i in effect_reactions) + var/decl/chemical_reaction/C = i + C.post_reaction(src) + update_total() \ No newline at end of file diff --git a/code/modules/reagents/Chemistry-Holder.dm b/code/modules/reagents/holder/holder.dm similarity index 94% rename from code/modules/reagents/Chemistry-Holder.dm rename to code/modules/reagents/holder/holder.dm index aa50a4b79f9..cdb602ad70b 100644 --- a/code/modules/reagents/Chemistry-Holder.dm +++ b/code/modules/reagents/holder/holder.dm @@ -1,518 +1,531 @@ -#define PROCESS_REACTION_ITER 5 //when processing a reaction, iterate this many times - -/datum/reagents - var/list/datum/reagent/reagent_list = list() - var/total_volume = 0 - var/maximum_volume = 100 - var/atom/my_atom = null - -/datum/reagents/New(var/max = 100, atom/A = null) - ..() - maximum_volume = max - my_atom = A - - //I dislike having these here but map-objects are initialised before world/New() is called. >_> - if(!SSchemistry.chemical_reagents) - //Chemical Reagents - Initialises all /datum/reagent into a list indexed by reagent id - var/paths = typesof(/datum/reagent) - /datum/reagent - SSchemistry.chemical_reagents = list() - for(var/path in paths) - var/datum/reagent/D = new path() - if(!D.name) - continue - SSchemistry.chemical_reagents[D.id] = D - -/datum/reagents/Destroy() - STOP_PROCESSING(SSchemistry, src) - for(var/datum/reagent/R in reagent_list) - qdel(R) - reagent_list = null - if(my_atom && my_atom.reagents == src) - my_atom.reagents = null - return ..() - -/* Internal procs */ - -/datum/reagents/proc/get_free_space() // Returns free space. - return maximum_volume - total_volume - -/datum/reagents/proc/get_master_reagent() // Returns reference to the reagent with the biggest volume. - var/the_reagent = null - var/the_volume = 0 - - for(var/datum/reagent/A in reagent_list) - if(A.volume > the_volume) - the_volume = A.volume - the_reagent = A - - return the_reagent - -/datum/reagents/proc/get_master_reagent_name() // Returns the name of the reagent with the biggest volume. - var/the_name = null - var/the_volume = 0 - for(var/datum/reagent/A in reagent_list) - if(A.volume > the_volume) - the_volume = A.volume - the_name = A.name - - return the_name - -/datum/reagents/proc/get_master_reagent_id() // Returns the id of the reagent with the biggest volume. - var/the_id = null - var/the_volume = 0 - for(var/datum/reagent/A in reagent_list) - if(A.volume > the_volume) - the_volume = A.volume - the_id = A.id - - return the_id - -/datum/reagents/proc/update_total() // Updates volume. - total_volume = 0 - for(var/datum/reagent/R in reagent_list) - if(R.volume < MINIMUM_CHEMICAL_VOLUME) - del_reagent(R.id) - else - total_volume += R.volume - return - -/datum/reagents/proc/handle_reactions() - if(QDELETED(my_atom)) - return FALSE - if(my_atom.flags & NOREACT) - return FALSE - var/reaction_occurred - var/list/eligible_reactions = list() - var/list/effect_reactions = list() - do - reaction_occurred = FALSE - for(var/i in reagent_list) - var/datum/reagent/R = i - if(SSchemistry.chemical_reactions_by_reagent[R.id]) - eligible_reactions |= SSchemistry.chemical_reactions_by_reagent[R.id] - - for(var/i in eligible_reactions) - var/datum/chemical_reaction/C = i - if(C.can_happen(src) && C.process(src)) - effect_reactions |= C - reaction_occurred = TRUE - eligible_reactions.len = 0 - while(reaction_occurred) - for(var/i in effect_reactions) - var/datum/chemical_reaction/C = i - C.post_reaction(src) - update_total() - -/* Holder-to-chemical */ - -/datum/reagents/proc/add_reagent(var/id, var/amount, var/data = null, var/safety = 0) - if(!isnum(amount) || amount <= 0) - return 0 - - update_total() - amount = min(amount, get_free_space()) - - if(istype(my_atom,/obj/item/weapon/reagent_containers/food)) //The following code is targeted specifically at getting allergen reagents into food items, since for the most part they're not applied by default. - var/list/add_reagents = list() - var/totalnum = 0 - - for(var/item in data) //Try to find the ID - var/add_reagent_id = null - if(item in SSchemistry.chemical_reagents) - add_reagent_id = item - else if("[item]juice" in SSchemistry.chemical_reagents) - add_reagent_id = "[item]juice" - if(add_reagent_id) //If we did find it, add it to our list of reagents to add, and add the number to our total. - add_reagents[add_reagent_id] += data[item] - totalnum += data[item] - - if(totalnum) - var/multconst = amount/totalnum //We're going to add these extra reagents so that they share the ratio described, but only add up to 1x the existing amount at the most - for(var/item in add_reagents) - add_reagent(item,add_reagents[item]*multconst) - - - - - for(var/datum/reagent/current in reagent_list) - if(current.id == id) - if(current.id == "blood") - if(LAZYLEN(data) && !isnull(data["species"]) && !isnull(current.data["species"]) && data["species"] != current.data["species"]) // Species bloodtypes are already incompatible, this just stops it from mixing into the one already in a container. - continue - - current.volume += amount - if(!isnull(data)) // For all we know, it could be zero or empty string and meaningful - current.mix_data(data, amount) - update_total() - if(!safety) - handle_reactions() - if(my_atom) - my_atom.on_reagent_change() - return 1 - var/datum/reagent/D = SSchemistry.chemical_reagents[id] - if(D) - var/datum/reagent/R = new D.type() - reagent_list += R - R.holder = src - R.volume = amount - R.initialize_data(data) - update_total() - if(!safety) - handle_reactions() - if(my_atom) - my_atom.on_reagent_change() - return 1 - else - crash_with("[my_atom] attempted to add a reagent called '[id]' which doesn't exist. ([usr])") - return 0 - -/datum/reagents/proc/isolate_reagent(reagent) - for(var/A in reagent_list) - var/datum/reagent/R = A - if(R.id != reagent) - del_reagent(R.id) - update_total() - -/datum/reagents/proc/remove_reagent(var/id, var/amount, var/safety = 0) - if(!isnum(amount)) - return 0 - for(var/datum/reagent/current in reagent_list) - if(current.id == id) - current.volume -= amount // It can go negative, but it doesn't matter - update_total() // Because this proc will delete it then - if(!safety) - handle_reactions() - if(my_atom) - my_atom.on_reagent_change() - return 1 - return 0 - -/datum/reagents/proc/del_reagent(var/id) - for(var/datum/reagent/current in reagent_list) - if (current.id == id) - reagent_list -= current - qdel(current) - update_total() - if(my_atom) - my_atom.on_reagent_change() - return 0 - -/datum/reagents/proc/has_reagent(var/id, var/amount = 0) - for(var/datum/reagent/current in reagent_list) - if(current.id == id) - if(current.volume >= amount) - return 1 - else - return 0 - return 0 - -/datum/reagents/proc/has_any_reagent(var/list/check_reagents) - for(var/datum/reagent/current in reagent_list) - if(current.id in check_reagents) - if(current.volume >= check_reagents[current.id]) - return 1 - else - return 0 - return 0 - -/datum/reagents/proc/has_all_reagents(var/list/check_reagents) - //this only works if check_reagents has no duplicate entries... hopefully okay since it expects an associative list - var/missing = check_reagents.len - for(var/datum/reagent/current in reagent_list) - if(current.id in check_reagents) - if(current.volume >= check_reagents[current.id]) - missing-- - return !missing - -/datum/reagents/proc/clear_reagents() - for(var/datum/reagent/current in reagent_list) - del_reagent(current.id) - return - -/datum/reagents/proc/get_reagent_amount(var/id) - for(var/datum/reagent/current in reagent_list) - if(current.id == id) - return current.volume - return 0 - -/datum/reagents/proc/get_data(var/id) - for(var/datum/reagent/current in reagent_list) - if(current.id == id) - return current.get_data() - return 0 - -/datum/reagents/proc/get_reagents() - . = list() - for(var/datum/reagent/current in reagent_list) - . += "[current.id] ([current.volume])" - return english_list(., "EMPTY", "", ", ", ", ") - -/* Holder-to-holder and similar procs */ - -/datum/reagents/proc/remove_any(var/amount = 1) // Removes up to [amount] of reagents from [src]. Returns actual amount removed. - amount = min(amount, total_volume) - - if(!amount) - return - - var/part = amount / total_volume - - for(var/datum/reagent/current in reagent_list) - var/amount_to_remove = current.volume * part - remove_reagent(current.id, amount_to_remove, 1) - - update_total() - handle_reactions() - return amount - -/datum/reagents/proc/trans_to_holder(var/datum/reagents/target, var/amount = 1, var/multiplier = 1, var/copy = 0) // Transfers [amount] reagents from [src] to [target], multiplying them by [multiplier]. Returns actual amount removed from [src] (not amount transferred to [target]). - if(!target || !istype(target)) - return - - amount = max(0, min(amount, total_volume, target.get_free_space() / multiplier)) - - if(!amount) - return - - var/part = amount / total_volume - - for(var/datum/reagent/current in reagent_list) - var/amount_to_transfer = current.volume * part - target.add_reagent(current.id, amount_to_transfer * multiplier, current.get_data(), safety = 1) // We don't react until everything is in place - if(!copy) - remove_reagent(current.id, amount_to_transfer, 1) - - if(!copy) - handle_reactions() - target.handle_reactions() - return amount - -/* Holder-to-atom and similar procs */ - -//The general proc for applying reagents to things. This proc assumes the reagents are being applied externally, -//not directly injected into the contents. It first calls touch, then the appropriate trans_to_*() or splash_mob(). -//If for some reason touch effects are bypassed (e.g. injecting stuff directly into a reagent container or person), -//call the appropriate trans_to_*() proc. -/datum/reagents/proc/trans_to(var/atom/target, var/amount = 1, var/multiplier = 1, var/copy = 0) - touch(target) //First, handle mere touch effects - - if(ismob(target)) - return splash_mob(target, amount, copy) - if(isturf(target)) - return trans_to_turf(target, amount, multiplier, copy) - if(isobj(target) && target.is_open_container()) - return trans_to_obj(target, amount, multiplier, copy) - return 0 - -//Splashing reagents is messier than trans_to, the target's loc gets some of the reagents as well. -/datum/reagents/proc/splash(var/atom/target, var/amount = 1, var/multiplier = 1, var/copy = 0, var/min_spill=0, var/max_spill=60) - var/spill = 0 - if(!isturf(target) && target.loc) - spill = amount*(rand(min_spill, max_spill)/100) - amount -= spill - if(spill) - splash(target.loc, spill, multiplier, copy, min_spill, max_spill) - - if(!trans_to(target, amount, multiplier, copy)) - touch(target, amount) - -/datum/reagents/proc/trans_type_to(var/target, var/rtype, var/amount = 1) - if (!target) - return - - var/datum/reagent/transfering_reagent = get_reagent(rtype) - - if (istype(target, /atom)) - var/atom/A = target - if (!A.reagents || !A.simulated) - return - - amount = min(amount, transfering_reagent.volume) - - if(!amount) - return - - - var/datum/reagents/F = new /datum/reagents(amount) - var/tmpdata = get_data(rtype) - F.add_reagent(rtype, amount, tmpdata) - remove_reagent(rtype, amount) - - - if (istype(target, /atom)) - return F.trans_to(target, amount) // Let this proc check the atom's type - else if (istype(target, /datum/reagents)) - return F.trans_to_holder(target, amount) - -/datum/reagents/proc/trans_id_to(var/atom/target, var/id, var/amount = 1) - if (!target || !target.reagents) - return - - amount = min(amount, get_reagent_amount(id)) - - if(!amount) - return - - var/datum/reagents/F = new /datum/reagents(amount) - var/tmpdata = get_data(id) - F.add_reagent(id, amount, tmpdata) - remove_reagent(id, amount) - - return F.trans_to(target, amount) // Let this proc check the atom's type - -// When applying reagents to an atom externally, touch() is called to trigger any on-touch effects of the reagent. -// This does not handle transferring reagents to things. -// For example, splashing someone with water will get them wet and extinguish them if they are on fire, -// even if they are wearing an impermeable suit that prevents the reagents from contacting the skin. -/datum/reagents/proc/touch(var/atom/target, var/amount) - if(ismob(target)) - touch_mob(target, amount) - if(isturf(target)) - touch_turf(target, amount) - if(isobj(target)) - touch_obj(target, amount) - return - -/datum/reagents/proc/touch_mob(var/mob/target) - if(!target || !istype(target)) - return - - for(var/datum/reagent/current in reagent_list) - current.touch_mob(target, current.volume) - - update_total() - -/datum/reagents/proc/touch_turf(var/turf/target, var/amount) - if(!target || !istype(target)) - return - - for(var/datum/reagent/current in reagent_list) - current.touch_turf(target, amount) - - update_total() - -/datum/reagents/proc/touch_obj(var/obj/target, var/amount) - if(!target || !istype(target)) - return - - for(var/datum/reagent/current in reagent_list) - current.touch_obj(target, amount) - - update_total() - -// Attempts to place a reagent on the mob's skin. -// Reagents are not guaranteed to transfer to the target. -// Do not call this directly, call trans_to() instead. -/datum/reagents/proc/splash_mob(var/mob/target, var/amount = 1, var/copy = 0) - var/perm = 1 - if(isliving(target)) //will we ever even need to tranfer reagents to non-living mobs? - var/mob/living/L = target - if(ishuman(L)) - var/mob/living/carbon/human/H = L - if(H.check_shields(0, null, null, null, "the spray") == 1) //If they block the spray, it does nothing. - amount = 0 - perm = L.reagent_permeability() - return trans_to_mob(target, amount, CHEM_TOUCH, perm, copy) - -/datum/reagents/proc/trans_to_mob(var/mob/target, var/amount = 1, var/type = CHEM_BLOOD, var/multiplier = 1, var/copy = 0) // Transfer after checking into which holder... - if(!target || !istype(target)) - return - if(iscarbon(target)) - var/mob/living/carbon/C = target - if(type == CHEM_BLOOD) - var/datum/reagents/R = C.reagents - return trans_to_holder(R, amount, multiplier, copy) - if(type == CHEM_INGEST) - var/datum/reagents/R = C.ingested - return C.ingest(src, R, amount, multiplier, copy) - if(type == CHEM_TOUCH) - var/datum/reagents/R = C.touching - return trans_to_holder(R, amount, multiplier, copy) - else - var/datum/reagents/R = new /datum/reagents(amount) - . = trans_to_holder(R, amount, multiplier, copy) - R.touch_mob(target) - -/datum/reagents/proc/trans_to_turf(var/turf/target, var/amount = 1, var/multiplier = 1, var/copy = 0) // Turfs don't have any reagents (at least, for now). Just touch it. - if(!target) - return - - var/datum/reagents/R = new /datum/reagents(amount * multiplier) - . = trans_to_holder(R, amount, multiplier, copy) - R.touch_turf(target, amount) - return - -/datum/reagents/proc/trans_to_obj(var/obj/target, var/amount = 1, var/multiplier = 1, var/copy = 0) // Objects may or may not; if they do, it's probably a beaker or something and we need to transfer properly; otherwise, just touch. - if(!target) - return - - if(!target.reagents) - var/datum/reagents/R = new /datum/reagents(amount * multiplier) - . = trans_to_holder(R, amount, multiplier, copy) - R.touch_obj(target, amount) - return - - return trans_to_holder(target.reagents, amount, multiplier, copy) - -/* Atom reagent creation - use it all the time */ - -/atom/proc/create_reagents(var/max_vol) - reagents = new/datum/reagents(max_vol, src) - -// Aurora Cooking Port -/datum/reagents/proc/get_reagent(var/id) // Returns reference to reagent matching passed ID - for(var/datum/reagent/A in reagent_list) - if (A.id == id) - return A - - return null - -//Spreads the contents of this reagent holder all over the vicinity of the target turf. -/datum/reagents/proc/splash_area(var/turf/epicentre, var/range = 3, var/portion = 1.0, var/multiplier = 1, var/copy = 0) - var/list/things = dview(range, epicentre, INVISIBILITY_LIGHTING) - var/list/turfs = list() - for (var/turf/T in things) - turfs += T - if (!turfs.len) - return//Nowhere to splash to, somehow - //Create a temporary holder to hold all the amount that will be spread - var/datum/reagents/R = new /datum/reagents(total_volume * portion * multiplier) - trans_to_holder(R, total_volume * portion, multiplier, copy) - //The exact amount that will be given to each turf - var/turfportion = R.total_volume / turfs.len - for (var/turf/T in turfs) - var/datum/reagents/TR = new /datum/reagents(turfportion) - R.trans_to_holder(TR, turfportion, 1, 0) - TR.splash_turf(T) - qdel(R) - - -//Spreads the contents of this reagent holder all over the target turf, dividing among things in it. -//50% is divided between mobs, 20% between objects, and whatever is left on the turf itself -/datum/reagents/proc/splash_turf(var/turf/T, var/amount = null, var/multiplier = 1, var/copy = 0) - if (isnull(amount)) - amount = total_volume - else - amount = min(amount, total_volume) - if (amount <= 0) - return - var/list/mobs = list() - for (var/mob/M in T) - mobs += M - var/list/objs = list() - for (var/obj/O in T) - objs += O - if (objs.len) - var/objportion = (amount * 0.2) / objs.len - for (var/o in objs) - var/obj/O = o - trans_to(O, objportion, multiplier, copy) - amount = min(amount, total_volume) - if (mobs.len) - var/mobportion = (amount * 0.5) / mobs.len - for (var/m in mobs) - var/mob/M = m - trans_to(M, mobportion, multiplier, copy) - trans_to(T, total_volume, multiplier, copy) - if (total_volume <= 0) - qdel(src) \ No newline at end of file +#define PROCESS_REACTION_ITER 5 //when processing a reaction, iterate this many times + +/datum/reagents + var/list/datum/reagent/reagent_list = list() + var/total_volume = 0 + var/maximum_volume = 100 + var/atom/my_atom = null + +/datum/reagents/New(var/max = 100, atom/A = null) + ..() + maximum_volume = max + my_atom = A + + //I dislike having these here but map-objects are initialised before world/New() is called. >_> + if(!SSchemistry.chemical_reagents) + //Chemical Reagents - Initialises all /datum/reagent into a list indexed by reagent id + var/paths = subtypesof(/datum/reagent) + SSchemistry.chemical_reagents = list() + for(var/path in paths) + var/datum/reagent/D = new path() + if(!D.name) + continue + SSchemistry.chemical_reagents[D.id] = D + +/datum/reagents/Destroy() + for(var/datum/reagent/R in reagent_list) + qdel(R) + reagent_list = null + if(my_atom && my_atom.reagents == src) + my_atom.reagents = null + return ..() + +/* Internal procs */ + +/datum/reagents/proc/get_free_space() // Returns free space. + return maximum_volume - total_volume + +/datum/reagents/proc/get_master_reagent() // Returns reference to the reagent with the biggest volume. + var/the_reagent = null + var/the_volume = 0 + + for(var/datum/reagent/A in reagent_list) + if(A.volume > the_volume) + the_volume = A.volume + the_reagent = A + + return the_reagent + +/datum/reagents/proc/get_master_reagent_name() // Returns the name of the reagent with the biggest volume. + var/the_name = null + var/the_volume = 0 + for(var/datum/reagent/A in reagent_list) + if(A.volume > the_volume) + the_volume = A.volume + the_name = A.name + + return the_name + +/datum/reagents/proc/get_master_reagent_id() // Returns the id of the reagent with the biggest volume. + var/the_id = null + var/the_volume = 0 + for(var/datum/reagent/A in reagent_list) + if(A.volume > the_volume) + the_volume = A.volume + the_id = A.id + + return the_id + +/datum/reagents/proc/update_total() // Updates volume. + total_volume = 0 + for(var/datum/reagent/R in reagent_list) + if(R.volume < MINIMUM_CHEMICAL_VOLUME) + del_reagent(R.id) + else + total_volume += R.volume + return + +/datum/reagents/proc/handle_reactions() + if(QDELETED(my_atom)) + return FALSE + if(my_atom.flags & NOREACT) + return FALSE + var/reaction_occurred + var/list/eligible_reactions = list() + var/list/effect_reactions = list() + do + reaction_occurred = FALSE + for(var/i in reagent_list) + var/datum/reagent/R = i + if(SSchemistry.instant_reactions_by_reagent[R.id]) + eligible_reactions |= SSchemistry.instant_reactions_by_reagent[R.id] + + for(var/i in eligible_reactions) + var/decl/chemical_reaction/C = i + if(C.can_happen(src) && C.process(src)) + effect_reactions |= C + reaction_occurred = TRUE + eligible_reactions.len = 0 + while(reaction_occurred) + for(var/i in effect_reactions) + var/decl/chemical_reaction/C = i + C.post_reaction(src) + update_total() + +/* Holder-to-chemical */ + +/datum/reagents/proc/add_reagent(var/id, var/amount, var/data = null, var/safety = 0) + if(!isnum(amount) || amount <= 0) + return 0 + + update_total() + amount = min(amount, get_free_space()) + + if(istype(my_atom,/obj/item/weapon/reagent_containers/food)) //The following code is targeted specifically at getting allergen reagents into food items, since for the most part they're not applied by default. + var/list/add_reagents = list() + var/totalnum = 0 + + for(var/item in data) //Try to find the ID + var/add_reagent_id = null + if(item in SSchemistry.chemical_reagents) + add_reagent_id = item + else if("[item]juice" in SSchemistry.chemical_reagents) + add_reagent_id = "[item]juice" + if(add_reagent_id) //If we did find it, add it to our list of reagents to add, and add the number to our total. + add_reagents[add_reagent_id] += data[item] + totalnum += data[item] + + if(totalnum) + var/multconst = amount/totalnum //We're going to add these extra reagents so that they share the ratio described, but only add up to 1x the existing amount at the most + for(var/item in add_reagents) + add_reagent(item,add_reagents[item]*multconst) + + + + + for(var/datum/reagent/current in reagent_list) + if(current.id == id) + if(current.id == "blood") + if(LAZYLEN(data) && !isnull(data["species"]) && !isnull(current.data["species"]) && data["species"] != current.data["species"]) // Species bloodtypes are already incompatible, this just stops it from mixing into the one already in a container. + continue + + current.volume += amount + if(!isnull(data)) // For all we know, it could be zero or empty string and meaningful + current.mix_data(data, amount) + update_total() + if(!safety) + handle_reactions() + if(my_atom) + my_atom.on_reagent_change() + return 1 + var/datum/reagent/D = SSchemistry.chemical_reagents[id] + if(D) + var/datum/reagent/R = new D.type() + reagent_list += R + R.holder = src + R.volume = amount + R.initialize_data(data) + update_total() + if(!safety) + handle_reactions() + if(my_atom) + my_atom.on_reagent_change() + return 1 + else + crash_with("[my_atom] attempted to add a reagent called '[id]' which doesn't exist. ([usr])") + return 0 + +/datum/reagents/proc/isolate_reagent(reagent) + for(var/A in reagent_list) + var/datum/reagent/R = A + if(R.id != reagent) + del_reagent(R.id) + update_total() + +/datum/reagents/proc/remove_reagent(var/id, var/amount, var/safety = 0) + if(!isnum(amount)) + return 0 + for(var/datum/reagent/current in reagent_list) + if(current.id == id) + current.volume -= amount // It can go negative, but it doesn't matter + update_total() // Because this proc will delete it then + if(!safety) + handle_reactions() + if(my_atom) + my_atom.on_reagent_change() + return 1 + return 0 + +/datum/reagents/proc/del_reagent(var/id) + for(var/datum/reagent/current in reagent_list) + if (current.id == id) + reagent_list -= current + qdel(current) + update_total() + if(my_atom) + my_atom.on_reagent_change() + return 0 + +/datum/reagents/proc/has_reagent(var/id, var/amount = 0) + for(var/datum/reagent/current in reagent_list) + if(current.id == id) + if(current.volume >= amount) + return 1 + else + return 0 + return 0 + +/datum/reagents/proc/has_any_reagent(var/list/check_reagents) + for(var/datum/reagent/current in reagent_list) + if(current.id in check_reagents) + if(current.volume >= check_reagents[current.id]) + return 1 + else + return 0 + return 0 + +/datum/reagents/proc/has_all_reagents(var/list/check_reagents) + //this only works if check_reagents has no duplicate entries... hopefully okay since it expects an associative list + var/missing = check_reagents.len + for(var/datum/reagent/current in reagent_list) + if(current.id in check_reagents) + if(current.volume >= check_reagents[current.id]) + missing-- + return !missing + +/datum/reagents/proc/clear_reagents() + for(var/datum/reagent/current in reagent_list) + del_reagent(current.id) + return + +/datum/reagents/proc/get_reagent_amount(var/id) + for(var/datum/reagent/current in reagent_list) + if(current.id == id) + return current.volume + return 0 + +/datum/reagents/proc/get_data(var/id) + for(var/datum/reagent/current in reagent_list) + if(current.id == id) + return current.get_data() + return 0 + +/datum/reagents/proc/get_reagents() + . = list() + for(var/datum/reagent/current in reagent_list) + . += "[current.id] ([current.volume])" + return english_list(., "EMPTY", "", ", ", ", ") + +/* Holder-to-holder and similar procs */ + +/datum/reagents/proc/remove_any(var/amount = 1) // Removes up to [amount] of reagents from [src]. Returns actual amount removed. + amount = min(amount, total_volume) + + if(!amount) + return + + var/part = amount / total_volume + + for(var/datum/reagent/current in reagent_list) + var/amount_to_remove = current.volume * part + remove_reagent(current.id, amount_to_remove, 1) + + update_total() + handle_reactions() + return amount + +/datum/reagents/proc/trans_to_holder(var/datum/reagents/target, var/amount = 1, var/multiplier = 1, var/copy = 0) // Transfers [amount] reagents from [src] to [target], multiplying them by [multiplier]. Returns actual amount removed from [src] (not amount transferred to [target]). + if(!target || !istype(target)) + return + + amount = max(0, min(amount, total_volume, target.get_free_space() / multiplier)) + + if(!amount) + return + + var/part = amount / total_volume + + for(var/datum/reagent/current in reagent_list) + var/amount_to_transfer = current.volume * part + target.add_reagent(current.id, amount_to_transfer * multiplier, current.get_data(), safety = 1) // We don't react until everything is in place + if(!copy) + remove_reagent(current.id, amount_to_transfer, 1) + + if(!copy) + handle_reactions() + target.handle_reactions() + return amount + +/* Holder-to-atom and similar procs */ + +//The general proc for applying reagents to things. This proc assumes the reagents are being applied externally, +//not directly injected into the contents. It first calls touch, then the appropriate trans_to_*() or splash_mob(). +//If for some reason touch effects are bypassed (e.g. injecting stuff directly into a reagent container or person), +//call the appropriate trans_to_*() proc. +/datum/reagents/proc/trans_to(var/atom/target, var/amount = 1, var/multiplier = 1, var/copy = 0) + touch(target) //First, handle mere touch effects + + if(ismob(target)) + return splash_mob(target, amount, copy) + if(isturf(target)) + return trans_to_turf(target, amount, multiplier, copy) + if(isobj(target) && target.is_open_container()) + return trans_to_obj(target, amount, multiplier, copy) + return 0 + +//Splashing reagents is messier than trans_to, the target's loc gets some of the reagents as well. +/datum/reagents/proc/splash(var/atom/target, var/amount = 1, var/multiplier = 1, var/copy = 0, var/min_spill=0, var/max_spill=60) + var/spill = 0 + if(!isturf(target) && target.loc) + spill = amount*(rand(min_spill, max_spill)/100) + amount -= spill + if(spill) + splash(target.loc, spill, multiplier, copy, min_spill, max_spill) + + if(!trans_to(target, amount, multiplier, copy)) + touch(target, amount) + +/datum/reagents/proc/trans_type_to(var/target, var/rtype, var/amount = 1) + if (!target) + return + + var/datum/reagent/transfering_reagent = get_reagent(rtype) + + if (istype(target, /atom)) + var/atom/A = target + if (!A.reagents || !A.simulated) + return + + amount = min(amount, transfering_reagent.volume) + + if(!amount) + return + + + var/datum/reagents/F = new /datum/reagents(amount) + var/tmpdata = get_data(rtype) + F.add_reagent(rtype, amount, tmpdata) + remove_reagent(rtype, amount) + + + if (istype(target, /atom)) + return F.trans_to(target, amount) // Let this proc check the atom's type + else if (istype(target, /datum/reagents)) + return F.trans_to_holder(target, amount) + +/datum/reagents/proc/trans_id_to(var/atom/target, var/id, var/amount = 1) + if (!target || !target.reagents) + return + + amount = min(amount, get_reagent_amount(id)) + + if(!amount) + return + + var/datum/reagents/F = new /datum/reagents(amount) + var/tmpdata = get_data(id) + F.add_reagent(id, amount, tmpdata) + remove_reagent(id, amount) + + return F.trans_to(target, amount) // Let this proc check the atom's type + +// When applying reagents to an atom externally, touch() is called to trigger any on-touch effects of the reagent. +// This does not handle transferring reagents to things. +// For example, splashing someone with water will get them wet and extinguish them if they are on fire, +// even if they are wearing an impermeable suit that prevents the reagents from contacting the skin. +/datum/reagents/proc/touch(var/atom/target, var/amount) + if(ismob(target)) + touch_mob(target, amount) + if(isturf(target)) + touch_turf(target, amount) + if(isobj(target)) + touch_obj(target, amount) + return + +/datum/reagents/proc/touch_mob(var/mob/target) + if(!target || !istype(target)) + return + + for(var/datum/reagent/current in reagent_list) + current.touch_mob(target, current.volume) + + update_total() + +/datum/reagents/proc/touch_turf(var/turf/target, var/amount) + if(!target || !istype(target)) + return + + for(var/datum/reagent/current in reagent_list) + current.touch_turf(target, amount) + + update_total() + +/datum/reagents/proc/touch_obj(var/obj/target, var/amount) + if(!target || !istype(target)) + return + + for(var/datum/reagent/current in reagent_list) + current.touch_obj(target, amount) + + update_total() + +// Attempts to place a reagent on the mob's skin. +// Reagents are not guaranteed to transfer to the target. +// Do not call this directly, call trans_to() instead. +/datum/reagents/proc/splash_mob(var/mob/target, var/amount = 1, var/copy = 0) + var/perm = 1 + if(isliving(target)) //will we ever even need to tranfer reagents to non-living mobs? + var/mob/living/L = target + if(ishuman(L)) + var/mob/living/carbon/human/H = L + if(H.check_shields(0, null, null, null, "the spray") == 1) //If they block the spray, it does nothing. + amount = 0 + perm = L.reagent_permeability() + return trans_to_mob(target, amount, CHEM_TOUCH, perm, copy) + +/datum/reagents/proc/trans_to_mob(var/mob/target, var/amount = 1, var/type = CHEM_BLOOD, var/multiplier = 1, var/copy = 0) // Transfer after checking into which holder... + if(!target || !istype(target)) + return + if(iscarbon(target)) + var/mob/living/carbon/C = target + if(type == CHEM_BLOOD) + var/datum/reagents/R = C.reagents + return trans_to_holder(R, amount, multiplier, copy) + if(type == CHEM_INGEST) + var/datum/reagents/R = C.ingested + return C.ingest(src, R, amount, multiplier, copy) + if(type == CHEM_TOUCH) + var/datum/reagents/R = C.touching + return trans_to_holder(R, amount, multiplier, copy) + else + var/datum/reagents/R = new /datum/reagents(amount) + . = trans_to_holder(R, amount, multiplier, copy) + R.touch_mob(target) + +/datum/reagents/proc/trans_to_turf(var/turf/target, var/amount = 1, var/multiplier = 1, var/copy = 0) // Turfs don't have any reagents (at least, for now). Just touch it. + if(!target) + return + + var/datum/reagents/R = new /datum/reagents(amount * multiplier) + . = trans_to_holder(R, amount, multiplier, copy) + R.touch_turf(target, amount) + return + +/datum/reagents/proc/trans_to_obj(var/obj/target, var/amount = 1, var/multiplier = 1, var/copy = 0) // Objects may or may not; if they do, it's probably a beaker or something and we need to transfer properly; otherwise, just touch. + if(!target) + return + + if(!target.reagents) + var/datum/reagents/R = new /datum/reagents(amount * multiplier) + . = trans_to_holder(R, amount, multiplier, copy) + R.touch_obj(target, amount) + return + + return trans_to_holder(target.reagents, amount, multiplier, copy) + +/* Atom reagent creation - use it all the time */ + +/atom/proc/create_reagents(var/max_vol, var/reagents_type = /datum/reagents) + if(!ispath(reagents_type)) + reagents_type = /datum/reagents + reagents = new reagents_type(max_vol, src) + +// Aurora Cooking Port +/datum/reagents/proc/get_reagent(var/id) // Returns reference to reagent matching passed ID + for(var/datum/reagent/A in reagent_list) + if (A.id == id) + return A + + return null + +//Spreads the contents of this reagent holder all over the vicinity of the target turf. +/datum/reagents/proc/splash_area(var/turf/epicentre, var/range = 3, var/portion = 1.0, var/multiplier = 1, var/copy = 0) + var/list/things = dview(range, epicentre, INVISIBILITY_LIGHTING) + var/list/turfs = list() + for (var/turf/T in things) + turfs += T + if (!turfs.len) + return//Nowhere to splash to, somehow + //Create a temporary holder to hold all the amount that will be spread + var/datum/reagents/R = new /datum/reagents(total_volume * portion * multiplier) + trans_to_holder(R, total_volume * portion, multiplier, copy) + //The exact amount that will be given to each turf + var/turfportion = R.total_volume / turfs.len + for (var/turf/T in turfs) + var/datum/reagents/TR = new /datum/reagents(turfportion) + R.trans_to_holder(TR, turfportion, 1, 0) + TR.splash_turf(T) + qdel(R) + + +//Spreads the contents of this reagent holder all over the target turf, dividing among things in it. +//50% is divided between mobs, 20% between objects, and whatever is left on the turf itself +/datum/reagents/proc/splash_turf(var/turf/T, var/amount = null, var/multiplier = 1, var/copy = 0) + if (isnull(amount)) + amount = total_volume + else + amount = min(amount, total_volume) + if (amount <= 0) + return + var/list/mobs = list() + for (var/mob/M in T) + mobs += M + var/list/objs = list() + for (var/obj/O in T) + objs += O + if (objs.len) + var/objportion = (amount * 0.2) / objs.len + for (var/o in objs) + var/obj/O = o + trans_to(O, objportion, multiplier, copy) + amount = min(amount, total_volume) + if (mobs.len) + var/mobportion = (amount * 0.5) / mobs.len + for (var/m in mobs) + var/mob/M = m + trans_to(M, mobportion, multiplier, copy) + trans_to(T, total_volume, multiplier, copy) + if (total_volume <= 0) + qdel(src) + +/** + * Calls [/datum/reagent/proc/on_update] on every reagent in this holder + * + * Arguments: + * * atom/A - passed to on_update + */ +/datum/reagents/proc/conditional_update(atom/A) + var/list/cached_reagents = reagent_list + for(var/datum/reagent/reagent as anything in cached_reagents) + reagent.on_update(A) + update_total() diff --git a/code/modules/reagents/Chemistry-Machinery.dm b/code/modules/reagents/machinery/chem_master.dm similarity index 58% rename from code/modules/reagents/Chemistry-Machinery.dm rename to code/modules/reagents/machinery/chem_master.dm index b5fe99b0540..3fdca52296a 100644 --- a/code/modules/reagents/Chemistry-Machinery.dm +++ b/code/modules/reagents/machinery/chem_master.dm @@ -1,862 +1,498 @@ -#define SOLID 1 -#define LIQUID 2 -#define GAS 3 - -#define MAX_PILL_SPRITE 24 //max icon state of the pill sprites -#define MAX_BOTTLE_SPRITE 4 //max icon state of the pill sprites -#define MAX_MULTI_AMOUNT 20 // Max number of pills/patches that can be made at once -#define MAX_UNITS_PER_PILL 60 // Max amount of units in a pill -#define MAX_UNITS_PER_PATCH 60 // Max amount of units in a patch -#define MAX_UNITS_PER_BOTTLE 60 // Max amount of units in a bottle (it's volume) -#define MAX_CUSTOM_NAME_LEN 64 // Max length of a custom pill/condiment/whatever - - - - -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -/obj/machinery/chem_master - name = "ChemMaster 3000" - desc = "Used to seperate and package chemicals in to patches, pills, or bottles. Warranty void if used to create Space Drugs." - density = 1 - anchored = 1 - icon = 'icons/obj/chemical.dmi' - icon_state = "mixer0" - circuit = /obj/item/weapon/circuitboard/chem_master - use_power = USE_POWER_IDLE - idle_power_usage = 20 - var/obj/item/weapon/reagent_containers/beaker = null - var/obj/item/weapon/storage/pill_bottle/loaded_pill_bottle = null - var/mode = 0 - var/condi = 0 - var/useramount = 15 // Last used amount - var/pillamount = 10 - var/list/bottle_styles - var/bottlesprite = 1 - var/pillsprite = 1 - var/max_pill_count = 20 - var/printing = FALSE - flags = OPENCONTAINER - clicksound = "button" - -/obj/machinery/chem_master/New() - ..() - var/datum/reagents/R = new/datum/reagents(900) //Just a huge random number so the buffer should (probably) never dump your reagents. - reagents = R //There should be a nano ui thingy to warn of this. - R.my_atom = src - -/obj/machinery/chem_master/ex_act(severity) - switch(severity) - if(1.0) - qdel(src) - return - if(2.0) - if (prob(50)) - qdel(src) - return - -/obj/machinery/chem_master/update_icon() - icon_state = "mixer[beaker ? "1" : "0"]" - -/obj/machinery/chem_master/attackby(var/obj/item/weapon/B as obj, var/mob/user as mob) - - if(istype(B, /obj/item/weapon/reagent_containers/glass) || istype(B, /obj/item/weapon/reagent_containers/food)) - - if(src.beaker) - to_chat(user, "\A [beaker] is already loaded into the machine.") - return - src.beaker = B - user.drop_item() - B.loc = src - to_chat(user, "You add \the [B] to the machine.") - update_icon() - - else if(istype(B, /obj/item/weapon/storage/pill_bottle)) - - if(src.loaded_pill_bottle) - to_chat(user, "A \the [loaded_pill_bottle] s already loaded into the machine.") - return - - src.loaded_pill_bottle = B - user.drop_item() - B.loc = src - to_chat(user, "You add \the [loaded_pill_bottle] into the dispenser slot.") - - else if(default_unfasten_wrench(user, B, 20)) - return - if(default_deconstruction_screwdriver(user, B)) - return - if(default_deconstruction_crowbar(user, B)) - return - - return - -/obj/machinery/chem_master/attack_hand(mob/user as mob) - if(stat & BROKEN) - return - user.set_machine(src) - tgui_interact(user) - -/obj/machinery/chem_master/ui_assets(mob/user) - return list( - get_asset_datum(/datum/asset/chem_master), - ) - -/obj/machinery/chem_master/tgui_interact(mob/user, datum/tgui/ui = null) - ui = SStgui.try_update_ui(user, src, ui) - if(!ui) - ui = new(user, src, "ChemMaster", name) - ui.open() - -/** - * Display the NanoUI window for the chem master. - * - * See NanoUI documentation for details. - */ -/obj/machinery/chem_master/tgui_data(mob/user) - var/list/data = list() - - data["condi"] = condi - - data["loaded_pill_bottle"] = !!loaded_pill_bottle - if(loaded_pill_bottle) - data["loaded_pill_bottle_name"] = loaded_pill_bottle.name - data["loaded_pill_bottle_contents_len"] = loaded_pill_bottle.contents.len - data["loaded_pill_bottle_storage_slots"] = loaded_pill_bottle.max_storage_space - - data["beaker"] = !!beaker - if(beaker) - var/list/beaker_reagents_list = list() - data["beaker_reagents"] = beaker_reagents_list - for(var/datum/reagent/R in beaker.reagents.reagent_list) - beaker_reagents_list[++beaker_reagents_list.len] = list("name" = R.name, "volume" = R.volume, "description" = R.description, "id" = R.id) - - var/list/buffer_reagents_list = list() - data["buffer_reagents"] = buffer_reagents_list - for(var/datum/reagent/R in reagents.reagent_list) - buffer_reagents_list[++buffer_reagents_list.len] = list("name" = R.name, "volume" = R.volume, "id" = R.id, "description" = R.description) - - data["pillsprite"] = pillsprite - data["bottlesprite"] = bottlesprite - data["mode"] = mode - data["printing"] = printing - - // Transfer modal information if there is one - data["modal"] = tgui_modal_data(src) - - return data - -/** - * Called in tgui_act() to process modal actions - * - * Arguments: - * * action - The action passed by tgui - * * params - The params passed by tgui - */ -/obj/machinery/chem_master/proc/tgui_act_modal(action, params, datum/tgui/ui, datum/tgui_state/state) - . = TRUE - var/id = params["id"] // The modal's ID - var/list/arguments = istext(params["arguments"]) ? json_decode(params["arguments"]) : params["arguments"] - switch(tgui_modal_act(src, action, params)) - if(TGUI_MODAL_OPEN) - switch(id) - if("analyze") - var/idx = text2num(arguments["idx"]) || 0 - var/from_beaker = text2num(arguments["beaker"]) || FALSE - var/reagent_list = from_beaker ? beaker.reagents.reagent_list : reagents.reagent_list - if(idx < 1 || idx > length(reagent_list)) - return - - var/datum/reagent/R = reagent_list[idx] - var/list/result = list("idx" = idx, "name" = R.name, "desc" = R.description) - if(!condi && istype(R, /datum/reagent/blood)) - var/datum/reagent/blood/B = R - result["blood_type"] = B.data["blood_type"] - result["blood_dna"] = B.data["blood_DNA"] - - arguments["analysis"] = result - tgui_modal_message(src, id, "", null, arguments) - // if("change_pill_bottle_style") - // if(!loaded_pill_bottle) - // return - // if(!pill_bottle_wrappers) - // pill_bottle_wrappers = list( - // "CLEAR" = "Default", - // COLOR_RED = "Red", - // COLOR_GREEN = "Green", - // COLOR_PALE_BTL_GREEN = "Pale green", - // COLOR_BLUE = "Blue", - // COLOR_CYAN_BLUE = "Light blue", - // COLOR_TEAL = "Teal", - // COLOR_YELLOW = "Yellow", - // COLOR_ORANGE = "Orange", - // COLOR_PINK = "Pink", - // COLOR_MAROON = "Brown" - // ) - // var/current = pill_bottle_wrappers[loaded_pill_bottle.wrapper_color] || "Default" - // tgui_modal_choice(src, id, "Please select a pill bottle wrapper:", null, arguments, current, pill_bottle_wrappers) - if("addcustom") - if(!beaker || !beaker.reagents.total_volume) - return - tgui_modal_input(src, id, "Please enter the amount to transfer to buffer:", null, arguments, useramount) - if("removecustom") - if(!reagents.total_volume) - return - tgui_modal_input(src, id, "Please enter the amount to transfer to [mode ? "beaker" : "disposal"]:", null, arguments, useramount) - if("create_condi_pack") - if(!condi || !reagents.total_volume) - return - tgui_modal_input(src, id, "Please name your new condiment pack:", null, arguments, reagents.get_master_reagent_name(), MAX_CUSTOM_NAME_LEN) - if("create_pill") - if(condi || !reagents.total_volume) - return - var/num = round(text2num(arguments["num"] || 1)) - if(!num) - return - arguments["num"] = num - var/amount_per_pill = CLAMP(reagents.total_volume / num, 0, MAX_UNITS_PER_PILL) - var/default_name = "[reagents.get_master_reagent_name()] ([amount_per_pill]u)" - var/pills_text = num == 1 ? "new pill" : "[num] new pills" - tgui_modal_input(src, id, "Please name your [pills_text]:", null, arguments, default_name, MAX_CUSTOM_NAME_LEN) - if("create_pill_multiple") - if(condi || !reagents.total_volume) - return - tgui_modal_input(src, id, "Please enter the amount of pills to make (max [MAX_MULTI_AMOUNT] at a time):", null, arguments, pillamount, 5) - if("change_pill_style") - var/list/choices = list() - for(var/i = 1 to MAX_PILL_SPRITE) - choices += "pill[i].png" - tgui_modal_bento(src, id, "Please select the new style for pills:", null, arguments, pillsprite, choices) - if("create_patch") - if(condi || !reagents.total_volume) - return - var/num = round(text2num(arguments["num"] || 1)) - if(!num) - return - arguments["num"] = num - var/amount_per_patch = CLAMP(reagents.total_volume / num, 0, MAX_UNITS_PER_PATCH) - var/default_name = "[reagents.get_master_reagent_name()] ([amount_per_patch]u)" - var/patches_text = num == 1 ? "new patch" : "[num] new patches" - tgui_modal_input(src, id, "Please name your [patches_text]:", null, arguments, default_name, MAX_CUSTOM_NAME_LEN) - if("create_patch_multiple") - if(condi || !reagents.total_volume) - return - tgui_modal_input(src, id, "Please enter the amount of patches to make (max [MAX_MULTI_AMOUNT] at a time):", null, arguments, pillamount, 5) - if("create_bottle") - if(condi || !reagents.total_volume) - return - var/num = round(text2num(arguments["num"] || 1)) - if(!num) - return - arguments["num"] = num - var/amount_per_bottle = CLAMP(reagents.total_volume / num, 0, MAX_UNITS_PER_BOTTLE) - var/default_name = "[reagents.get_master_reagent_name()]" - var/bottles_text = num == 1 ? "new bottle" : "[num] new bottles" - tgui_modal_input(src, id, "Please name your [bottles_text] ([amount_per_bottle]u in bottle):", null, arguments, default_name, MAX_CUSTOM_NAME_LEN) - if("create_bottle_multiple") - if(condi || !reagents.total_volume) - return - tgui_modal_input(src, id, "Please enter the amount of bottles to make (max [MAX_MULTI_AMOUNT] at a time):", null, arguments, pillamount, 5) - if("change_bottle_style") - var/list/choices = list() - for(var/i = 1 to MAX_BOTTLE_SPRITE) - choices += "bottle-[i].png" - tgui_modal_bento(src, id, "Please select the new style for bottles:", null, arguments, bottlesprite, choices) - else - return FALSE - if(TGUI_MODAL_ANSWER) - var/answer = params["answer"] - switch(id) - // if("change_pill_bottle_style") - // if(!pill_bottle_wrappers || !loaded_pill_bottle) // wat? - // return - // var/color = "CLEAR" - // for(var/col in pill_bottle_wrappers) - // var/col_name = pill_bottle_wrappers[col] - // if(col_name == answer) - // color = col - // break - // if(length(color) && color != "CLEAR") - // loaded_pill_bottle.wrapper_color = color - // loaded_pill_bottle.apply_wrap() - // else - // loaded_pill_bottle.wrapper_color = null - // loaded_pill_bottle.cut_overlays() - if("addcustom") - var/amount = isgoodnumber(text2num(answer)) - if(!amount || !arguments["id"]) - return - tgui_act("add", list("id" = arguments["id"], "amount" = amount), ui, state) - if("removecustom") - var/amount = isgoodnumber(text2num(answer)) - if(!amount || !arguments["id"]) - return - tgui_act("remove", list("id" = arguments["id"], "amount" = amount), ui, state) - if("create_condi_pack") - if(!condi || !reagents.total_volume) - return - if(!length(answer)) - answer = reagents.get_master_reagent_name() - var/obj/item/weapon/reagent_containers/pill/P = new(loc) - P.name = "[answer] pack" - P.desc = "A small condiment pack. The label says it contains [answer]." - P.icon_state = "bouilloncube"//Reskinned monkey cube - reagents.trans_to_obj(P, 10) - if("create_pill") - if(condi || !reagents.total_volume) - return - var/count = CLAMP(round(text2num(arguments["num"]) || 0), 0, MAX_MULTI_AMOUNT) - if(!count) - return - - if(!length(answer)) - answer = reagents.get_master_reagent_name() - var/amount_per_pill = CLAMP(reagents.total_volume / count, 0, MAX_UNITS_PER_PILL) - while(count--) - if(reagents.total_volume <= 0) - to_chat(usr, "Not enough reagents to create these pills!") - return - - var/obj/item/weapon/reagent_containers/pill/P = new(loc) - P.name = "[answer] pill" - P.pixel_x = rand(-7, 7) // Random position - P.pixel_y = rand(-7, 7) - P.icon_state = "pill[pillsprite]" - if(P.icon_state in list("pill1", "pill2", "pill3", "pill4")) // if using greyscale, take colour from reagent - P.color = reagents.get_color() - reagents.trans_to_obj(P, amount_per_pill) - // Load the pills in the bottle if there's one loaded - if(istype(loaded_pill_bottle) && length(loaded_pill_bottle.contents) < loaded_pill_bottle.max_storage_space) - P.forceMove(loaded_pill_bottle) - if("create_pill_multiple") - if(condi || !reagents.total_volume) - return - tgui_act("modal_open", list("id" = "create_pill", "arguments" = list("num" = answer)), ui, state) - if("change_pill_style") - var/new_style = CLAMP(text2num(answer) || 0, 0, MAX_PILL_SPRITE) - if(!new_style) - return - pillsprite = new_style - if("create_patch") - if(condi || !reagents.total_volume) - return - var/count = CLAMP(round(text2num(arguments["num"]) || 0), 0, MAX_MULTI_AMOUNT) - if(!count) - return - - if(!length(answer)) - answer = reagents.get_master_reagent_name() - var/amount_per_patch = CLAMP(reagents.total_volume / count, 0, MAX_UNITS_PER_PATCH) - // var/is_medical_patch = chemical_safety_check(reagents) - while(count--) - if(reagents.total_volume <= 0) - to_chat(usr, "Not enough reagents to create these patches!") - return - - var/obj/item/weapon/reagent_containers/pill/patch/P = new(loc) - P.name = "[answer] patch" - P.pixel_x = rand(-7, 7) // random position - P.pixel_y = rand(-7, 7) - reagents.trans_to_obj(P, amount_per_patch) - // if(is_medical_patch) - // P.instant_application = TRUE - // P.icon_state = "bandaid_med" - if("create_patch_multiple") - if(condi || !reagents.total_volume) - return - tgui_act("modal_open", list("id" = "create_patch", "arguments" = list("num" = answer)), ui, state) - if("create_bottle") - if(condi || !reagents.total_volume) - return - var/count = CLAMP(round(text2num(arguments["num"]) || 0), 0, MAX_MULTI_AMOUNT) - if(!count) - return - - if(!length(answer)) - answer = reagents.get_master_reagent_name() - var/amount_per_bottle = CLAMP(reagents.total_volume / count, 0, MAX_UNITS_PER_BOTTLE) - while(count--) - if(reagents.total_volume <= 0) - to_chat(usr, "Not enough reagents to create these bottles!") - return - var/obj/item/weapon/reagent_containers/glass/bottle/P = new(loc) - P.name = "[answer] bottle" - P.pixel_x = rand(-7, 7) // random position - P.pixel_y = rand(-7, 7) - P.icon_state = "bottle-[bottlesprite]" || "bottle-1" - reagents.trans_to_obj(P, amount_per_bottle) - P.update_icon() - if("create_bottle_multiple") - if(condi || !reagents.total_volume) - return - tgui_act("modal_open", list("id" = "create_bottle", "arguments" = list("num" = answer)), ui, state) - if("change_bottle_style") - var/new_style = CLAMP(text2num(answer) || 0, 0, MAX_BOTTLE_SPRITE) - if(!new_style) - return - bottlesprite = new_style - else - return FALSE - else - return FALSE - -/obj/machinery/chem_master/tgui_act(action, params, datum/tgui/ui, datum/tgui_state/state) - if(..()) - return TRUE - - if(tgui_act_modal(action, params, ui, state)) - return TRUE - - add_fingerprint(usr) - usr.set_machine(src) - - . = TRUE - switch(action) - if("toggle") - mode = !mode - if("ejectp") - if(loaded_pill_bottle) - loaded_pill_bottle.forceMove(get_turf(src)) - if(Adjacent(usr) && !issilicon(usr)) - usr.put_in_hands(loaded_pill_bottle) - loaded_pill_bottle = null - if("print") - if(printing || condi) - return - - var/idx = text2num(params["idx"]) || 0 - var/from_beaker = text2num(params["beaker"]) || FALSE - var/reagent_list = from_beaker ? beaker.reagents.reagent_list : reagents.reagent_list - if(idx < 1 || idx > length(reagent_list)) - return - - var/datum/reagent/R = reagent_list[idx] - - printing = TRUE - visible_message("[src] rattles and prints out a sheet of paper.") - // playsound(loc, 'sound/goonstation/machines/printer_dotmatrix.ogg', 50, 1) - - var/obj/item/weapon/paper/P = new /obj/item/weapon/paper(loc) - P.info = "
Chemical Analysis

" - P.info += "Time of analysis: [worldtime2stationtime(world.time)]

" - P.info += "Chemical name: [R.name]
" - if(istype(R, /datum/reagent/blood)) - var/datum/reagent/blood/B = R - P.info += "Description: N/A
Blood Type: [B.data["blood_type"]]
DNA: [B.data["blood_DNA"]]" - else - P.info += "Description: [R.description]" - P.info += "

Notes:
" - P.name = "Chemical Analysis - [R.name]" - spawn(50) - printing = FALSE - else - . = FALSE - - if(. || !beaker) - return - - . = TRUE - var/datum/reagents/R = beaker.reagents - switch(action) - if("add") - var/id = params["id"] - var/amount = text2num(params["amount"]) - if(!id || !amount) - return - R.trans_id_to(src, id, amount) - if("remove") - var/id = params["id"] - var/amount = text2num(params["amount"]) - if(!id || !amount) - return - if(mode) - reagents.trans_id_to(beaker, id, amount) - else - reagents.remove_reagent(id, amount) - if("eject") - if(!beaker) - return - beaker.forceMove(get_turf(src)) - if(Adjacent(usr) && !issilicon(usr)) - usr.put_in_hands(beaker) - beaker = null - reagents.clear_reagents() - update_icon() - if("create_condi_bottle") - if(!condi || !reagents.total_volume) - return - var/obj/item/weapon/reagent_containers/food/condiment/P = new(loc) - reagents.trans_to_obj(P, 50) - else - return FALSE - -/obj/machinery/chem_master/attack_ai(mob/user) - return attack_hand(user) - -/obj/machinery/chem_master/proc/isgoodnumber(num) - if(isnum(num)) - if(num > 200) - num = 200 - else if(num < 0) - num = 1 - return num - else - return FALSE - -// /obj/machinery/chem_master/proc/chemical_safety_check(datum/reagents/R) -// var/all_safe = TRUE -// for(var/datum/reagent/A in R.reagent_list) -// if(!GLOB.safe_chem_list.Find(A.id)) -// all_safe = FALSE -// return all_safe - -/obj/machinery/chem_master/condimaster - name = "CondiMaster 3000" - condi = 1 - -//////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////// -/obj/machinery/reagentgrinder - - name = "All-In-One Grinder" - desc = "Grinds stuff into itty bitty bits." - icon = 'icons/obj/kitchen.dmi' - icon_state = "juicer1" - density = 0 - anchored = 0 - use_power = USE_POWER_IDLE - idle_power_usage = 5 - active_power_usage = 100 - circuit = /obj/item/weapon/circuitboard/grinder - var/inuse = 0 - var/obj/item/weapon/reagent_containers/beaker = null - var/limit = 10 - var/list/holdingitems = list() - var/list/sheet_reagents = list( //have a number of reageents divisible by REAGENTS_PER_SHEET (default 20) unless you like decimals, - /obj/item/stack/material/iron = list("iron"), - /obj/item/stack/material/uranium = list("uranium"), - /obj/item/stack/material/phoron = list("phoron"), - /obj/item/stack/material/gold = list("gold"), - /obj/item/stack/material/silver = list("silver"), - /obj/item/stack/material/platinum = list("platinum"), - /obj/item/stack/material/mhydrogen = list("hydrogen"), - /obj/item/stack/material/steel = list("iron", "carbon"), - /obj/item/stack/material/plasteel = list("iron", "iron", "carbon", "carbon", "platinum"), //8 iron, 8 carbon, 4 platinum, - /obj/item/stack/material/snow = list("water"), - /obj/item/stack/material/sandstone = list("silicon", "oxygen"), - /obj/item/stack/material/glass = list("silicon"), - /obj/item/stack/material/glass/phoronglass = list("platinum", "silicon", "silicon", "silicon"), //5 platinum, 15 silicon, - ) - - var/static/radial_examine = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_examine") - var/static/radial_eject = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_eject") - var/static/radial_grind = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_grind") - // var/static/radial_juice = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_juice") - // var/static/radial_mix = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_mix") - -/obj/machinery/reagentgrinder/Initialize() - . = ..() - beaker = new /obj/item/weapon/reagent_containers/glass/beaker/large(src) - default_apply_parts() - -/obj/machinery/reagentgrinder/examine(mob/user) - . = ..() - if(!in_range(user, src) && !issilicon(user) && !isobserver(user)) - . += "You're too far away to examine [src]'s contents and display!" - return - - if(inuse) - . += "\The [src] is operating." - return - - if(beaker || length(holdingitems)) - . += "\The [src] contains:" - if(beaker) - . += "- \A [beaker]." - for(var/i in holdingitems) - var/obj/item/O = i - . += "- \A [O.name]." - - if(!(stat & (NOPOWER|BROKEN))) - . += "The status display reads:\n" - if(beaker) - for(var/datum/reagent/R in beaker.reagents.reagent_list) - . += "- [R.volume] units of [R.name]." - -/obj/machinery/reagentgrinder/update_icon() - icon_state = "juicer"+num2text(!isnull(beaker)) - return - -/obj/machinery/reagentgrinder/attackby(var/obj/item/O as obj, var/mob/user as mob) - if(beaker) - if(default_deconstruction_screwdriver(user, O)) - return - if(default_deconstruction_crowbar(user, O)) - return - - //vorestation edit start - for solargrubs - if (istype(O, /obj/item/device/multitool)) - return ..() - //vorestation edit end - - - if (istype(O,/obj/item/weapon/reagent_containers/glass) || \ - istype(O,/obj/item/weapon/reagent_containers/food/drinks/glass2) || \ - istype(O,/obj/item/weapon/reagent_containers/food/drinks/shaker)) - - if (beaker) - return 1 - else - src.beaker = O - user.drop_item() - O.loc = src - update_icon() - src.updateUsrDialog() - return 0 - - if(holdingitems && holdingitems.len >= limit) - to_chat(user, "The machine cannot hold anymore items.") - return 1 - - if(!istype(O)) - return - - if(istype(O,/obj/item/weapon/storage/bag/plants)) - var/obj/item/weapon/storage/bag/plants/bag = O - var/failed = 1 - for(var/obj/item/G in O.contents) - if(!G.reagents || !G.reagents.total_volume) - continue - failed = 0 - bag.remove_from_storage(G, src) - holdingitems += G - if(holdingitems && holdingitems.len >= limit) - break - - if(failed) - to_chat(user, "Nothing in the plant bag is usable.") - return 1 - - if(!O.contents.len) - to_chat(user, "You empty \the [O] into \the [src].") - else - to_chat(user, "You fill \the [src] from \the [O].") - - src.updateUsrDialog() - return 0 - - if(istype(O,/obj/item/weapon/gripper)) - var/obj/item/weapon/gripper/B = O //B, for Borg. - if(!B.wrapped) - to_chat(user, "\The [B] is not holding anything.") - return 0 - else - var/B_held = B.wrapped - to_chat(user, "You use \the [B] to load \the [src] with \the [B_held].") - - return 0 - - if(!sheet_reagents[O.type] && (!O.reagents || !O.reagents.total_volume)) - to_chat(user, "\The [O] is not suitable for blending.") - return 1 - - user.remove_from_mob(O) - O.loc = src - holdingitems += O - return 0 - -/obj/machinery/reagentgrinder/AltClick(mob/user) - . = ..() - if(user.incapacitated() || !Adjacent(user)) - return - replace_beaker(user) - -/obj/machinery/reagentgrinder/attack_hand(mob/user as mob) - interact(user) - -/obj/machinery/reagentgrinder/interact(mob/user as mob) // The microwave Menu //I am reasonably certain that this is not a microwave - if(inuse || user.incapacitated()) - return - - var/list/options = list() - - if(beaker || length(holdingitems)) - options["eject"] = radial_eject - - if(isAI(user)) - if(stat & NOPOWER) - return - options["examine"] = radial_examine - - // if there is no power or it's broken, the procs will fail but the buttons will still show - if(length(holdingitems)) - options["grind"] = radial_grind - - var/choice - if(length(options) < 1) - return - if(length(options) == 1) - for(var/key in options) - choice = key - else - choice = show_radial_menu(user, src, options, require_near = !issilicon(user)) - - // post choice verification - if(inuse || (isAI(user) && stat & NOPOWER) || user.incapacitated()) - return - - switch(choice) - if("eject") - eject(user) - if("grind") - grind(user) - if("examine") - examine(user) - -/obj/machinery/reagentgrinder/proc/eject(mob/user) - if(user.incapacitated()) - return - for(var/obj/item/O in holdingitems) - O.loc = src.loc - holdingitems -= O - holdingitems.Cut() - if(beaker) - replace_beaker(user) - -/obj/machinery/reagentgrinder/proc/grind() - - power_change() - if(stat & (NOPOWER|BROKEN)) - return - - // Sanity check. - if (!beaker || (beaker && beaker.reagents.total_volume >= beaker.reagents.maximum_volume)) - return - - playsound(src, 'sound/machines/blender.ogg', 50, 1) - inuse = 1 - - // Reset the machine. - spawn(60) - inuse = 0 - - // Process. - for (var/obj/item/O in holdingitems) - - var/remaining_volume = beaker.reagents.maximum_volume - beaker.reagents.total_volume - if(remaining_volume <= 0) - break - - if(sheet_reagents[O.type]) - var/obj/item/stack/stack = O - if(istype(stack)) - var/list/sheet_components = sheet_reagents[stack.type] - var/amount_to_take = max(0,min(stack.amount,round(remaining_volume/REAGENTS_PER_SHEET))) - if(amount_to_take) - stack.use(amount_to_take) - if(QDELETED(stack)) - holdingitems -= stack - if(islist(sheet_components)) - amount_to_take = (amount_to_take/(sheet_components.len)) - for(var/i in sheet_components) - beaker.reagents.add_reagent(i, (amount_to_take*REAGENTS_PER_SHEET)) - else - beaker.reagents.add_reagent(sheet_components, (amount_to_take*REAGENTS_PER_SHEET)) - continue - - if(O.reagents) - O.reagents.trans_to_obj(beaker, min(O.reagents.total_volume, remaining_volume)) - if(O.reagents.total_volume == 0) - holdingitems -= O - qdel(O) - if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break - -/obj/machinery/reagentgrinder/proc/replace_beaker(mob/living/user, obj/item/weapon/reagent_containers/new_beaker) - if(!user) - return FALSE - if(beaker) - if(!user.incapacitated() && Adjacent(user)) - user.put_in_hands(beaker) - else - beaker.forceMove(drop_location()) - beaker = null - if(new_beaker) - beaker = new_beaker - update_icon() - return TRUE - -/////////////// -/////////////// -// Detects reagents inside most containers, and acts as an infinite identification system for reagent-based unidentified objects. - -/obj/machinery/chemical_analyzer - name = "chem analyzer" - desc = "Used to precisely scan chemicals and other liquids inside various containers. \ - It may also identify the liquid contents of unknown objects." - description_info = "This machine will try to tell you what reagents are inside of something capable of holding reagents. \ - It is also used to 'identify' specific reagent-based objects with their properties obscured from inspection by normal means." - icon = 'icons/obj/chemical.dmi' - icon_state = "chem_analyzer" - density = TRUE - anchored = TRUE - use_power = TRUE - idle_power_usage = 20 - clicksound = "button" - var/analyzing = FALSE - -/obj/machinery/chemical_analyzer/update_icon() - icon_state = "chem_analyzer[analyzing ? "-working":""]" - -/obj/machinery/chemical_analyzer/attackby(obj/item/I, mob/living/user) - if(!istype(I)) - return ..() - - if(default_deconstruction_screwdriver(user, I)) - return - if(default_deconstruction_crowbar(user, I)) - return - - if(istype(I,/obj/item/weapon/reagent_containers)) - analyzing = TRUE - update_icon() - to_chat(user, span("notice", "Analyzing \the [I], please stand by...")) - - if(!do_after(user, 2 SECONDS, src)) - to_chat(user, span("warning", "Sample moved outside of scan range, please try again and remain still.")) - analyzing = FALSE - update_icon() - return - - // First, identify it if it isn't already. - if(!I.is_identified(IDENTITY_FULL)) - var/datum/identification/ID = I.identity - if(ID.identification_type == IDENTITY_TYPE_CHEMICAL) // This only solves chemical-based mysteries. - I.identify(IDENTITY_FULL, user) - - // Now tell us everything that is inside. - if(I.reagents && I.reagents.reagent_list.len) - to_chat(user, "
") // To add padding between regular chat and the output. - for(var/datum/reagent/R in I.reagents.reagent_list) - if(!R.name) - continue - to_chat(user, span("notice", "Contains [R.volume]u of [R.name].
[R.description]
")) - - // Last, unseal it if it's an autoinjector. - if(istype(I,/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector) && !(I.flags & OPENCONTAINER)) - I.flags |= OPENCONTAINER - to_chat(user, span("notice", "Sample container unsealed.
")) - - to_chat(user, span("notice", "Scanning of \the [I] complete.")) - analyzing = FALSE - update_icon() - return - -#undef MAX_PILL_SPRITE -#undef MAX_BOTTLE_SPRITE -#undef MAX_MULTI_AMOUNT -#undef MAX_UNITS_PER_PILL -#undef MAX_UNITS_PER_PATCH -#undef MAX_UNITS_PER_BOTTLE -#undef MAX_CUSTOM_NAME_LEN +/obj/machinery/chem_master + name = "ChemMaster 3000" + desc = "Used to seperate and package chemicals in to patches, pills, or bottles. Warranty void if used to create Space Drugs." + density = 1 + anchored = 1 + icon = 'icons/obj/chemical.dmi' + icon_state = "mixer0" + circuit = /obj/item/weapon/circuitboard/chem_master + use_power = USE_POWER_IDLE + idle_power_usage = 20 + var/obj/item/weapon/reagent_containers/beaker = null + var/obj/item/weapon/storage/pill_bottle/loaded_pill_bottle = null + var/mode = 0 + var/condi = 0 + var/useramount = 15 // Last used amount + var/pillamount = 10 + var/list/bottle_styles + var/bottlesprite = 1 + var/pillsprite = 1 + var/max_pill_count = 20 + var/printing = FALSE + flags = OPENCONTAINER + clicksound = "button" + +/obj/machinery/chem_master/New() + ..() + var/datum/reagents/R = new/datum/reagents(900) //Just a huge random number so the buffer should (probably) never dump your reagents. + reagents = R //There should be a nano ui thingy to warn of this. + R.my_atom = src + +/obj/machinery/chem_master/ex_act(severity) + switch(severity) + if(1.0) + qdel(src) + return + if(2.0) + if (prob(50)) + qdel(src) + return + +/obj/machinery/chem_master/update_icon() + icon_state = "mixer[beaker ? "1" : "0"]" + +/obj/machinery/chem_master/attackby(var/obj/item/weapon/B as obj, var/mob/user as mob) + + if(istype(B, /obj/item/weapon/reagent_containers/glass) || istype(B, /obj/item/weapon/reagent_containers/food)) + + if(src.beaker) + to_chat(user, "\A [beaker] is already loaded into the machine.") + return + src.beaker = B + user.drop_item() + B.loc = src + to_chat(user, "You add \the [B] to the machine.") + update_icon() + + else if(istype(B, /obj/item/weapon/storage/pill_bottle)) + + if(src.loaded_pill_bottle) + to_chat(user, "A \the [loaded_pill_bottle] s already loaded into the machine.") + return + + src.loaded_pill_bottle = B + user.drop_item() + B.loc = src + to_chat(user, "You add \the [loaded_pill_bottle] into the dispenser slot.") + + else if(default_unfasten_wrench(user, B, 20)) + return + if(default_deconstruction_screwdriver(user, B)) + return + if(default_deconstruction_crowbar(user, B)) + return + + return + +/obj/machinery/chem_master/attack_hand(mob/user as mob) + if(stat & BROKEN) + return + user.set_machine(src) + tgui_interact(user) + +/obj/machinery/chem_master/ui_assets(mob/user) + return list( + get_asset_datum(/datum/asset/chem_master), + ) + +/obj/machinery/chem_master/tgui_interact(mob/user, datum/tgui/ui = null) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "ChemMaster", name) + ui.open() + +/** + * Display the NanoUI window for the chem master. + * + * See NanoUI documentation for details. + */ +/obj/machinery/chem_master/tgui_data(mob/user) + var/list/data = list() + + data["condi"] = condi + + data["loaded_pill_bottle"] = !!loaded_pill_bottle + if(loaded_pill_bottle) + data["loaded_pill_bottle_name"] = loaded_pill_bottle.name + data["loaded_pill_bottle_contents_len"] = loaded_pill_bottle.contents.len + data["loaded_pill_bottle_storage_slots"] = loaded_pill_bottle.max_storage_space + + data["beaker"] = !!beaker + if(beaker) + var/list/beaker_reagents_list = list() + data["beaker_reagents"] = beaker_reagents_list + for(var/datum/reagent/R in beaker.reagents.reagent_list) + beaker_reagents_list[++beaker_reagents_list.len] = list("name" = R.name, "volume" = R.volume, "description" = R.description, "id" = R.id) + + var/list/buffer_reagents_list = list() + data["buffer_reagents"] = buffer_reagents_list + for(var/datum/reagent/R in reagents.reagent_list) + buffer_reagents_list[++buffer_reagents_list.len] = list("name" = R.name, "volume" = R.volume, "id" = R.id, "description" = R.description) + + data["pillsprite"] = pillsprite + data["bottlesprite"] = bottlesprite + data["mode"] = mode + data["printing"] = printing + + // Transfer modal information if there is one + data["modal"] = tgui_modal_data(src) + + return data + +/** + * Called in tgui_act() to process modal actions + * + * Arguments: + * * action - The action passed by tgui + * * params - The params passed by tgui + */ +/obj/machinery/chem_master/proc/tgui_act_modal(action, params, datum/tgui/ui, datum/tgui_state/state) + . = TRUE + var/id = params["id"] // The modal's ID + var/list/arguments = istext(params["arguments"]) ? json_decode(params["arguments"]) : params["arguments"] + switch(tgui_modal_act(src, action, params)) + if(TGUI_MODAL_OPEN) + switch(id) + if("analyze") + var/idx = text2num(arguments["idx"]) || 0 + var/from_beaker = text2num(arguments["beaker"]) || FALSE + var/reagent_list = from_beaker ? beaker.reagents.reagent_list : reagents.reagent_list + if(idx < 1 || idx > length(reagent_list)) + return + + var/datum/reagent/R = reagent_list[idx] + var/list/result = list("idx" = idx, "name" = R.name, "desc" = R.description) + if(!condi && istype(R, /datum/reagent/blood)) + var/datum/reagent/blood/B = R + result["blood_type"] = B.data["blood_type"] + result["blood_dna"] = B.data["blood_DNA"] + + arguments["analysis"] = result + tgui_modal_message(src, id, "", null, arguments) + // if("change_pill_bottle_style") + // if(!loaded_pill_bottle) + // return + // if(!pill_bottle_wrappers) + // pill_bottle_wrappers = list( + // "CLEAR" = "Default", + // COLOR_RED = "Red", + // COLOR_GREEN = "Green", + // COLOR_PALE_BTL_GREEN = "Pale green", + // COLOR_BLUE = "Blue", + // COLOR_CYAN_BLUE = "Light blue", + // COLOR_TEAL = "Teal", + // COLOR_YELLOW = "Yellow", + // COLOR_ORANGE = "Orange", + // COLOR_PINK = "Pink", + // COLOR_MAROON = "Brown" + // ) + // var/current = pill_bottle_wrappers[loaded_pill_bottle.wrapper_color] || "Default" + // tgui_modal_choice(src, id, "Please select a pill bottle wrapper:", null, arguments, current, pill_bottle_wrappers) + if("addcustom") + if(!beaker || !beaker.reagents.total_volume) + return + tgui_modal_input(src, id, "Please enter the amount to transfer to buffer:", null, arguments, useramount) + if("removecustom") + if(!reagents.total_volume) + return + tgui_modal_input(src, id, "Please enter the amount to transfer to [mode ? "beaker" : "disposal"]:", null, arguments, useramount) + if("create_condi_pack") + if(!condi || !reagents.total_volume) + return + tgui_modal_input(src, id, "Please name your new condiment pack:", null, arguments, reagents.get_master_reagent_name(), MAX_CUSTOM_NAME_LEN) + if("create_pill") + if(condi || !reagents.total_volume) + return + var/num = round(text2num(arguments["num"] || 1)) + if(!num) + return + arguments["num"] = num + var/amount_per_pill = CLAMP(reagents.total_volume / num, 0, MAX_UNITS_PER_PILL) + var/default_name = "[reagents.get_master_reagent_name()] ([amount_per_pill]u)" + var/pills_text = num == 1 ? "new pill" : "[num] new pills" + tgui_modal_input(src, id, "Please name your [pills_text]:", null, arguments, default_name, MAX_CUSTOM_NAME_LEN) + if("create_pill_multiple") + if(condi || !reagents.total_volume) + return + tgui_modal_input(src, id, "Please enter the amount of pills to make (max [MAX_MULTI_AMOUNT] at a time):", null, arguments, pillamount, 5) + if("change_pill_style") + var/list/choices = list() + for(var/i = 1 to MAX_PILL_SPRITE) + choices += "pill[i].png" + tgui_modal_bento(src, id, "Please select the new style for pills:", null, arguments, pillsprite, choices) + if("create_patch") + if(condi || !reagents.total_volume) + return + var/num = round(text2num(arguments["num"] || 1)) + if(!num) + return + arguments["num"] = num + var/amount_per_patch = CLAMP(reagents.total_volume / num, 0, MAX_UNITS_PER_PATCH) + var/default_name = "[reagents.get_master_reagent_name()] ([amount_per_patch]u)" + var/patches_text = num == 1 ? "new patch" : "[num] new patches" + tgui_modal_input(src, id, "Please name your [patches_text]:", null, arguments, default_name, MAX_CUSTOM_NAME_LEN) + if("create_patch_multiple") + if(condi || !reagents.total_volume) + return + tgui_modal_input(src, id, "Please enter the amount of patches to make (max [MAX_MULTI_AMOUNT] at a time):", null, arguments, pillamount, 5) + if("create_bottle") + if(condi || !reagents.total_volume) + return + var/num = round(text2num(arguments["num"] || 1)) + if(!num) + return + arguments["num"] = num + var/amount_per_bottle = CLAMP(reagents.total_volume / num, 0, MAX_UNITS_PER_BOTTLE) + var/default_name = "[reagents.get_master_reagent_name()]" + var/bottles_text = num == 1 ? "new bottle" : "[num] new bottles" + tgui_modal_input(src, id, "Please name your [bottles_text] ([amount_per_bottle]u in bottle):", null, arguments, default_name, MAX_CUSTOM_NAME_LEN) + if("create_bottle_multiple") + if(condi || !reagents.total_volume) + return + tgui_modal_input(src, id, "Please enter the amount of bottles to make (max [MAX_MULTI_AMOUNT] at a time):", null, arguments, pillamount, 5) + if("change_bottle_style") + var/list/choices = list() + for(var/i = 1 to MAX_BOTTLE_SPRITE) + choices += "bottle-[i].png" + tgui_modal_bento(src, id, "Please select the new style for bottles:", null, arguments, bottlesprite, choices) + else + return FALSE + if(TGUI_MODAL_ANSWER) + var/answer = params["answer"] + switch(id) + // if("change_pill_bottle_style") + // if(!pill_bottle_wrappers || !loaded_pill_bottle) // wat? + // return + // var/color = "CLEAR" + // for(var/col in pill_bottle_wrappers) + // var/col_name = pill_bottle_wrappers[col] + // if(col_name == answer) + // color = col + // break + // if(length(color) && color != "CLEAR") + // loaded_pill_bottle.wrapper_color = color + // loaded_pill_bottle.apply_wrap() + // else + // loaded_pill_bottle.wrapper_color = null + // loaded_pill_bottle.cut_overlays() + if("addcustom") + var/amount = isgoodnumber(text2num(answer)) + if(!amount || !arguments["id"]) + return + tgui_act("add", list("id" = arguments["id"], "amount" = amount), ui, state) + if("removecustom") + var/amount = isgoodnumber(text2num(answer)) + if(!amount || !arguments["id"]) + return + tgui_act("remove", list("id" = arguments["id"], "amount" = amount), ui, state) + if("create_condi_pack") + if(!condi || !reagents.total_volume) + return + if(!length(answer)) + answer = reagents.get_master_reagent_name() + var/obj/item/weapon/reagent_containers/pill/P = new(loc) + P.name = "[answer] pack" + P.desc = "A small condiment pack. The label says it contains [answer]." + P.icon_state = "bouilloncube"//Reskinned monkey cube + reagents.trans_to_obj(P, 10) + if("create_pill") + if(condi || !reagents.total_volume) + return + var/count = CLAMP(round(text2num(arguments["num"]) || 0), 0, MAX_MULTI_AMOUNT) + if(!count) + return + + if(!length(answer)) + answer = reagents.get_master_reagent_name() + var/amount_per_pill = CLAMP(reagents.total_volume / count, 0, MAX_UNITS_PER_PILL) + while(count--) + if(reagents.total_volume <= 0) + to_chat(usr, "Not enough reagents to create these pills!") + return + + var/obj/item/weapon/reagent_containers/pill/P = new(loc) + P.name = "[answer] pill" + P.pixel_x = rand(-7, 7) // Random position + P.pixel_y = rand(-7, 7) + P.icon_state = "pill[pillsprite]" + if(P.icon_state in list("pill1", "pill2", "pill3", "pill4")) // if using greyscale, take colour from reagent + P.color = reagents.get_color() + reagents.trans_to_obj(P, amount_per_pill) + // Load the pills in the bottle if there's one loaded + if(istype(loaded_pill_bottle) && length(loaded_pill_bottle.contents) < loaded_pill_bottle.max_storage_space) + P.forceMove(loaded_pill_bottle) + if("create_pill_multiple") + if(condi || !reagents.total_volume) + return + tgui_act("modal_open", list("id" = "create_pill", "arguments" = list("num" = answer)), ui, state) + if("change_pill_style") + var/new_style = CLAMP(text2num(answer) || 0, 0, MAX_PILL_SPRITE) + if(!new_style) + return + pillsprite = new_style + if("create_patch") + if(condi || !reagents.total_volume) + return + var/count = CLAMP(round(text2num(arguments["num"]) || 0), 0, MAX_MULTI_AMOUNT) + if(!count) + return + + if(!length(answer)) + answer = reagents.get_master_reagent_name() + var/amount_per_patch = CLAMP(reagents.total_volume / count, 0, MAX_UNITS_PER_PATCH) + // var/is_medical_patch = chemical_safety_check(reagents) + while(count--) + if(reagents.total_volume <= 0) + to_chat(usr, "Not enough reagents to create these patches!") + return + + var/obj/item/weapon/reagent_containers/pill/patch/P = new(loc) + P.name = "[answer] patch" + P.pixel_x = rand(-7, 7) // random position + P.pixel_y = rand(-7, 7) + reagents.trans_to_obj(P, amount_per_patch) + // if(is_medical_patch) + // P.instant_application = TRUE + // P.icon_state = "bandaid_med" + if("create_patch_multiple") + if(condi || !reagents.total_volume) + return + tgui_act("modal_open", list("id" = "create_patch", "arguments" = list("num" = answer)), ui, state) + if("create_bottle") + if(condi || !reagents.total_volume) + return + var/count = CLAMP(round(text2num(arguments["num"]) || 0), 0, MAX_MULTI_AMOUNT) + if(!count) + return + + if(!length(answer)) + answer = reagents.get_master_reagent_name() + var/amount_per_bottle = CLAMP(reagents.total_volume / count, 0, MAX_UNITS_PER_BOTTLE) + while(count--) + if(reagents.total_volume <= 0) + to_chat(usr, "Not enough reagents to create these bottles!") + return + var/obj/item/weapon/reagent_containers/glass/bottle/P = new(loc) + P.name = "[answer] bottle" + P.pixel_x = rand(-7, 7) // random position + P.pixel_y = rand(-7, 7) + P.icon_state = "bottle-[bottlesprite]" || "bottle-1" + reagents.trans_to_obj(P, amount_per_bottle) + P.update_icon() + if("create_bottle_multiple") + if(condi || !reagents.total_volume) + return + tgui_act("modal_open", list("id" = "create_bottle", "arguments" = list("num" = answer)), ui, state) + if("change_bottle_style") + var/new_style = CLAMP(text2num(answer) || 0, 0, MAX_BOTTLE_SPRITE) + if(!new_style) + return + bottlesprite = new_style + else + return FALSE + else + return FALSE + +/obj/machinery/chem_master/tgui_act(action, params, datum/tgui/ui, datum/tgui_state/state) + if(..()) + return TRUE + + if(tgui_act_modal(action, params, ui, state)) + return TRUE + + add_fingerprint(usr) + usr.set_machine(src) + + . = TRUE + switch(action) + if("toggle") + mode = !mode + if("ejectp") + if(loaded_pill_bottle) + loaded_pill_bottle.forceMove(get_turf(src)) + if(Adjacent(usr) && !issilicon(usr)) + usr.put_in_hands(loaded_pill_bottle) + loaded_pill_bottle = null + if("print") + if(printing || condi) + return + + var/idx = text2num(params["idx"]) || 0 + var/from_beaker = text2num(params["beaker"]) || FALSE + var/reagent_list = from_beaker ? beaker.reagents.reagent_list : reagents.reagent_list + if(idx < 1 || idx > length(reagent_list)) + return + + var/datum/reagent/R = reagent_list[idx] + + printing = TRUE + visible_message("[src] rattles and prints out a sheet of paper.") + // playsound(loc, 'sound/goonstation/machines/printer_dotmatrix.ogg', 50, 1) + + var/obj/item/weapon/paper/P = new /obj/item/weapon/paper(loc) + P.info = "
Chemical Analysis

" + P.info += "Time of analysis: [worldtime2stationtime(world.time)]

" + P.info += "Chemical name: [R.name]
" + if(istype(R, /datum/reagent/blood)) + var/datum/reagent/blood/B = R + P.info += "Description: N/A
Blood Type: [B.data["blood_type"]]
DNA: [B.data["blood_DNA"]]" + else + P.info += "Description: [R.description]" + P.info += "

Notes:
" + P.name = "Chemical Analysis - [R.name]" + spawn(50) + printing = FALSE + else + . = FALSE + + if(. || !beaker) + return + + . = TRUE + var/datum/reagents/R = beaker.reagents + switch(action) + if("add") + var/id = params["id"] + var/amount = text2num(params["amount"]) + if(!id || !amount) + return + R.trans_id_to(src, id, amount) + if("remove") + var/id = params["id"] + var/amount = text2num(params["amount"]) + if(!id || !amount) + return + if(mode) + reagents.trans_id_to(beaker, id, amount) + else + reagents.remove_reagent(id, amount) + if("eject") + if(!beaker) + return + beaker.forceMove(get_turf(src)) + if(Adjacent(usr) && !issilicon(usr)) + usr.put_in_hands(beaker) + beaker = null + reagents.clear_reagents() + update_icon() + if("create_condi_bottle") + if(!condi || !reagents.total_volume) + return + var/obj/item/weapon/reagent_containers/food/condiment/P = new(loc) + reagents.trans_to_obj(P, 50) + else + return FALSE + +/obj/machinery/chem_master/attack_ai(mob/user) + return attack_hand(user) + +/obj/machinery/chem_master/proc/isgoodnumber(num) + if(isnum(num)) + if(num > 200) + num = 200 + else if(num < 0) + num = 1 + return num + else + return FALSE + +// /obj/machinery/chem_master/proc/chemical_safety_check(datum/reagents/R) +// var/all_safe = TRUE +// for(var/datum/reagent/A in R.reagent_list) +// if(!GLOB.safe_chem_list.Find(A.id)) +// all_safe = FALSE +// return all_safe + +/obj/machinery/chem_master/condimaster + name = "CondiMaster 3000" + condi = 1 diff --git a/code/modules/reagents/Chemistry-Machinery_vr.dm b/code/modules/reagents/machinery/chem_master_vr.dm similarity index 100% rename from code/modules/reagents/Chemistry-Machinery_vr.dm rename to code/modules/reagents/machinery/chem_master_vr.dm diff --git a/code/modules/reagents/machinery/chemalyzer.dm b/code/modules/reagents/machinery/chemalyzer.dm new file mode 100644 index 00000000000..ce8b1d6f12d --- /dev/null +++ b/code/modules/reagents/machinery/chemalyzer.dm @@ -0,0 +1,63 @@ +// Detects reagents inside most containers, and acts as an infinite identification system for reagent-based unidentified objects. + +/obj/machinery/chemical_analyzer + name = "chem analyzer" + desc = "Used to precisely scan chemicals and other liquids inside various containers. \ + It may also identify the liquid contents of unknown objects." + description_info = "This machine will try to tell you what reagents are inside of something capable of holding reagents. \ + It is also used to 'identify' specific reagent-based objects with their properties obscured from inspection by normal means." + icon = 'icons/obj/chemical.dmi' + icon_state = "chem_analyzer" + density = TRUE + anchored = TRUE + use_power = TRUE + idle_power_usage = 20 + clicksound = "button" + var/analyzing = FALSE + +/obj/machinery/chemical_analyzer/update_icon() + icon_state = "chem_analyzer[analyzing ? "-working":""]" + +/obj/machinery/chemical_analyzer/attackby(obj/item/I, mob/living/user) + if(!istype(I)) + return ..() + + if(default_deconstruction_screwdriver(user, I)) + return + if(default_deconstruction_crowbar(user, I)) + return + + if(istype(I,/obj/item/weapon/reagent_containers)) + analyzing = TRUE + update_icon() + to_chat(user, span("notice", "Analyzing \the [I], please stand by...")) + + if(!do_after(user, 2 SECONDS, src)) + to_chat(user, span("warning", "Sample moved outside of scan range, please try again and remain still.")) + analyzing = FALSE + update_icon() + return + + // First, identify it if it isn't already. + if(!I.is_identified(IDENTITY_FULL)) + var/datum/identification/ID = I.identity + if(ID.identification_type == IDENTITY_TYPE_CHEMICAL) // This only solves chemical-based mysteries. + I.identify(IDENTITY_FULL, user) + + // Now tell us everything that is inside. + if(I.reagents && I.reagents.reagent_list.len) + to_chat(user, "
") // To add padding between regular chat and the output. + for(var/datum/reagent/R in I.reagents.reagent_list) + if(!R.name) + continue + to_chat(user, span("notice", "Contains [R.volume]u of [R.name].
[R.description]
")) + + // Last, unseal it if it's an autoinjector. + if(istype(I,/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector) && !(I.flags & OPENCONTAINER)) + I.flags |= OPENCONTAINER + to_chat(user, span("notice", "Sample container unsealed.
")) + + to_chat(user, span("notice", "Scanning of \the [I] complete.")) + analyzing = FALSE + update_icon() + return \ No newline at end of file diff --git a/code/modules/reagents/dispenser/_defines.dm b/code/modules/reagents/machinery/dispenser/_defines.dm similarity index 96% rename from code/modules/reagents/dispenser/_defines.dm rename to code/modules/reagents/machinery/dispenser/_defines.dm index 60c12cdba66..8d52cf5cd07 100644 --- a/code/modules/reagents/dispenser/_defines.dm +++ b/code/modules/reagents/machinery/dispenser/_defines.dm @@ -1,8 +1,8 @@ -#define CARTRIDGE_VOLUME_LARGE 500 -#define CARTRIDGE_VOLUME_MEDIUM 250 -#define CARTRIDGE_VOLUME_SMALL 100 - -// Chemistry dispenser starts with 21 -// ERT dispenser starts with 28 -#define DISPENSER_MAX_CARTRIDGES 30 - +#define CARTRIDGE_VOLUME_LARGE 500 +#define CARTRIDGE_VOLUME_MEDIUM 250 +#define CARTRIDGE_VOLUME_SMALL 100 + +// Chemistry dispenser starts with 21 +// ERT dispenser starts with 28 +#define DISPENSER_MAX_CARTRIDGES 30 + diff --git a/code/modules/reagents/dispenser/cartridge.dm b/code/modules/reagents/machinery/dispenser/cartridge.dm similarity index 97% rename from code/modules/reagents/dispenser/cartridge.dm rename to code/modules/reagents/machinery/dispenser/cartridge.dm index 444577aaa51..0e2b09eb575 100644 --- a/code/modules/reagents/dispenser/cartridge.dm +++ b/code/modules/reagents/machinery/dispenser/cartridge.dm @@ -1,95 +1,95 @@ -/obj/item/weapon/reagent_containers/chem_disp_cartridge - name = "chemical dispenser cartridge" - desc = "This goes in a chemical dispenser." - icon_state = "cartridge" - - w_class = ITEMSIZE_NORMAL - - volume = CARTRIDGE_VOLUME_LARGE - amount_per_transfer_from_this = 50 - // Large, but inaccurate. Use a chem dispenser or beaker for accuracy. - possible_transfer_amounts = list(50, 100, 250, 500) - unacidable = 1 - - var/spawn_reagent = null - var/label = "" - -/obj/item/weapon/reagent_containers/chem_disp_cartridge/Initialize() - . = ..() - if(spawn_reagent) - reagents.add_reagent(spawn_reagent, volume) - var/datum/reagent/R = SSchemistry.chemical_reagents[spawn_reagent] - setLabel(R.name) - -/obj/item/weapon/reagent_containers/chem_disp_cartridge/examine(mob/user) - . = ..() - . += "It has a capacity of [volume] units." - if(reagents.total_volume <= 0) - . += "It is empty." - else - . += "It contains [reagents.total_volume] units of liquid." - if(!is_open_container()) - . += "The cap is sealed." - -/obj/item/weapon/reagent_containers/chem_disp_cartridge/verb/verb_set_label(L as text) - set name = "Set Cartridge Label" - set category = "Object" - set src in view(usr, 1) - - setLabel(L, usr) - -/obj/item/weapon/reagent_containers/chem_disp_cartridge/proc/setLabel(L, mob/user = null) - if(L) - if(user) - to_chat(user, "You set the label on \the [src] to '[L]'.") - - label = L - name = "[initial(name)] - '[L]'" - else - if(user) - to_chat(user, "You clear the label on \the [src].") - label = "" - name = initial(name) - -/obj/item/weapon/reagent_containers/chem_disp_cartridge/attack_self() - ..() - if (is_open_container()) - to_chat(usr, "You put the cap on \the [src].") - flags ^= OPENCONTAINER - else - to_chat(usr, "You take the cap off \the [src].") - flags |= OPENCONTAINER - -/obj/item/weapon/reagent_containers/chem_disp_cartridge/afterattack(obj/target, mob/user , flag) - if (!is_open_container() || !flag) - return - - else if(istype(target, /obj/structure/reagent_dispensers)) //A dispenser. Transfer FROM it TO us. - target.add_fingerprint(user) - - if(!target.reagents.total_volume && target.reagents) - to_chat(user, "\The [target] is empty.") - return - - if(reagents.total_volume >= reagents.maximum_volume) - to_chat(user, "\The [src] is full.") - return - - var/trans = target.reagents.trans_to(src, target:amount_per_transfer_from_this) - to_chat(user, "You fill \the [src] with [trans] units of the contents of \the [target].") - - else if(target.is_open_container() && target.reagents) //Something like a glass. Player probably wants to transfer TO it. - - if(!reagents.total_volume) - to_chat(user, "\The [src] is empty.") - return - - if(target.reagents.total_volume >= target.reagents.maximum_volume) - to_chat(user, "\The [target] is full.") - return - - var/trans = src.reagents.trans_to(target, amount_per_transfer_from_this) - to_chat(user, "You transfer [trans] units of the solution to \the [target].") - - else - return ..() +/obj/item/weapon/reagent_containers/chem_disp_cartridge + name = "chemical dispenser cartridge" + desc = "This goes in a chemical dispenser." + icon_state = "cartridge" + + w_class = ITEMSIZE_NORMAL + + volume = CARTRIDGE_VOLUME_LARGE + amount_per_transfer_from_this = 50 + // Large, but inaccurate. Use a chem dispenser or beaker for accuracy. + possible_transfer_amounts = list(50, 100, 250, 500) + unacidable = 1 + + var/spawn_reagent = null + var/label = "" + +/obj/item/weapon/reagent_containers/chem_disp_cartridge/Initialize() + . = ..() + if(spawn_reagent) + reagents.add_reagent(spawn_reagent, volume) + var/datum/reagent/R = SSchemistry.chemical_reagents[spawn_reagent] + setLabel(R.name) + +/obj/item/weapon/reagent_containers/chem_disp_cartridge/examine(mob/user) + . = ..() + . += "It has a capacity of [volume] units." + if(reagents.total_volume <= 0) + . += "It is empty." + else + . += "It contains [reagents.total_volume] units of liquid." + if(!is_open_container()) + . += "The cap is sealed." + +/obj/item/weapon/reagent_containers/chem_disp_cartridge/verb/verb_set_label(L as text) + set name = "Set Cartridge Label" + set category = "Object" + set src in view(usr, 1) + + setLabel(L, usr) + +/obj/item/weapon/reagent_containers/chem_disp_cartridge/proc/setLabel(L, mob/user = null) + if(L) + if(user) + to_chat(user, "You set the label on \the [src] to '[L]'.") + + label = L + name = "[initial(name)] - '[L]'" + else + if(user) + to_chat(user, "You clear the label on \the [src].") + label = "" + name = initial(name) + +/obj/item/weapon/reagent_containers/chem_disp_cartridge/attack_self() + ..() + if (is_open_container()) + to_chat(usr, "You put the cap on \the [src].") + flags ^= OPENCONTAINER + else + to_chat(usr, "You take the cap off \the [src].") + flags |= OPENCONTAINER + +/obj/item/weapon/reagent_containers/chem_disp_cartridge/afterattack(obj/target, mob/user , flag) + if (!is_open_container() || !flag) + return + + else if(istype(target, /obj/structure/reagent_dispensers)) //A dispenser. Transfer FROM it TO us. + target.add_fingerprint(user) + + if(!target.reagents.total_volume && target.reagents) + to_chat(user, "\The [target] is empty.") + return + + if(reagents.total_volume >= reagents.maximum_volume) + to_chat(user, "\The [src] is full.") + return + + var/trans = target.reagents.trans_to(src, target:amount_per_transfer_from_this) + to_chat(user, "You fill \the [src] with [trans] units of the contents of \the [target].") + + else if(target.is_open_container() && target.reagents) //Something like a glass. Player probably wants to transfer TO it. + + if(!reagents.total_volume) + to_chat(user, "\The [src] is empty.") + return + + if(target.reagents.total_volume >= target.reagents.maximum_volume) + to_chat(user, "\The [target] is full.") + return + + var/trans = src.reagents.trans_to(target, amount_per_transfer_from_this) + to_chat(user, "You transfer [trans] units of the solution to \the [target].") + + else + return ..() diff --git a/code/modules/reagents/dispenser/cartridge_presets.dm b/code/modules/reagents/machinery/dispenser/cartridge_presets.dm similarity index 97% rename from code/modules/reagents/dispenser/cartridge_presets.dm rename to code/modules/reagents/machinery/dispenser/cartridge_presets.dm index eea22fff7ea..21b321ad34d 100644 --- a/code/modules/reagents/dispenser/cartridge_presets.dm +++ b/code/modules/reagents/machinery/dispenser/cartridge_presets.dm @@ -1,108 +1,108 @@ -/obj/item/weapon/reagent_containers/chem_disp_cartridge - small - volume = CARTRIDGE_VOLUME_SMALL - - medium - volume = CARTRIDGE_VOLUME_MEDIUM - - // Multiple - water spawn_reagent = "water" - sugar spawn_reagent = "sugar" - - // Chemistry - hydrogen spawn_reagent = "hydrogen" - lithium spawn_reagent = "lithium" - carbon spawn_reagent = "carbon" - nitrogen spawn_reagent = "nitrogen" - oxygen spawn_reagent = "oxygen" - fluorine spawn_reagent = "fluorine" - sodium spawn_reagent = "sodium" - aluminum spawn_reagent = "aluminum" - silicon spawn_reagent = "silicon" - phosphorus spawn_reagent = "phosphorus" - sulfur spawn_reagent = "sulfur" - chlorine spawn_reagent = "chlorine" - potassium spawn_reagent = "potassium" - iron spawn_reagent = "iron" - copper spawn_reagent = "copper" - mercury spawn_reagent = "mercury" - radium spawn_reagent = "radium" - ethanol spawn_reagent = "ethanol" - sacid spawn_reagent = "sacid" - tungsten spawn_reagent = "tungsten" - calcium spawn_reagent = "calcium" - - // Bar, alcoholic - beer spawn_reagent = "beer" - kahlua spawn_reagent = "kahlua" - whiskey spawn_reagent = "whiskey" - wine spawn_reagent = "wine" - vodka spawn_reagent = "vodka" - gin spawn_reagent = "gin" - rum spawn_reagent = "rum" - tequila spawn_reagent = "tequilla" - vermouth spawn_reagent = "vermouth" - cognac spawn_reagent = "cognac" - ale spawn_reagent = "ale" - mead spawn_reagent = "mead" - bitters spawn_reagent = "bitters" - cider spawn_reagent = "cider" - - // Bar, soft - ice spawn_reagent = "ice" - tea spawn_reagent = "tea" - icetea spawn_reagent = "icetea" - cola spawn_reagent = "cola" - smw spawn_reagent = "spacemountainwind" - dr_gibb spawn_reagent = "dr_gibb" - spaceup spawn_reagent = "space_up" - tonic spawn_reagent = "tonic" - sodawater spawn_reagent = "sodawater" - lemon_lime spawn_reagent = "lemon_lime" - orange spawn_reagent = "orangejuice" - lime spawn_reagent = "limejuice" - watermelon spawn_reagent = "watermelonjuice" - lemon spawn_reagent = "lemonjuice" - - // Bar, coffee - coffee spawn_reagent = "coffee" - cafe_latte spawn_reagent = "cafe_latte" - soy_latte spawn_reagent = "soy_latte" - hot_coco spawn_reagent = "hot_coco" - milk spawn_reagent = "milk" - cream spawn_reagent = "cream" - mint spawn_reagent = "mint" - berry spawn_reagent = "berryjuice" - greentea spawn_reagent = "greentea" - decaf spawn_reagent = "decaf" - - // ERT - inaprov spawn_reagent = "inaprovaline" - ryetalyn spawn_reagent = "ryetalyn" - paracetamol spawn_reagent = "paracetamol" - tramadol spawn_reagent = "tramadol" - oxycodone spawn_reagent = "oxycodone" - sterilizine spawn_reagent = "sterilizine" - leporazine spawn_reagent = "leporazine" - kelotane spawn_reagent = "kelotane" - dermaline spawn_reagent = "dermaline" - dexalin spawn_reagent = "dexalin" - dexalin/small volume = CARTRIDGE_VOLUME_SMALL // For the medicine cartridge crate, so it's not too easy to get large amounts of dexalin - dexalin_p spawn_reagent = "dexalinp" - tricord spawn_reagent = "tricordrazine" - dylovene spawn_reagent = "anti_toxin" - synaptizine spawn_reagent = "synaptizine" - hyronalin spawn_reagent = "hyronalin" - arithrazine spawn_reagent = "arithrazine" - alkysine spawn_reagent = "alkysine" - imidazoline spawn_reagent = "imidazoline" - peridaxon spawn_reagent = "peridaxon" - bicaridine spawn_reagent = "bicaridine" - hyperzine spawn_reagent = "hyperzine" - rezadone spawn_reagent = "rezadone" - spaceacillin spawn_reagent = "spaceacillin" - ethylredox spawn_reagent = "ethylredoxrazine" - sleeptox spawn_reagent = "stoxin" - chloral spawn_reagent = "chloralhydrate" - cryoxadone spawn_reagent = "cryoxadone" - clonexadone spawn_reagent = "clonexadone" +/obj/item/weapon/reagent_containers/chem_disp_cartridge + small + volume = CARTRIDGE_VOLUME_SMALL + + medium + volume = CARTRIDGE_VOLUME_MEDIUM + + // Multiple + water spawn_reagent = "water" + sugar spawn_reagent = "sugar" + + // Chemistry + hydrogen spawn_reagent = "hydrogen" + lithium spawn_reagent = "lithium" + carbon spawn_reagent = "carbon" + nitrogen spawn_reagent = "nitrogen" + oxygen spawn_reagent = "oxygen" + fluorine spawn_reagent = "fluorine" + sodium spawn_reagent = "sodium" + aluminum spawn_reagent = "aluminum" + silicon spawn_reagent = "silicon" + phosphorus spawn_reagent = "phosphorus" + sulfur spawn_reagent = "sulfur" + chlorine spawn_reagent = "chlorine" + potassium spawn_reagent = "potassium" + iron spawn_reagent = "iron" + copper spawn_reagent = "copper" + mercury spawn_reagent = "mercury" + radium spawn_reagent = "radium" + ethanol spawn_reagent = "ethanol" + sacid spawn_reagent = "sacid" + tungsten spawn_reagent = "tungsten" + calcium spawn_reagent = "calcium" + + // Bar, alcoholic + beer spawn_reagent = "beer" + kahlua spawn_reagent = "kahlua" + whiskey spawn_reagent = "whiskey" + wine spawn_reagent = "wine" + vodka spawn_reagent = "vodka" + gin spawn_reagent = "gin" + rum spawn_reagent = "rum" + tequila spawn_reagent = "tequilla" + vermouth spawn_reagent = "vermouth" + cognac spawn_reagent = "cognac" + ale spawn_reagent = "ale" + mead spawn_reagent = "mead" + bitters spawn_reagent = "bitters" + cider spawn_reagent = "cider" + + // Bar, soft + ice spawn_reagent = "ice" + tea spawn_reagent = "tea" + icetea spawn_reagent = "icetea" + cola spawn_reagent = "cola" + smw spawn_reagent = "spacemountainwind" + dr_gibb spawn_reagent = "dr_gibb" + spaceup spawn_reagent = "space_up" + tonic spawn_reagent = "tonic" + sodawater spawn_reagent = "sodawater" + lemon_lime spawn_reagent = "lemon_lime" + orange spawn_reagent = "orangejuice" + lime spawn_reagent = "limejuice" + watermelon spawn_reagent = "watermelonjuice" + lemon spawn_reagent = "lemonjuice" + + // Bar, coffee + coffee spawn_reagent = "coffee" + cafe_latte spawn_reagent = "cafe_latte" + soy_latte spawn_reagent = "soy_latte" + hot_coco spawn_reagent = "hot_coco" + milk spawn_reagent = "milk" + cream spawn_reagent = "cream" + mint spawn_reagent = "mint" + berry spawn_reagent = "berryjuice" + greentea spawn_reagent = "greentea" + decaf spawn_reagent = "decaf" + + // ERT + inaprov spawn_reagent = "inaprovaline" + ryetalyn spawn_reagent = "ryetalyn" + paracetamol spawn_reagent = "paracetamol" + tramadol spawn_reagent = "tramadol" + oxycodone spawn_reagent = "oxycodone" + sterilizine spawn_reagent = "sterilizine" + leporazine spawn_reagent = "leporazine" + kelotane spawn_reagent = "kelotane" + dermaline spawn_reagent = "dermaline" + dexalin spawn_reagent = "dexalin" + dexalin/small volume = CARTRIDGE_VOLUME_SMALL // For the medicine cartridge crate, so it's not too easy to get large amounts of dexalin + dexalin_p spawn_reagent = "dexalinp" + tricord spawn_reagent = "tricordrazine" + dylovene spawn_reagent = "anti_toxin" + synaptizine spawn_reagent = "synaptizine" + hyronalin spawn_reagent = "hyronalin" + arithrazine spawn_reagent = "arithrazine" + alkysine spawn_reagent = "alkysine" + imidazoline spawn_reagent = "imidazoline" + peridaxon spawn_reagent = "peridaxon" + bicaridine spawn_reagent = "bicaridine" + hyperzine spawn_reagent = "hyperzine" + rezadone spawn_reagent = "rezadone" + spaceacillin spawn_reagent = "spaceacillin" + ethylredox spawn_reagent = "ethylredoxrazine" + sleeptox spawn_reagent = "stoxin" + chloral spawn_reagent = "chloralhydrate" + cryoxadone spawn_reagent = "cryoxadone" + clonexadone spawn_reagent = "clonexadone" diff --git a/code/modules/reagents/dispenser/cartridge_presets_vr.dm b/code/modules/reagents/machinery/dispenser/cartridge_presets_vr.dm similarity index 100% rename from code/modules/reagents/dispenser/cartridge_presets_vr.dm rename to code/modules/reagents/machinery/dispenser/cartridge_presets_vr.dm diff --git a/code/modules/reagents/dispenser/cartridge_spawn.dm b/code/modules/reagents/machinery/dispenser/cartridge_spawn.dm similarity index 100% rename from code/modules/reagents/dispenser/cartridge_spawn.dm rename to code/modules/reagents/machinery/dispenser/cartridge_spawn.dm diff --git a/code/modules/reagents/dispenser/dispenser2.dm b/code/modules/reagents/machinery/dispenser/dispenser2.dm similarity index 97% rename from code/modules/reagents/dispenser/dispenser2.dm rename to code/modules/reagents/machinery/dispenser/dispenser2.dm index 7f2fb13f404..d53dac4ba53 100644 --- a/code/modules/reagents/dispenser/dispenser2.dm +++ b/code/modules/reagents/machinery/dispenser/dispenser2.dm @@ -1,205 +1,205 @@ -/obj/machinery/chemical_dispenser - name = "chemical dispenser" - desc = "Automagically fabricates chemicals from electricity." - icon = 'icons/obj/chemical.dmi' - icon_state = "dispenser" - clicksound = "switch" - - var/list/spawn_cartridges = null // Set to a list of types to spawn one of each on New() - - var/list/cartridges = list() // Associative, label -> cartridge - var/obj/item/weapon/reagent_containers/container = null - - var/ui_title = "Chemical Dispenser" - - var/accept_drinking = 0 - var/amount = 30 - - use_power = USE_POWER_IDLE - idle_power_usage = 100 - anchored = 1 - -/obj/machinery/chemical_dispenser/Initialize() - . = ..() - if(spawn_cartridges) - for(var/type in spawn_cartridges) - add_cartridge(new type(src)) - -/obj/machinery/chemical_dispenser/examine(mob/user) - . = ..() - . += "It has [cartridges.len] cartridges installed, and has space for [DISPENSER_MAX_CARTRIDGES - cartridges.len] more." - -/obj/machinery/chemical_dispenser/verb/rotate_clockwise() - set name = "Rotate Dispenser Clockwise" - set category = "Object" - set src in oview(1) - - if (src.anchored || usr:stat) - to_chat(usr, "It is fastened down!") - return 0 - src.set_dir(turn(src.dir, 270)) - return 1 - -/obj/machinery/chemical_dispenser/proc/add_cartridge(obj/item/weapon/reagent_containers/chem_disp_cartridge/C, mob/user) - if(!istype(C)) - if(user) - to_chat(user, "\The [C] will not fit in \the [src]!") - return - - if(cartridges.len >= DISPENSER_MAX_CARTRIDGES) - if(user) - to_chat(user, "\The [src] does not have any slots open for \the [C] to fit into!") - return - - if(!C.label) - if(user) - to_chat(user, "\The [C] does not have a label!") - return - - if(cartridges[C.label]) - if(user) - to_chat(user, "\The [src] already contains a cartridge with that label!") - return - - if(user) - user.drop_from_inventory(C) - to_chat(user, "You add \the [C] to \the [src].") - - C.loc = src - cartridges[C.label] = C - cartridges = sortAssoc(cartridges) - SStgui.update_uis(src) - -/obj/machinery/chemical_dispenser/proc/remove_cartridge(label) - . = cartridges[label] - cartridges -= label - SStgui.update_uis(src) - -/obj/machinery/chemical_dispenser/attackby(obj/item/weapon/W, mob/user) - if(W.is_wrench()) - playsound(src, W.usesound, 50, 1) - to_chat(user, "You begin to [anchored ? "un" : ""]fasten \the [src].") - if (do_after(user, 20 * W.toolspeed)) - user.visible_message( - "\The [user] [anchored ? "un" : ""]fastens \the [src].", - "You have [anchored ? "un" : ""]fastened \the [src].", - "You hear a ratchet.") - anchored = !anchored - else - to_chat(user, "You decide not to [anchored ? "un" : ""]fasten \the [src].") - - else if(istype(W, /obj/item/weapon/reagent_containers/chem_disp_cartridge)) - add_cartridge(W, user) - - else if(W.is_screwdriver()) - var/label = input(user, "Which cartridge would you like to remove?", "Chemical Dispenser") as null|anything in cartridges - if(!label) return - var/obj/item/weapon/reagent_containers/chem_disp_cartridge/C = remove_cartridge(label) - if(C) - to_chat(user, "You remove \the [C] from \the [src].") - C.loc = loc - playsound(src, W.usesound, 50, 1) - - else if(istype(W, /obj/item/weapon/reagent_containers/glass) || istype(W, /obj/item/weapon/reagent_containers/food)) - if(container) - to_chat(user, "There is already \a [container] on \the [src]!") - return - - var/obj/item/weapon/reagent_containers/RC = W - - if(!accept_drinking && istype(RC,/obj/item/weapon/reagent_containers/food)) - to_chat(user, "This machine only accepts beakers!") - return - - if(!RC.is_open_container()) - to_chat(user, "You don't see how \the [src] could dispense reagents into \the [RC].") - return - - container = RC - user.drop_from_inventory(RC) - RC.loc = src - to_chat(user, "You set \the [RC] on \the [src].") - else - return ..() - -/obj/machinery/chemical_dispenser/tgui_interact(mob/user, datum/tgui/ui = null) - ui = SStgui.try_update_ui(user, src, ui) - if(!ui) - ui = new(user, src, "ChemDispenser", ui_title) // 390, 655 - ui.open() - -/obj/machinery/chemical_dispenser/tgui_data(mob/user) - var/data[0] - data["amount"] = amount - data["isBeakerLoaded"] = container ? 1 : 0 - data["glass"] = accept_drinking - - var/beakerContents[0] - if(container && container.reagents && container.reagents.reagent_list.len) - for(var/datum/reagent/R in container.reagents.reagent_list) - beakerContents.Add(list(list("name" = R.name, "id" = R.id, "volume" = R.volume))) // list in a list because Byond merges the first list... - data["beakerContents"] = beakerContents - - if(container) - data["beakerCurrentVolume"] = container.reagents.total_volume - data["beakerMaxVolume"] = container.reagents.maximum_volume - else - data["beakerCurrentVolume"] = null - data["beakerMaxVolume"] = null - - var/chemicals[0] - for(var/label in cartridges) - var/obj/item/weapon/reagent_containers/chem_disp_cartridge/C = cartridges[label] - chemicals.Add(list(list("title" = label, "id" = label, "amount" = C.reagents.total_volume))) // list in a list because Byond merges the first list... - data["chemicals"] = chemicals - return data - -/obj/machinery/chemical_dispenser/tgui_act(action, params) - if(..()) - return TRUE - - . = TRUE - switch(action) - if("amount") - amount = clamp(round(text2num(params["amount"]), 1), 0, 120) // round to nearest 1 and clamp 0 - 120 - if("dispense") - var/label = params["reagent"] - if(cartridges[label] && container && container.is_open_container()) - var/obj/item/weapon/reagent_containers/chem_disp_cartridge/C = cartridges[label] - playsound(src, 'sound/machines/reagent_dispense.ogg', 25, 1) - C.reagents.trans_to(container, amount) - if("remove") - var/amount = text2num(params["amount"]) - if(!container || !amount) - return - var/datum/reagents/R = container.reagents - var/id = params["reagent"] - if(amount > 0) - R.remove_reagent(id, amount) - else if(amount == -1) // Isolate - R.isolate_reagent(id) - if("ejectBeaker") - if(container) - container.forceMove(get_turf(src)) - - if(Adjacent(usr)) // So the AI doesn't get a beaker somehow. - usr.put_in_hands(container) - - container = null - else - return FALSE - - add_fingerprint(usr) - -/obj/machinery/chemical_dispenser/attack_ghost(mob/user) - if(stat & BROKEN) - return - tgui_interact(user) - -/obj/machinery/chemical_dispenser/attack_ai(mob/user) - attack_hand(user) - -/obj/machinery/chemical_dispenser/attack_hand(mob/user) - if(stat & BROKEN) - return - tgui_interact(user) +/obj/machinery/chemical_dispenser + name = "chemical dispenser" + desc = "Automagically fabricates chemicals from electricity." + icon = 'icons/obj/chemical.dmi' + icon_state = "dispenser" + clicksound = "switch" + + var/list/spawn_cartridges = null // Set to a list of types to spawn one of each on New() + + var/list/cartridges = list() // Associative, label -> cartridge + var/obj/item/weapon/reagent_containers/container = null + + var/ui_title = "Chemical Dispenser" + + var/accept_drinking = 0 + var/amount = 30 + + use_power = USE_POWER_IDLE + idle_power_usage = 100 + anchored = 1 + +/obj/machinery/chemical_dispenser/Initialize() + . = ..() + if(spawn_cartridges) + for(var/type in spawn_cartridges) + add_cartridge(new type(src)) + +/obj/machinery/chemical_dispenser/examine(mob/user) + . = ..() + . += "It has [cartridges.len] cartridges installed, and has space for [DISPENSER_MAX_CARTRIDGES - cartridges.len] more." + +/obj/machinery/chemical_dispenser/verb/rotate_clockwise() + set name = "Rotate Dispenser Clockwise" + set category = "Object" + set src in oview(1) + + if (src.anchored || usr:stat) + to_chat(usr, "It is fastened down!") + return 0 + src.set_dir(turn(src.dir, 270)) + return 1 + +/obj/machinery/chemical_dispenser/proc/add_cartridge(obj/item/weapon/reagent_containers/chem_disp_cartridge/C, mob/user) + if(!istype(C)) + if(user) + to_chat(user, "\The [C] will not fit in \the [src]!") + return + + if(cartridges.len >= DISPENSER_MAX_CARTRIDGES) + if(user) + to_chat(user, "\The [src] does not have any slots open for \the [C] to fit into!") + return + + if(!C.label) + if(user) + to_chat(user, "\The [C] does not have a label!") + return + + if(cartridges[C.label]) + if(user) + to_chat(user, "\The [src] already contains a cartridge with that label!") + return + + if(user) + user.drop_from_inventory(C) + to_chat(user, "You add \the [C] to \the [src].") + + C.loc = src + cartridges[C.label] = C + cartridges = sortAssoc(cartridges) + SStgui.update_uis(src) + +/obj/machinery/chemical_dispenser/proc/remove_cartridge(label) + . = cartridges[label] + cartridges -= label + SStgui.update_uis(src) + +/obj/machinery/chemical_dispenser/attackby(obj/item/weapon/W, mob/user) + if(W.is_wrench()) + playsound(src, W.usesound, 50, 1) + to_chat(user, "You begin to [anchored ? "un" : ""]fasten \the [src].") + if (do_after(user, 20 * W.toolspeed)) + user.visible_message( + "\The [user] [anchored ? "un" : ""]fastens \the [src].", + "You have [anchored ? "un" : ""]fastened \the [src].", + "You hear a ratchet.") + anchored = !anchored + else + to_chat(user, "You decide not to [anchored ? "un" : ""]fasten \the [src].") + + else if(istype(W, /obj/item/weapon/reagent_containers/chem_disp_cartridge)) + add_cartridge(W, user) + + else if(W.is_screwdriver()) + var/label = input(user, "Which cartridge would you like to remove?", "Chemical Dispenser") as null|anything in cartridges + if(!label) return + var/obj/item/weapon/reagent_containers/chem_disp_cartridge/C = remove_cartridge(label) + if(C) + to_chat(user, "You remove \the [C] from \the [src].") + C.loc = loc + playsound(src, W.usesound, 50, 1) + + else if(istype(W, /obj/item/weapon/reagent_containers/glass) || istype(W, /obj/item/weapon/reagent_containers/food)) + if(container) + to_chat(user, "There is already \a [container] on \the [src]!") + return + + var/obj/item/weapon/reagent_containers/RC = W + + if(!accept_drinking && istype(RC,/obj/item/weapon/reagent_containers/food)) + to_chat(user, "This machine only accepts beakers!") + return + + if(!RC.is_open_container()) + to_chat(user, "You don't see how \the [src] could dispense reagents into \the [RC].") + return + + container = RC + user.drop_from_inventory(RC) + RC.loc = src + to_chat(user, "You set \the [RC] on \the [src].") + else + return ..() + +/obj/machinery/chemical_dispenser/tgui_interact(mob/user, datum/tgui/ui = null) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "ChemDispenser", ui_title) // 390, 655 + ui.open() + +/obj/machinery/chemical_dispenser/tgui_data(mob/user) + var/data[0] + data["amount"] = amount + data["isBeakerLoaded"] = container ? 1 : 0 + data["glass"] = accept_drinking + + var/beakerContents[0] + if(container && container.reagents && container.reagents.reagent_list.len) + for(var/datum/reagent/R in container.reagents.reagent_list) + beakerContents.Add(list(list("name" = R.name, "id" = R.id, "volume" = R.volume))) // list in a list because Byond merges the first list... + data["beakerContents"] = beakerContents + + if(container) + data["beakerCurrentVolume"] = container.reagents.total_volume + data["beakerMaxVolume"] = container.reagents.maximum_volume + else + data["beakerCurrentVolume"] = null + data["beakerMaxVolume"] = null + + var/chemicals[0] + for(var/label in cartridges) + var/obj/item/weapon/reagent_containers/chem_disp_cartridge/C = cartridges[label] + chemicals.Add(list(list("title" = label, "id" = label, "amount" = C.reagents.total_volume))) // list in a list because Byond merges the first list... + data["chemicals"] = chemicals + return data + +/obj/machinery/chemical_dispenser/tgui_act(action, params) + if(..()) + return TRUE + + . = TRUE + switch(action) + if("amount") + amount = clamp(round(text2num(params["amount"]), 1), 0, 120) // round to nearest 1 and clamp 0 - 120 + if("dispense") + var/label = params["reagent"] + if(cartridges[label] && container && container.is_open_container()) + var/obj/item/weapon/reagent_containers/chem_disp_cartridge/C = cartridges[label] + playsound(src, 'sound/machines/reagent_dispense.ogg', 25, 1) + C.reagents.trans_to(container, amount) + if("remove") + var/amount = text2num(params["amount"]) + if(!container || !amount) + return + var/datum/reagents/R = container.reagents + var/id = params["reagent"] + if(amount > 0) + R.remove_reagent(id, amount) + else if(amount == -1) // Isolate + R.isolate_reagent(id) + if("ejectBeaker") + if(container) + container.forceMove(get_turf(src)) + + if(Adjacent(usr)) // So the AI doesn't get a beaker somehow. + usr.put_in_hands(container) + + container = null + else + return FALSE + + add_fingerprint(usr) + +/obj/machinery/chemical_dispenser/attack_ghost(mob/user) + if(stat & BROKEN) + return + tgui_interact(user) + +/obj/machinery/chemical_dispenser/attack_ai(mob/user) + attack_hand(user) + +/obj/machinery/chemical_dispenser/attack_hand(mob/user) + if(stat & BROKEN) + return + tgui_interact(user) diff --git a/code/modules/reagents/dispenser/dispenser2_energy.dm b/code/modules/reagents/machinery/dispenser/dispenser2_energy.dm similarity index 100% rename from code/modules/reagents/dispenser/dispenser2_energy.dm rename to code/modules/reagents/machinery/dispenser/dispenser2_energy.dm diff --git a/code/modules/reagents/dispenser/dispenser_presets.dm b/code/modules/reagents/machinery/dispenser/dispenser_presets.dm similarity index 98% rename from code/modules/reagents/dispenser/dispenser_presets.dm rename to code/modules/reagents/machinery/dispenser/dispenser_presets.dm index 69169030486..6b90357a2c6 100644 --- a/code/modules/reagents/dispenser/dispenser_presets.dm +++ b/code/modules/reagents/machinery/dispenser/dispenser_presets.dm @@ -1,144 +1,144 @@ -/obj/machinery/chemical_dispenser/full - spawn_cartridges = list( - /obj/item/weapon/reagent_containers/chem_disp_cartridge/hydrogen, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/lithium, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/carbon, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/nitrogen, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/oxygen, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/fluorine, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/sodium, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/aluminum, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/silicon, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/phosphorus, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/sulfur, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/chlorine, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/potassium, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/iron, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/copper, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/mercury, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/radium, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/water, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/ethanol, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/sugar, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/sacid, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/tungsten, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/calcium - ) - -/obj/machinery/chemical_dispenser/ert - name = "medicine dispenser" - spawn_cartridges = list( - /obj/item/weapon/reagent_containers/chem_disp_cartridge/inaprov, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/ryetalyn, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/paracetamol, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/tramadol, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/oxycodone, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/sterilizine, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/leporazine, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/kelotane, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/dermaline, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/dexalin, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/dexalin_p, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/tricord, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/dylovene, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/synaptizine, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/hyronalin, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/arithrazine, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/alkysine, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/imidazoline, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/peridaxon, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/bicaridine, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/hyperzine, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/rezadone, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/spaceacillin, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/ethylredox, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/sleeptox, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/chloral, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/cryoxadone, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/clonexadone - ) - -/obj/machinery/chemical_dispenser/bar_soft - name = "soft drink dispenser" - desc = "A soda machine." - icon_state = "soda_dispenser" - ui_title = "Soda Dispenser" - accept_drinking = 1 - -/obj/machinery/chemical_dispenser/bar_soft/full - spawn_cartridges = list( - /obj/item/weapon/reagent_containers/chem_disp_cartridge/water, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/ice, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/coffee, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/cream, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/tea, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/icetea, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/cola, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/smw, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/dr_gibb, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/spaceup, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/tonic, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/sodawater, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon_lime, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/sugar, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/orange, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/lime, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/watermelon, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon - ) - -/obj/machinery/chemical_dispenser/bar_alc - name = "booze dispenser" - desc = "A beer machine. Like a soda machine, but more fun!" - icon_state = "booze_dispenser" - ui_title = "Booze Dispenser" - accept_drinking = 1 - -/obj/machinery/chemical_dispenser/bar_alc/full - spawn_cartridges = list( - /obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon_lime, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/sugar, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/orange, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/lime, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/sodawater, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/tonic, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/beer, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/kahlua, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/whiskey, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/wine, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/vodka, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/gin, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/rum, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/tequila, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/vermouth, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/cognac, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/cider, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/ale, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/mead - ) - -/obj/machinery/chemical_dispenser/bar_coffee - name = "coffee dispenser" - desc = "Driving crack dealers out of employment since 2280." - icon_state = "coffee_dispenser" - ui_title = "Coffee Dispenser" - accept_drinking = 1 - -/obj/machinery/chemical_dispenser/bar_coffee/full - spawn_cartridges = list( - /obj/item/weapon/reagent_containers/chem_disp_cartridge/coffee, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/cafe_latte, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/soy_latte, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/hot_coco, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/milk, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/cream, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/tea, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/ice, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/mint, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/orange, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/lime, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/berry, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/greentea, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/decaf - ) +/obj/machinery/chemical_dispenser/full + spawn_cartridges = list( + /obj/item/weapon/reagent_containers/chem_disp_cartridge/hydrogen, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/lithium, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/carbon, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/nitrogen, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/oxygen, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/fluorine, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/sodium, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/aluminum, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/silicon, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/phosphorus, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/sulfur, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/chlorine, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/potassium, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/iron, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/copper, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/mercury, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/radium, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/water, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/ethanol, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/sugar, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/sacid, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/tungsten, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/calcium + ) + +/obj/machinery/chemical_dispenser/ert + name = "medicine dispenser" + spawn_cartridges = list( + /obj/item/weapon/reagent_containers/chem_disp_cartridge/inaprov, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/ryetalyn, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/paracetamol, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/tramadol, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/oxycodone, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/sterilizine, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/leporazine, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/kelotane, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/dermaline, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/dexalin, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/dexalin_p, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/tricord, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/dylovene, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/synaptizine, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/hyronalin, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/arithrazine, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/alkysine, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/imidazoline, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/peridaxon, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/bicaridine, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/hyperzine, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/rezadone, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/spaceacillin, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/ethylredox, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/sleeptox, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/chloral, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/cryoxadone, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/clonexadone + ) + +/obj/machinery/chemical_dispenser/bar_soft + name = "soft drink dispenser" + desc = "A soda machine." + icon_state = "soda_dispenser" + ui_title = "Soda Dispenser" + accept_drinking = 1 + +/obj/machinery/chemical_dispenser/bar_soft/full + spawn_cartridges = list( + /obj/item/weapon/reagent_containers/chem_disp_cartridge/water, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/ice, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/coffee, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/cream, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/tea, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/icetea, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/cola, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/smw, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/dr_gibb, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/spaceup, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/tonic, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/sodawater, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon_lime, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/sugar, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/orange, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/lime, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/watermelon, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon + ) + +/obj/machinery/chemical_dispenser/bar_alc + name = "booze dispenser" + desc = "A beer machine. Like a soda machine, but more fun!" + icon_state = "booze_dispenser" + ui_title = "Booze Dispenser" + accept_drinking = 1 + +/obj/machinery/chemical_dispenser/bar_alc/full + spawn_cartridges = list( + /obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon_lime, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/sugar, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/orange, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/lime, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/sodawater, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/tonic, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/beer, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/kahlua, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/whiskey, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/wine, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/vodka, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/gin, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/rum, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/tequila, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/vermouth, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/cognac, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/cider, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/ale, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/mead + ) + +/obj/machinery/chemical_dispenser/bar_coffee + name = "coffee dispenser" + desc = "Driving crack dealers out of employment since 2280." + icon_state = "coffee_dispenser" + ui_title = "Coffee Dispenser" + accept_drinking = 1 + +/obj/machinery/chemical_dispenser/bar_coffee/full + spawn_cartridges = list( + /obj/item/weapon/reagent_containers/chem_disp_cartridge/coffee, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/cafe_latte, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/soy_latte, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/hot_coco, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/milk, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/cream, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/tea, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/ice, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/mint, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/orange, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/lime, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/berry, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/greentea, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/decaf + ) diff --git a/code/modules/reagents/dispenser/dispenser_presets_vr.dm b/code/modules/reagents/machinery/dispenser/dispenser_presets_vr.dm similarity index 100% rename from code/modules/reagents/dispenser/dispenser_presets_vr.dm rename to code/modules/reagents/machinery/dispenser/dispenser_presets_vr.dm diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/machinery/dispenser/reagent_tank.dm similarity index 96% rename from code/modules/reagents/reagent_dispenser.dm rename to code/modules/reagents/machinery/dispenser/reagent_tank.dm index 91352a84981..6444ac85a2c 100644 --- a/code/modules/reagents/reagent_dispenser.dm +++ b/code/modules/reagents/machinery/dispenser/reagent_tank.dm @@ -1,466 +1,473 @@ - - -/obj/structure/reagent_dispensers - name = "Dispenser" - desc = "..." - icon = 'icons/obj/objects.dmi' - icon_state = "watertank" - layer = TABLE_LAYER - density = 1 - anchored = 0 - pressure_resistance = 2*ONE_ATMOSPHERE - - var/obj/item/hose_connector/input/active/InputSocket - var/obj/item/hose_connector/output/active/OutputSocket - - var/amount_per_transfer_from_this = 10 - var/possible_transfer_amounts = list(10,25,50,100) - -/obj/structure/reagent_dispensers/attackby(obj/item/weapon/W as obj, mob/user as mob) - return - -/obj/structure/reagent_dispensers/Destroy() - QDEL_NULL(InputSocket) - QDEL_NULL(OutputSocket) - - ..() - -/obj/structure/reagent_dispensers/Initialize() - var/datum/reagents/R = new/datum/reagents(5000) - reagents = R - R.my_atom = src - if (!possible_transfer_amounts) - src.verbs -= /obj/structure/reagent_dispensers/verb/set_APTFT - - InputSocket = new(src) - InputSocket.carrier = src - OutputSocket = new(src) - OutputSocket.carrier = src - - . = ..() - -/obj/structure/reagent_dispensers/examine(mob/user) - . = ..() - if(get_dist(user, src) <= 2) - . += "It contains:" - if(reagents && reagents.reagent_list.len) - for(var/datum/reagent/R in reagents.reagent_list) - . += "[R.volume] units of [R.name]" - else - . += "Nothing." - -/obj/structure/reagent_dispensers/verb/set_APTFT() //set amount_per_transfer_from_this - set name = "Set transfer amount" - set category = "Object" - set src in view(1) - var/N = input("Amount per transfer from this:","[src]") as null|anything in possible_transfer_amounts - if (N) - amount_per_transfer_from_this = N - -/obj/structure/reagent_dispensers/ex_act(severity) - switch(severity) - if(1.0) - qdel(src) - return - if(2.0) - if (prob(50)) - new /obj/effect/effect/water(src.loc) - qdel(src) - return - if(3.0) - if (prob(5)) - new /obj/effect/effect/water(src.loc) - qdel(src) - return - else - return - -/obj/structure/reagent_dispensers/blob_act() - qdel(src) - - - -//Dispensers -/obj/structure/reagent_dispensers/watertank - name = "watertank" - desc = "A watertank." - icon = 'icons/obj/objects_vr.dmi' //VOREStation Edit - icon_state = "watertank" - amount_per_transfer_from_this = 10 - -/obj/structure/reagent_dispensers/watertank/Initialize() - . = ..() - reagents.add_reagent("water", 1000) - -/obj/structure/reagent_dispensers/watertank/high - name = "high-capacity water tank" - desc = "A highly-pressurized water tank made to hold vast amounts of water.." - icon_state = "watertank_high" - -/obj/structure/reagent_dispensers/watertank/high/Initialize() - . = ..() - reagents.add_reagent("water", 4000) - -/obj/structure/reagent_dispensers/fueltank - name = "fueltank" - desc = "A fueltank." - icon = 'icons/obj/objects_vr.dmi' //VOREStation Edit - icon_state = "weldtank" - amount_per_transfer_from_this = 10 - var/modded = 0 - var/obj/item/device/assembly_holder/rig = null - -/obj/structure/reagent_dispensers/fueltank/Initialize() - . = ..() - reagents.add_reagent("fuel",1000) - -//VOREStation Add -/obj/structure/reagent_dispensers/fueltank/high - name = "high-capacity fuel tank" - desc = "A highly-pressurized fuel tank made to hold vast amounts of fuel." - icon_state = "weldtank_high" - -/obj/structure/reagent_dispensers/fueltank/high/Initialize() - . = ..() - reagents.add_reagent("fuel",4000) - -/obj/structure/reagent_dispensers/foam - name = "foamtank" - desc = "A foam tank." - icon = 'icons/obj/objects_vr.dmi' //VOREStation Edit - icon_state = "foamtank" - amount_per_transfer_from_this = 10 - -/obj/structure/reagent_dispensers/foam/Initialize() - . = ..() - reagents.add_reagent("firefoam",1000) - -/obj/structure/reagent_dispensers/fueltank/barrel - name = "hazardous barrel" - desc = "An open-topped barrel full of nasty-looking liquid." - icon_state = "barrel" - modded = TRUE - -/obj/structure/reagent_dispensers/fueltank/barrel/attackby(obj/item/weapon/W as obj, mob/user as mob) - if (W.is_wrench()) //can't wrench it shut, it's always open - return - return ..() - -//VOREStation Add End - - -/obj/structure/reagent_dispensers/fueltank/examine(mob/user) - . = ..() - if(get_dist(user, src) <= 2) - if(modded) - . += "Fuel faucet is wrenched open, leaking the fuel!" - if(rig) - . += "There is some kind of device rigged to the tank." - -/obj/structure/reagent_dispensers/fueltank/attack_hand() - if (rig) - usr.visible_message("[usr] begins to detach [rig] from \the [src].", "You begin to detach [rig] from \the [src]") - if(do_after(usr, 20)) - usr.visible_message("[usr] detaches [rig] from \the [src].", "You detach [rig] from \the [src]") - rig.loc = get_turf(usr) - rig = null - overlays = new/list() - -/obj/structure/reagent_dispensers/fueltank/attackby(obj/item/weapon/W as obj, mob/user as mob) - src.add_fingerprint(user) - if (W.is_wrench()) - user.visible_message("[user] wrenches [src]'s faucet [modded ? "closed" : "open"].", \ - "You wrench [src]'s faucet [modded ? "closed" : "open"]") - modded = modded ? 0 : 1 - playsound(src, W.usesound, 75, 1) - if (modded) - message_admins("[key_name_admin(user)] opened fueltank at [loc.loc.name] ([loc.x],[loc.y],[loc.z]), leaking fuel. (JMP)") - log_game("[key_name(user)] opened fueltank at [loc.loc.name] ([loc.x],[loc.y],[loc.z]), leaking fuel.") - leak_fuel(amount_per_transfer_from_this) - if (istype(W,/obj/item/device/assembly_holder)) - if (rig) - to_chat(user, "There is another device in the way.") - return ..() - user.visible_message("[user] begins rigging [W] to \the [src].", "You begin rigging [W] to \the [src]") - if(do_after(user, 20)) - user.visible_message("[user] rigs [W] to \the [src].", "You rig [W] to \the [src]") - - var/obj/item/device/assembly_holder/H = W - if (istype(H.a_left,/obj/item/device/assembly/igniter) || istype(H.a_right,/obj/item/device/assembly/igniter)) - message_admins("[key_name_admin(user)] rigged fueltank at [loc.loc.name] ([loc.x],[loc.y],[loc.z]) for explosion. (JMP)") - log_game("[key_name(user)] rigged fueltank at [loc.loc.name] ([loc.x],[loc.y],[loc.z]) for explosion.") - - rig = W - user.drop_item() - W.loc = src - - var/icon/test = getFlatIcon(W) - test.Shift(NORTH,1) - test.Shift(EAST,6) - overlays += test - - return ..() - - -/obj/structure/reagent_dispensers/fueltank/bullet_act(var/obj/item/projectile/Proj) - if(Proj.get_structure_damage()) - if(istype(Proj.firer)) - message_admins("[key_name_admin(Proj.firer)] shot fueltank at [loc.loc.name] ([loc.x],[loc.y],[loc.z]) (JMP).") - log_game("[key_name(Proj.firer)] shot fueltank at [loc.loc.name] ([loc.x],[loc.y],[loc.z]).") - - if(!istype(Proj ,/obj/item/projectile/beam/lasertag) && !istype(Proj ,/obj/item/projectile/beam/practice) ) - explode() - -/obj/structure/reagent_dispensers/fueltank/ex_act() - explode() - -/obj/structure/reagent_dispensers/fueltank/blob_act() - explode() - -/obj/structure/reagent_dispensers/fueltank/proc/explode() - if (reagents.total_volume > 500) - explosion(src.loc,1,2,4) - else if (reagents.total_volume > 100) - explosion(src.loc,0,1,3) - else if (reagents.total_volume > 50) - explosion(src.loc,-1,1,2) - if(src) - qdel(src) - -/obj/structure/reagent_dispensers/fueltank/fire_act(datum/gas_mixture/air, temperature, volume) - if (modded) - explode() - else if (temperature > T0C+500) - explode() - return ..() - -/obj/structure/reagent_dispensers/fueltank/Move() - if (..() && modded) - leak_fuel(amount_per_transfer_from_this/10.0) - -/obj/structure/reagent_dispensers/fueltank/proc/leak_fuel(amount) - if (reagents.total_volume == 0) - return - - amount = min(amount, reagents.total_volume) - reagents.remove_reagent("fuel",amount) - new /obj/effect/decal/cleanable/liquid_fuel(src.loc, amount,1) - -/obj/structure/reagent_dispensers/peppertank - name = "Pepper Spray Refiller" - desc = "Refills pepper spray canisters." - icon = 'icons/obj/objects.dmi' - icon_state = "peppertank" - anchored = 1 - density = 0 - amount_per_transfer_from_this = 45 - -/obj/structure/reagent_dispensers/peppertank/Initialize() - . = ..() - reagents.add_reagent("condensedcapsaicin",1000) - - -/obj/structure/reagent_dispensers/water_cooler - name = "Water-Cooler" - desc = "A machine that dispenses water to drink." - amount_per_transfer_from_this = 5 - icon = 'icons/obj/vending.dmi' - icon_state = "water_cooler" - possible_transfer_amounts = null - anchored = 1 - var/bottle = 0 - var/cups = 0 - var/cupholder = 0 - -/obj/structure/reagent_dispensers/water_cooler/full - bottle = 1 - cupholder = 1 - cups = 10 - -/obj/structure/reagent_dispensers/water_cooler/Initialize() - . = ..() - if(bottle) - reagents.add_reagent("water",120) - update_icon() - -/obj/structure/reagent_dispensers/water_cooler/examine(mob/user) - . = ..() - if(cupholder) - . += "There are [cups] cups in the cup dispenser." - -/obj/structure/reagent_dispensers/water_cooler/verb/rotate_clockwise() - set name = "Rotate Cooler Clockwise" - set category = "Object" - set src in oview(1) - - if (src.anchored || usr:stat) - to_chat(usr, "It is fastened to the floor!") - return 0 - src.set_dir(turn(src.dir, 270)) - return 1 - -/obj/structure/reagent_dispensers/water_cooler/attackby(obj/item/I as obj, mob/user as mob) - if(I.is_wrench()) - src.add_fingerprint(user) - if(bottle) - playsound(src, I.usesound, 50, 1) - if(do_after(user, 20) && bottle) - to_chat(user, "You unfasten the jug.") - var/obj/item/weapon/reagent_containers/glass/cooler_bottle/G = new /obj/item/weapon/reagent_containers/glass/cooler_bottle( src.loc ) - for(var/datum/reagent/R in reagents.reagent_list) - var/total_reagent = reagents.get_reagent_amount(R.id) - G.reagents.add_reagent(R.id, total_reagent) - reagents.clear_reagents() - bottle = 0 - update_icon() - else - if(anchored) - user.visible_message("\The [user] begins unsecuring \the [src] from the floor.", "You start unsecuring \the [src] from the floor.") - else - user.visible_message("\The [user] begins securing \the [src] to the floor.", "You start securing \the [src] to the floor.") - if(do_after(user, 20 * I.toolspeed, src)) - if(!src) return - to_chat(user, "You [anchored? "un" : ""]secured \the [src]!") - anchored = !anchored - playsound(src, I.usesound, 50, 1) - return - - if(I.is_screwdriver()) - if(cupholder) - playsound(src, I.usesound, 50, 1) - to_chat(user, "You take the cup dispenser off.") - new /obj/item/stack/material/plastic( src.loc ) - if(cups) - for(var/i = 0 to cups) - new /obj/item/weapon/reagent_containers/food/drinks/sillycup(src.loc) - cups = 0 - cupholder = 0 - update_icon() - return - if(!bottle && !cupholder) - playsound(src, I.usesound, 50, 1) - to_chat(user, "You start taking the water-cooler apart.") - if(do_after(user, 20 * I.toolspeed) && !bottle && !cupholder) - to_chat(user, "You take the water-cooler apart.") - new /obj/item/stack/material/plastic( src.loc, 4 ) - qdel(src) - return - - if(istype(I, /obj/item/weapon/reagent_containers/glass/cooler_bottle)) - src.add_fingerprint(user) - if(!bottle) - if(anchored) - var/obj/item/weapon/reagent_containers/glass/cooler_bottle/G = I - to_chat(user, "You start to screw the bottle onto the water-cooler.") - if(do_after(user, 20) && !bottle && anchored) - bottle = 1 - update_icon() - to_chat(user, "You screw the bottle onto the water-cooler!") - for(var/datum/reagent/R in G.reagents.reagent_list) - var/total_reagent = G.reagents.get_reagent_amount(R.id) - reagents.add_reagent(R.id, total_reagent) - qdel(G) - else - to_chat(user, "You need to wrench down the cooler first.") - else - to_chat(user, "There is already a bottle there!") - return 1 - - if(istype(I, /obj/item/stack/material/plastic)) - if(!cupholder) - if(anchored) - var/obj/item/stack/material/plastic/P = I - src.add_fingerprint(user) - to_chat(user, "You start to attach a cup dispenser onto the water-cooler.") - playsound(src, 'sound/items/Deconstruct.ogg', 50, 1) - if(do_after(user, 20) && !cupholder && anchored) - if (P.use(1)) - to_chat(user, "You attach a cup dispenser onto the water-cooler.") - cupholder = 1 - update_icon() - else - to_chat(user, "You need to wrench down the cooler first.") - else - to_chat(user, "There is already a cup dispenser there!") - return - -/obj/structure/reagent_dispensers/water_cooler/attack_hand(mob/user) - if(cups) - new /obj/item/weapon/reagent_containers/food/drinks/sillycup(src.loc) - cups-- - flick("[icon_state]-vend", src) - return - -/obj/structure/reagent_dispensers/water_cooler/update_icon() - icon_state = "water_cooler" - overlays.Cut() - var/image/I - if(bottle) - I = image(icon, "water_cooler_bottle") - overlays += I - return - -/obj/structure/reagent_dispensers/beerkeg - name = "beer keg" - desc = "A beer keg." - icon = 'icons/obj/objects.dmi' - icon_state = "beertankTEMP" - amount_per_transfer_from_this = 10 - -/obj/structure/reagent_dispensers/beerkeg/Initialize() - . = ..() - reagents.add_reagent("beer",1000) - -/obj/structure/reagent_dispensers/beerkeg/fakenuke - name = "nuclear beer keg" - desc = "A beer keg in the form of a nuclear bomb! An absolute blast at parties!" - icon = 'icons/obj/stationobjs.dmi' - icon_state = "nuclearbomb0" - -/obj/structure/reagent_dispensers/virusfood - name = "Virus Food Dispenser" - desc = "A dispenser of virus food. Yum." - icon = 'icons/obj/objects.dmi' - icon_state = "virusfoodtank" - amount_per_transfer_from_this = 10 - anchored = 1 - -/obj/structure/reagent_dispensers/virusfood/Initialize() - . = ..() - reagents.add_reagent("virusfood", 1000) - -/obj/structure/reagent_dispensers/acid - name = "Sulphuric Acid Dispenser" - desc = "A dispenser of acid for industrial processes." - icon = 'icons/obj/objects.dmi' - icon_state = "acidtank" - amount_per_transfer_from_this = 10 - anchored = 1 - -/obj/structure/reagent_dispensers/acid/Initialize() - . = ..() - reagents.add_reagent("sacid", 1000) - -//Cooking oil refill tank -/obj/structure/reagent_dispensers/cookingoil - name = "cooking oil tank" - desc = "A fifty-litre tank of commercial-grade corn oil, intended for use in large scale deep fryers. Store in a cool, dark place" - icon = 'icons/obj/objects.dmi' - icon_state = "oiltank" - amount_per_transfer_from_this = 120 - -/obj/structure/reagent_dispensers/cookingoil/New() - ..() - reagents.add_reagent("cornoil",5000) - -/obj/structure/reagent_dispensers/cookingoil/bullet_act(var/obj/item/projectile/Proj) - if(Proj.get_structure_damage()) - explode() - -/obj/structure/reagent_dispensers/cookingoil/ex_act() - explode() - -/obj/structure/reagent_dispensers/cookingoil/proc/explode() - reagents.splash_area(get_turf(src), 3) - visible_message(span("danger", "The [src] bursts open, spreading oil all over the area.")) - qdel(src) +/obj/structure/reagent_dispensers + name = "Dispenser" + desc = "..." + icon = 'icons/obj/objects.dmi' + icon_state = "watertank" + layer = TABLE_LAYER + density = 1 + anchored = 0 + pressure_resistance = 2*ONE_ATMOSPHERE + + var/obj/item/hose_connector/input/active/InputSocket + var/obj/item/hose_connector/output/active/OutputSocket + + var/amount_per_transfer_from_this = 10 + var/possible_transfer_amounts = list(10,25,50,100) + +/obj/structure/reagent_dispensers/attackby(obj/item/weapon/W as obj, mob/user as mob) + return + +/obj/structure/reagent_dispensers/Destroy() + QDEL_NULL(InputSocket) + QDEL_NULL(OutputSocket) + + ..() + +/obj/structure/reagent_dispensers/Initialize() + var/datum/reagents/R = new/datum/reagents(5000) + reagents = R + R.my_atom = src + if (!possible_transfer_amounts) + src.verbs -= /obj/structure/reagent_dispensers/verb/set_APTFT + + InputSocket = new(src) + InputSocket.carrier = src + OutputSocket = new(src) + OutputSocket.carrier = src + + . = ..() + +/obj/structure/reagent_dispensers/examine(mob/user) + . = ..() + if(get_dist(user, src) <= 2) + . += "It contains:" + if(reagents && reagents.reagent_list.len) + for(var/datum/reagent/R in reagents.reagent_list) + . += "[R.volume] units of [R.name]" + else + . += "Nothing." + +/obj/structure/reagent_dispensers/verb/set_APTFT() //set amount_per_transfer_from_this + set name = "Set transfer amount" + set category = "Object" + set src in view(1) + var/N = input("Amount per transfer from this:","[src]") as null|anything in possible_transfer_amounts + if (N) + amount_per_transfer_from_this = N + +/obj/structure/reagent_dispensers/ex_act(severity) + switch(severity) + if(1.0) + qdel(src) + return + if(2.0) + if (prob(50)) + new /obj/effect/effect/water(src.loc) + qdel(src) + return + if(3.0) + if (prob(5)) + new /obj/effect/effect/water(src.loc) + qdel(src) + return + else + return + +/obj/structure/reagent_dispensers/blob_act() + qdel(src) + + + +//Dispensers +/obj/structure/reagent_dispensers/watertank + name = "watertank" + desc = "A watertank." + icon = 'icons/obj/objects_vr.dmi' //VOREStation Edit + icon_state = "watertank" + amount_per_transfer_from_this = 10 + +/obj/structure/reagent_dispensers/watertank/Initialize() + . = ..() + reagents.add_reagent("water", 1000) + +/obj/structure/reagent_dispensers/watertank/high + name = "high-capacity water tank" + desc = "A highly-pressurized water tank made to hold vast amounts of water.." + icon_state = "watertank_high" + +/obj/structure/reagent_dispensers/watertank/high/Initialize() + . = ..() + reagents.add_reagent("water", 4000) + +/obj/structure/reagent_dispensers/fueltank + name = "fueltank" + desc = "A fueltank." + icon = 'icons/obj/objects_vr.dmi' //VOREStation Edit + icon_state = "weldtank" + amount_per_transfer_from_this = 10 + var/modded = 0 + var/obj/item/device/assembly_holder/rig = null + +/obj/structure/reagent_dispensers/fueltank/Initialize() + . = ..() + reagents.add_reagent("fuel",1000) + +//VOREStation Add +/obj/structure/reagent_dispensers/fueltank/high + name = "high-capacity fuel tank" + desc = "A highly-pressurized fuel tank made to hold vast amounts of fuel." + icon_state = "weldtank_high" + +/obj/structure/reagent_dispensers/fueltank/high/Initialize() + . = ..() + reagents.add_reagent("fuel",4000) + +/obj/structure/reagent_dispensers/foam + name = "foamtank" + desc = "A foam tank." + icon = 'icons/obj/objects_vr.dmi' + icon_state = "foamtank" + amount_per_transfer_from_this = 10 + +/obj/structure/reagent_dispensers/foam/Initialize() + . = ..() + reagents.add_reagent("firefoam",1000) + +/obj/structure/reagent_dispensers/fueltank/barrel + name = "hazardous barrel" + desc = "An open-topped barrel full of nasty-looking liquid." + icon_state = "barrel" + modded = TRUE + +/obj/structure/reagent_dispensers/fueltank/barrel/attackby(obj/item/weapon/W as obj, mob/user as mob) + if (W.is_wrench()) //can't wrench it shut, it's always open + return + return ..() +//VOREStation Add End + +/obj/structure/reagent_dispensers/fueltank/examine(mob/user) + . = ..() + if(get_dist(user, src) <= 2) + if(modded) + . += "Fuel faucet is wrenched open, leaking the fuel!" + if(rig) + . += "There is some kind of device rigged to the tank." + +/obj/structure/reagent_dispensers/fueltank/attack_hand() + if (rig) + usr.visible_message("[usr] begins to detach [rig] from \the [src].", "You begin to detach [rig] from \the [src]") + if(do_after(usr, 20)) + usr.visible_message("[usr] detaches [rig] from \the [src].", "You detach [rig] from \the [src]") + rig.loc = get_turf(usr) + rig = null + overlays = new/list() + +/obj/structure/reagent_dispensers/fueltank/attackby(obj/item/weapon/W as obj, mob/user as mob) + src.add_fingerprint(user) + if (W.is_wrench()) + user.visible_message("[user] wrenches [src]'s faucet [modded ? "closed" : "open"].", \ + "You wrench [src]'s faucet [modded ? "closed" : "open"]") + modded = modded ? 0 : 1 + playsound(src, W.usesound, 75, 1) + if (modded) + message_admins("[key_name_admin(user)] opened fueltank at [loc.loc.name] ([loc.x],[loc.y],[loc.z]), leaking fuel. (JMP)") + log_game("[key_name(user)] opened fueltank at [loc.loc.name] ([loc.x],[loc.y],[loc.z]), leaking fuel.") + leak_fuel(amount_per_transfer_from_this) + if (istype(W,/obj/item/device/assembly_holder)) + if (rig) + to_chat(user, "There is another device in the way.") + return ..() + user.visible_message("[user] begins rigging [W] to \the [src].", "You begin rigging [W] to \the [src]") + if(do_after(user, 20)) + user.visible_message("[user] rigs [W] to \the [src].", "You rig [W] to \the [src]") + + var/obj/item/device/assembly_holder/H = W + if (istype(H.a_left,/obj/item/device/assembly/igniter) || istype(H.a_right,/obj/item/device/assembly/igniter)) + message_admins("[key_name_admin(user)] rigged fueltank at [loc.loc.name] ([loc.x],[loc.y],[loc.z]) for explosion. (JMP)") + log_game("[key_name(user)] rigged fueltank at [loc.loc.name] ([loc.x],[loc.y],[loc.z]) for explosion.") + + rig = W + user.drop_item() + W.loc = src + + var/icon/test = getFlatIcon(W) + test.Shift(NORTH,1) + test.Shift(EAST,6) + overlays += test + + return ..() + + +/obj/structure/reagent_dispensers/fueltank/bullet_act(var/obj/item/projectile/Proj) + if(Proj.get_structure_damage()) + if(istype(Proj.firer)) + message_admins("[key_name_admin(Proj.firer)] shot fueltank at [loc.loc.name] ([loc.x],[loc.y],[loc.z]) (JMP).") + log_game("[key_name(Proj.firer)] shot fueltank at [loc.loc.name] ([loc.x],[loc.y],[loc.z]).") + + if(!istype(Proj ,/obj/item/projectile/beam/lasertag) && !istype(Proj ,/obj/item/projectile/beam/practice) ) + explode() + +/obj/structure/reagent_dispensers/fueltank/ex_act() + explode() + +/obj/structure/reagent_dispensers/fueltank/blob_act() + explode() + +/obj/structure/reagent_dispensers/fueltank/proc/explode() + if (reagents.total_volume > 500) + explosion(src.loc,1,2,4) + else if (reagents.total_volume > 100) + explosion(src.loc,0,1,3) + else if (reagents.total_volume > 50) + explosion(src.loc,-1,1,2) + if(src) + qdel(src) + +/obj/structure/reagent_dispensers/fueltank/fire_act(datum/gas_mixture/air, temperature, volume) + if (modded) + explode() + else if (temperature > T0C+500) + explode() + return ..() + +/obj/structure/reagent_dispensers/fueltank/Move() + if (..() && modded) + leak_fuel(amount_per_transfer_from_this/10.0) + +/obj/structure/reagent_dispensers/fueltank/proc/leak_fuel(amount) + if (reagents.total_volume == 0) + return + + amount = min(amount, reagents.total_volume) + reagents.remove_reagent("fuel",amount) + new /obj/effect/decal/cleanable/liquid_fuel(src.loc, amount,1) + +/obj/structure/reagent_dispensers/peppertank + name = "Pepper Spray Refiller" + desc = "Refills pepper spray canisters." + icon = 'icons/obj/objects.dmi' + icon_state = "peppertank" + anchored = 1 + density = 0 + amount_per_transfer_from_this = 45 + +/obj/structure/reagent_dispensers/peppertank/Initialize() + . = ..() + reagents.add_reagent("condensedcapsaicin",1000) + + +/obj/structure/reagent_dispensers/water_cooler + name = "Water-Cooler" + desc = "A machine that dispenses water to drink." + amount_per_transfer_from_this = 5 + icon = 'icons/obj/vending.dmi' + icon_state = "water_cooler" + possible_transfer_amounts = null + anchored = 1 + var/bottle = 0 + var/cups = 0 + var/cupholder = 0 + +/obj/structure/reagent_dispensers/water_cooler/full + bottle = 1 + cupholder = 1 + cups = 10 + +/obj/structure/reagent_dispensers/water_cooler/Initialize() + . = ..() + if(bottle) + reagents.add_reagent("water",120) + update_icon() + +/obj/structure/reagent_dispensers/water_cooler/examine(mob/user) + . = ..() + if(cupholder) + . += "There are [cups] cups in the cup dispenser." + +/obj/structure/reagent_dispensers/water_cooler/verb/rotate_clockwise() + set name = "Rotate Cooler Clockwise" + set category = "Object" + set src in oview(1) + + if (src.anchored || usr:stat) + to_chat(usr, "It is fastened to the floor!") + return 0 + src.set_dir(turn(src.dir, 270)) + return 1 + +/obj/structure/reagent_dispensers/water_cooler/attackby(obj/item/I as obj, mob/user as mob) + if(I.is_wrench()) + src.add_fingerprint(user) + if(bottle) + playsound(src, I.usesound, 50, 1) + if(do_after(user, 20) && bottle) + to_chat(user, "You unfasten the jug.") + var/obj/item/weapon/reagent_containers/glass/cooler_bottle/G = new /obj/item/weapon/reagent_containers/glass/cooler_bottle( src.loc ) + for(var/datum/reagent/R in reagents.reagent_list) + var/total_reagent = reagents.get_reagent_amount(R.id) + G.reagents.add_reagent(R.id, total_reagent) + reagents.clear_reagents() + bottle = 0 + update_icon() + else + if(anchored) + user.visible_message("\The [user] begins unsecuring \the [src] from the floor.", "You start unsecuring \the [src] from the floor.") + else + user.visible_message("\The [user] begins securing \the [src] to the floor.", "You start securing \the [src] to the floor.") + if(do_after(user, 20 * I.toolspeed, src)) + if(!src) return + to_chat(user, "You [anchored? "un" : ""]secured \the [src]!") + anchored = !anchored + playsound(src, I.usesound, 50, 1) + return + + if(I.is_screwdriver()) + if(cupholder) + playsound(src, I.usesound, 50, 1) + to_chat(user, "You take the cup dispenser off.") + new /obj/item/stack/material/plastic( src.loc ) + if(cups) + for(var/i = 0 to cups) + new /obj/item/weapon/reagent_containers/food/drinks/sillycup(src.loc) + cups = 0 + cupholder = 0 + update_icon() + return + if(!bottle && !cupholder) + playsound(src, I.usesound, 50, 1) + to_chat(user, "You start taking the water-cooler apart.") + if(do_after(user, 20 * I.toolspeed) && !bottle && !cupholder) + to_chat(user, "You take the water-cooler apart.") + new /obj/item/stack/material/plastic( src.loc, 4 ) + qdel(src) + return + + if(istype(I, /obj/item/weapon/reagent_containers/glass/cooler_bottle)) + src.add_fingerprint(user) + if(!bottle) + if(anchored) + var/obj/item/weapon/reagent_containers/glass/cooler_bottle/G = I + to_chat(user, "You start to screw the bottle onto the water-cooler.") + if(do_after(user, 20) && !bottle && anchored) + bottle = 1 + update_icon() + to_chat(user, "You screw the bottle onto the water-cooler!") + for(var/datum/reagent/R in G.reagents.reagent_list) + var/total_reagent = G.reagents.get_reagent_amount(R.id) + reagents.add_reagent(R.id, total_reagent) + qdel(G) + else + to_chat(user, "You need to wrench down the cooler first.") + else + to_chat(user, "There is already a bottle there!") + return 1 + + if(istype(I, /obj/item/stack/material/plastic)) + if(!cupholder) + if(anchored) + var/obj/item/stack/material/plastic/P = I + src.add_fingerprint(user) + to_chat(user, "You start to attach a cup dispenser onto the water-cooler.") + playsound(src, 'sound/items/Deconstruct.ogg', 50, 1) + if(do_after(user, 20) && !cupholder && anchored) + if (P.use(1)) + to_chat(user, "You attach a cup dispenser onto the water-cooler.") + cupholder = 1 + update_icon() + else + to_chat(user, "You need to wrench down the cooler first.") + else + to_chat(user, "There is already a cup dispenser there!") + return + +/obj/structure/reagent_dispensers/water_cooler/attack_hand(mob/user) + if(cups) + new /obj/item/weapon/reagent_containers/food/drinks/sillycup(src.loc) + cups-- + flick("[icon_state]-vend", src) + return + +/obj/structure/reagent_dispensers/water_cooler/update_icon() + icon_state = "water_cooler" + overlays.Cut() + var/image/I + if(bottle) + I = image(icon, "water_cooler_bottle") + overlays += I + return + +/obj/structure/reagent_dispensers/beerkeg + name = "beer keg" + desc = "A beer keg." + icon = 'icons/obj/objects.dmi' + icon_state = "beertankTEMP" + amount_per_transfer_from_this = 10 + +/obj/structure/reagent_dispensers/beerkeg/Initialize() + . = ..() + reagents.add_reagent("beer",1000) + +/obj/structure/reagent_dispensers/beerkeg/fakenuke + name = "nuclear beer keg" + desc = "A beer keg in the form of a nuclear bomb! An absolute blast at parties!" + icon = 'icons/obj/stationobjs.dmi' + icon_state = "nuclearbomb0" + +/obj/structure/reagent_dispensers/virusfood + name = "Virus Food Dispenser" + desc = "A dispenser of virus food. Yum." + icon = 'icons/obj/objects.dmi' + icon_state = "virusfoodtank" + amount_per_transfer_from_this = 10 + anchored = 1 + +/obj/structure/reagent_dispensers/virusfood/Initialize() + . = ..() + reagents.add_reagent("virusfood", 1000) + +/obj/structure/reagent_dispensers/acid + name = "Sulphuric Acid Dispenser" + desc = "A dispenser of acid for industrial processes." + icon = 'icons/obj/objects.dmi' + icon_state = "acidtank" + amount_per_transfer_from_this = 10 + anchored = 1 + +/obj/structure/reagent_dispensers/acid/Initialize() + . = ..() + reagents.add_reagent("sacid", 1000) + +//Cooking oil refill tank +/obj/structure/reagent_dispensers/cookingoil + name = "cooking oil tank" + desc = "A fifty-litre tank of commercial-grade corn oil, intended for use in large scale deep fryers. Store in a cool, dark place" + icon = 'icons/obj/objects.dmi' + icon_state = "oiltank" + amount_per_transfer_from_this = 120 + +/obj/structure/reagent_dispensers/cookingoil/New() + ..() + reagents.add_reagent("cornoil",5000) + +/obj/structure/reagent_dispensers/cookingoil/bullet_act(var/obj/item/projectile/Proj) + if(Proj.get_structure_damage()) + explode() + +/obj/structure/reagent_dispensers/cookingoil/ex_act() + explode() + +/obj/structure/reagent_dispensers/cookingoil/proc/explode() + reagents.splash_area(get_turf(src), 3) + visible_message(span("danger", "The [src] bursts open, spreading oil all over the area.")) + qdel(src) + +/obj/structure/reagent_dispensers/he3 + name = "fueltank" + desc = "A fueltank." + icon = 'icons/obj/objects.dmi' + icon_state = "weldtank" + amount_per_transfer_from_this = 10 + +/obj/structure/reagent_dispenser/he3/Initialize() + ..() + reagents.add_reagent("helium3",1000) diff --git a/code/modules/reagents/dispenser/supply.dm b/code/modules/reagents/machinery/dispenser/supply.dm similarity index 98% rename from code/modules/reagents/dispenser/supply.dm rename to code/modules/reagents/machinery/dispenser/supply.dm index 228c5dfeeff..30b1c3c0f63 100644 --- a/code/modules/reagents/dispenser/supply.dm +++ b/code/modules/reagents/machinery/dispenser/supply.dm @@ -1,238 +1,238 @@ -/datum/supply_pack/chemistry_dispenser - name = "Reagent dispenser" - contains = list( - /obj/machinery/chemical_dispenser{anchored = 0} - ) - cost = 25 - containertype = /obj/structure/largecrate - containername = "reagent dispenser crate" - group = "Reagents" - -/datum/supply_pack/beer_dispenser - name = "Booze dispenser" - contains = list( - /obj/machinery/chemical_dispenser/bar_alc{anchored = 0} - ) - cost = 25 - containertype = /obj/structure/largecrate - containername = "booze dispenser crate" - group = "Reagents" - -/datum/supply_pack/soda_dispenser - name = "Soda dispenser" - contains = list( - /obj/machinery/chemical_dispenser/bar_soft{anchored = 0} - ) - cost = 25 - containertype = /obj/structure/largecrate - containername = "soda dispenser crate" - group = "Reagents" - -/datum/supply_pack/reagents - name = "Chemistry dispenser refill" - contains = list( - /obj/item/weapon/reagent_containers/chem_disp_cartridge/hydrogen, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/lithium, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/carbon, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/nitrogen, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/oxygen, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/fluorine, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/sodium, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/aluminum, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/silicon, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/phosphorus, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/sulfur, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/chlorine, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/potassium, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/iron, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/copper, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/mercury, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/radium, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/water, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/ethanol, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/sugar, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/sacid, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/tungsten - ) - cost = 150 - containertype = /obj/structure/closet/crate/secure - containername = "chemical crate" - access = list(access_chemistry) - group = "Reagents" - -/datum/supply_pack/alcohol_reagents - name = "Bar alcoholic dispenser refill" - contains = list( - /obj/item/weapon/reagent_containers/chem_disp_cartridge/beer, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/kahlua, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/whiskey, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/wine, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/vodka, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/gin, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/rum, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/tequila, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/vermouth, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/cognac, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/ale, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/mead, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/bitters - ) - cost = 50 - containertype = /obj/structure/closet/crate/secure - containername = "alcoholic drinks crate" - access = list(access_bar) - group = "Reagents" - -/datum/supply_pack/softdrink_reagents - name = "Bar soft drink dispenser refill" - contains = list( - /obj/item/weapon/reagent_containers/chem_disp_cartridge/water, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/ice, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/coffee, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/cream, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/tea, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/icetea, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/cola, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/smw, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/dr_gibb, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/spaceup, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/tonic, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/sodawater, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon_lime, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/sugar, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/orange, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/lime, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/watermelon, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon - ) - cost = 50 - containertype = /obj/structure/closet/crate - containername = "soft drinks crate" - group = "Reagents" - -/datum/supply_pack/coffee_reagents - name = "Coffee machine dispenser refill" - contains = list( - /obj/item/weapon/reagent_containers/chem_disp_cartridge/coffee, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/cafe_latte, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/soy_latte, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/hot_coco, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/milk, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/cream, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/tea, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/ice - ) - cost = 50 - containertype = /obj/structure/closet/crate - containername = "coffee drinks crate" - group = "Reagents" - -/datum/supply_pack/dispenser_cartridges - name = "Empty dispenser cartridges" - contains = list( - /obj/item/weapon/reagent_containers/chem_disp_cartridge, - /obj/item/weapon/reagent_containers/chem_disp_cartridge, - /obj/item/weapon/reagent_containers/chem_disp_cartridge, - /obj/item/weapon/reagent_containers/chem_disp_cartridge, - /obj/item/weapon/reagent_containers/chem_disp_cartridge, - /obj/item/weapon/reagent_containers/chem_disp_cartridge, - /obj/item/weapon/reagent_containers/chem_disp_cartridge, - /obj/item/weapon/reagent_containers/chem_disp_cartridge, - /obj/item/weapon/reagent_containers/chem_disp_cartridge, - /obj/item/weapon/reagent_containers/chem_disp_cartridge - ) - cost = 15 - containertype = /obj/structure/closet/crate - containername = "dispenser cartridge crate" - group = "Reagents" - -#define SEC_PACK(_tname, _type, _name, _cname, _cost, _access)\ - datum/supply_pack/dispenser_cartridges{\ - _tname {\ - name = _name ;\ - containername = _cname ;\ - containertype = /obj/structure/closet/crate/secure;\ - access = list( _access );\ - cost = _cost ;\ - contains = list( _type , _type );\ - group = "Reagent Cartridges"\ - }\ - } -#define PACK(_tname, _type, _name, _cname, _cost)\ - datum/supply_pack/dispenser_cartridges{\ - _tname {\ - name = _name ;\ - containername = _cname ;\ - containertype = /obj/structure/closet/crate;\ - cost = _cost ;\ - contains = list( _type , _type );\ - group = "Reagent Cartridges"\ - }\ - } - -// Chemistry-restricted (raw reagents excluding sugar/water) -// Datum path Contents type Supply pack name Container name Cost Container access -SEC_PACK(hydrogen, /obj/item/weapon/reagent_containers/chem_disp_cartridge/hydrogen, "Reagent refill - Hydrogen", "hydrogen reagent cartridge crate", 15, access_chemistry) -SEC_PACK(lithium, /obj/item/weapon/reagent_containers/chem_disp_cartridge/lithium, "Reagent refill - Lithium", "lithium reagent cartridge crate", 15, access_chemistry) -SEC_PACK(carbon, /obj/item/weapon/reagent_containers/chem_disp_cartridge/carbon, "Reagent refill - Carbon", "carbon reagent cartridge crate", 15, access_chemistry) -SEC_PACK(nitrogen, /obj/item/weapon/reagent_containers/chem_disp_cartridge/nitrogen, "Reagent refill - Nitrogen", "nitrogen reagent cartridge crate", 15, access_chemistry) -SEC_PACK(oxygen, /obj/item/weapon/reagent_containers/chem_disp_cartridge/oxygen, "Reagent refill - Oxygen", "oxygen reagent cartridge crate", 15, access_chemistry) -SEC_PACK(fluorine, /obj/item/weapon/reagent_containers/chem_disp_cartridge/fluorine, "Reagent refill - Fluorine", "fluorine reagent cartridge crate", 15, access_chemistry) -SEC_PACK(sodium, /obj/item/weapon/reagent_containers/chem_disp_cartridge/sodium, "Reagent refill - Sodium", "sodium reagent cartridge crate", 15, access_chemistry) -SEC_PACK(aluminium, /obj/item/weapon/reagent_containers/chem_disp_cartridge/aluminum, "Reagent refill - Aluminum", "aluminum reagent cartridge crate", 15, access_chemistry) -SEC_PACK(silicon, /obj/item/weapon/reagent_containers/chem_disp_cartridge/silicon, "Reagent refill - Silicon", "silicon reagent cartridge crate", 15, access_chemistry) -SEC_PACK(phosphorus,/obj/item/weapon/reagent_containers/chem_disp_cartridge/phosphorus, "Reagent refill - Phosphorus", "phosphorus reagent cartridge crate", 15, access_chemistry) -SEC_PACK(sulfur, /obj/item/weapon/reagent_containers/chem_disp_cartridge/sulfur, "Reagent refill - Sulfur", "sulfur reagent cartridge crate", 15, access_chemistry) -SEC_PACK(chlorine, /obj/item/weapon/reagent_containers/chem_disp_cartridge/chlorine, "Reagent refill - Chlorine", "chlorine reagent cartridge crate", 15, access_chemistry) -SEC_PACK(potassium, /obj/item/weapon/reagent_containers/chem_disp_cartridge/potassium, "Reagent refill - Potassium", "potassium reagent cartridge crate", 15, access_chemistry) -SEC_PACK(iron, /obj/item/weapon/reagent_containers/chem_disp_cartridge/iron, "Reagent refill - Iron", "iron reagent cartridge crate", 15, access_chemistry) -SEC_PACK(copper, /obj/item/weapon/reagent_containers/chem_disp_cartridge/copper, "Reagent refill - Copper", "copper reagent cartridge crate", 15, access_chemistry) -SEC_PACK(mercury, /obj/item/weapon/reagent_containers/chem_disp_cartridge/mercury, "Reagent refill - Mercury", "mercury reagent cartridge crate", 15, access_chemistry) -SEC_PACK(radium, /obj/item/weapon/reagent_containers/chem_disp_cartridge/radium, "Reagent refill - Radium", "radium reagent cartridge crate", 15, access_chemistry) -SEC_PACK(ethanol, /obj/item/weapon/reagent_containers/chem_disp_cartridge/ethanol, "Reagent refill - Ethanol", "ethanol reagent cartridge crate", 15, access_chemistry) -SEC_PACK(sacid, /obj/item/weapon/reagent_containers/chem_disp_cartridge/sacid, "Reagent refill - Sulfuric Acid", "sulfuric acid reagent cartridge crate", 15, access_chemistry) -SEC_PACK(tungsten, /obj/item/weapon/reagent_containers/chem_disp_cartridge/tungsten, "Reagent refill - Tungsten", "tungsten reagent cartridge crate", 15, access_chemistry) -SEC_PACK(calcium, /obj/item/weapon/reagent_containers/chem_disp_cartridge/calcium, "Reagent refill - Calcium", "calcium reagent cartridge crate", 15, access_chemistry) - -// Bar-restricted (alcoholic drinks) -// Datum path Contents type Supply pack name Container name Cost Container access -SEC_PACK(beer, /obj/item/weapon/reagent_containers/chem_disp_cartridge/beer, "Reagent refill - Beer", "beer reagent cartridge crate", 15, access_bar) -SEC_PACK(kahlua, /obj/item/weapon/reagent_containers/chem_disp_cartridge/kahlua, "Reagent refill - Kahlua", "kahlua reagent cartridge crate", 15, access_bar) -SEC_PACK(whiskey, /obj/item/weapon/reagent_containers/chem_disp_cartridge/whiskey, "Reagent refill - Whiskey", "whiskey reagent cartridge crate", 15, access_bar) -SEC_PACK(wine, /obj/item/weapon/reagent_containers/chem_disp_cartridge/wine, "Reagent refill - Wine", "wine reagent cartridge crate", 15, access_bar) -SEC_PACK(vodka, /obj/item/weapon/reagent_containers/chem_disp_cartridge/vodka, "Reagent refill - Vodka", "vodka reagent cartridge crate", 15, access_bar) -SEC_PACK(gin, /obj/item/weapon/reagent_containers/chem_disp_cartridge/gin, "Reagent refill - Gin", "gin reagent cartridge crate", 15, access_bar) -SEC_PACK(rum, /obj/item/weapon/reagent_containers/chem_disp_cartridge/rum, "Reagent refill - Rum", "rum reagent cartridge crate", 15, access_bar) -SEC_PACK(tequila, /obj/item/weapon/reagent_containers/chem_disp_cartridge/tequila, "Reagent refill - Tequila", "tequila reagent cartridge crate", 15, access_bar) -SEC_PACK(vermouth, /obj/item/weapon/reagent_containers/chem_disp_cartridge/vermouth, "Reagent refill - Vermouth", "vermouth reagent cartridge crate", 15, access_bar) -SEC_PACK(cognac, /obj/item/weapon/reagent_containers/chem_disp_cartridge/cognac, "Reagent refill - Cognac", "cognac reagent cartridge crate", 15, access_bar) -SEC_PACK(ale, /obj/item/weapon/reagent_containers/chem_disp_cartridge/ale, "Reagent refill - Ale", "ale reagent cartridge crate", 15, access_bar) -SEC_PACK(mead, /obj/item/weapon/reagent_containers/chem_disp_cartridge/mead, "Reagent refill - Mead", "mead reagent cartridge crate", 15, access_bar) - -// Unrestricted (water, sugar, non-alcoholic drinks) -// Datum path Contents type Supply pack name Container name Cost -PACK(water, /obj/item/weapon/reagent_containers/chem_disp_cartridge/water, "Reagent refill - Water", "water reagent cartridge crate", 15) -PACK(sugar, /obj/item/weapon/reagent_containers/chem_disp_cartridge/sugar, "Reagent refill - Sugar", "sugar reagent cartridge crate", 15) -PACK(ice, /obj/item/weapon/reagent_containers/chem_disp_cartridge/ice, "Reagent refill - Ice", "ice reagent cartridge crate", 15) -PACK(tea, /obj/item/weapon/reagent_containers/chem_disp_cartridge/tea, "Reagent refill - Tea", "tea reagent cartridge crate", 15) -PACK(icetea, /obj/item/weapon/reagent_containers/chem_disp_cartridge/icetea, "Reagent refill - Iced Tea", "iced tea reagent cartridge crate", 15) -PACK(cola, /obj/item/weapon/reagent_containers/chem_disp_cartridge/cola, "Reagent refill - Space Cola", "\improper Space Cola reagent cartridge crate", 15) -PACK(smw, /obj/item/weapon/reagent_containers/chem_disp_cartridge/smw, "Reagent refill - Space Mountain Wind", "\improper Space Mountain Wind reagent cartridge crate", 15) -PACK(dr_gibb, /obj/item/weapon/reagent_containers/chem_disp_cartridge/dr_gibb, "Reagent refill - Dr. Gibb", "\improper Dr. Gibb reagent cartridge crate", 15) -PACK(spaceup, /obj/item/weapon/reagent_containers/chem_disp_cartridge/spaceup, "Reagent refill - Space-Up", "\improper Space-Up reagent cartridge crate", 15) -PACK(tonic, /obj/item/weapon/reagent_containers/chem_disp_cartridge/tonic, "Reagent refill - Tonic Water", "tonic water reagent cartridge crate", 15) -PACK(sodawater, /obj/item/weapon/reagent_containers/chem_disp_cartridge/sodawater, "Reagent refill - Soda Water", "soda water reagent cartridge crate", 15) -PACK(lemon_lime, /obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon_lime, "Reagent refill - Lemon-Lime Juice", "lemon-lime juice reagent cartridge crate", 15) -PACK(orange, /obj/item/weapon/reagent_containers/chem_disp_cartridge/orange, "Reagent refill - Orange Juice", "orange juice reagent cartridge crate", 15) -PACK(lime, /obj/item/weapon/reagent_containers/chem_disp_cartridge/lime, "Reagent refill - Lime Juice", "lime juice reagent cartridge crate", 15) -PACK(lemon, /obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon, "Reagent refill - Lemon Juice", "lemon juice reagent cartridge crate", 15) -PACK(watermelon, /obj/item/weapon/reagent_containers/chem_disp_cartridge/watermelon, "Reagent refill - Watermelon Juice", "watermelon juice reagent cartridge crate", 15) -PACK(coffee, /obj/item/weapon/reagent_containers/chem_disp_cartridge/coffee, "Reagent refill - Coffee", "coffee reagent cartridge crate", 15) -PACK(cafe_latte, /obj/item/weapon/reagent_containers/chem_disp_cartridge/cafe_latte, "Reagent refill - Cafe Latte", "cafe latte reagent cartridge crate", 15) -PACK(soy_latte, /obj/item/weapon/reagent_containers/chem_disp_cartridge/soy_latte, "Reagent refill - Soy Latte", "soy latte reagent cartridge crate", 15) -PACK(hot_coco, /obj/item/weapon/reagent_containers/chem_disp_cartridge/hot_coco, "Reagent refill - Hot Coco", "hot coco reagent cartridge crate", 15) -PACK(milk, /obj/item/weapon/reagent_containers/chem_disp_cartridge/milk, "Reagent refill - Milk", "milk reagent cartridge crate", 15) -PACK(cream, /obj/item/weapon/reagent_containers/chem_disp_cartridge/cream, "Reagent refill - Cream", "cream reagent cartridge crate", 15) - -#undef SEC_PACK -#undef PACK +/datum/supply_pack/chemistry_dispenser + name = "Reagent dispenser" + contains = list( + /obj/machinery/chemical_dispenser{anchored = 0} + ) + cost = 25 + containertype = /obj/structure/largecrate + containername = "reagent dispenser crate" + group = "Reagents" + +/datum/supply_pack/beer_dispenser + name = "Booze dispenser" + contains = list( + /obj/machinery/chemical_dispenser/bar_alc{anchored = 0} + ) + cost = 25 + containertype = /obj/structure/largecrate + containername = "booze dispenser crate" + group = "Reagents" + +/datum/supply_pack/soda_dispenser + name = "Soda dispenser" + contains = list( + /obj/machinery/chemical_dispenser/bar_soft{anchored = 0} + ) + cost = 25 + containertype = /obj/structure/largecrate + containername = "soda dispenser crate" + group = "Reagents" + +/datum/supply_pack/reagents + name = "Chemistry dispenser refill" + contains = list( + /obj/item/weapon/reagent_containers/chem_disp_cartridge/hydrogen, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/lithium, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/carbon, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/nitrogen, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/oxygen, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/fluorine, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/sodium, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/aluminum, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/silicon, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/phosphorus, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/sulfur, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/chlorine, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/potassium, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/iron, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/copper, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/mercury, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/radium, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/water, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/ethanol, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/sugar, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/sacid, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/tungsten + ) + cost = 150 + containertype = /obj/structure/closet/crate/secure + containername = "chemical crate" + access = list(access_chemistry) + group = "Reagents" + +/datum/supply_pack/alcohol_reagents + name = "Bar alcoholic dispenser refill" + contains = list( + /obj/item/weapon/reagent_containers/chem_disp_cartridge/beer, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/kahlua, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/whiskey, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/wine, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/vodka, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/gin, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/rum, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/tequila, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/vermouth, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/cognac, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/ale, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/mead, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/bitters + ) + cost = 50 + containertype = /obj/structure/closet/crate/secure + containername = "alcoholic drinks crate" + access = list(access_bar) + group = "Reagents" + +/datum/supply_pack/softdrink_reagents + name = "Bar soft drink dispenser refill" + contains = list( + /obj/item/weapon/reagent_containers/chem_disp_cartridge/water, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/ice, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/coffee, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/cream, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/tea, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/icetea, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/cola, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/smw, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/dr_gibb, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/spaceup, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/tonic, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/sodawater, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon_lime, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/sugar, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/orange, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/lime, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/watermelon, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon + ) + cost = 50 + containertype = /obj/structure/closet/crate + containername = "soft drinks crate" + group = "Reagents" + +/datum/supply_pack/coffee_reagents + name = "Coffee machine dispenser refill" + contains = list( + /obj/item/weapon/reagent_containers/chem_disp_cartridge/coffee, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/cafe_latte, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/soy_latte, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/hot_coco, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/milk, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/cream, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/tea, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/ice + ) + cost = 50 + containertype = /obj/structure/closet/crate + containername = "coffee drinks crate" + group = "Reagents" + +/datum/supply_pack/dispenser_cartridges + name = "Empty dispenser cartridges" + contains = list( + /obj/item/weapon/reagent_containers/chem_disp_cartridge, + /obj/item/weapon/reagent_containers/chem_disp_cartridge, + /obj/item/weapon/reagent_containers/chem_disp_cartridge, + /obj/item/weapon/reagent_containers/chem_disp_cartridge, + /obj/item/weapon/reagent_containers/chem_disp_cartridge, + /obj/item/weapon/reagent_containers/chem_disp_cartridge, + /obj/item/weapon/reagent_containers/chem_disp_cartridge, + /obj/item/weapon/reagent_containers/chem_disp_cartridge, + /obj/item/weapon/reagent_containers/chem_disp_cartridge, + /obj/item/weapon/reagent_containers/chem_disp_cartridge + ) + cost = 15 + containertype = /obj/structure/closet/crate + containername = "dispenser cartridge crate" + group = "Reagents" + +#define SEC_PACK(_tname, _type, _name, _cname, _cost, _access)\ + datum/supply_pack/dispenser_cartridges{\ + _tname {\ + name = _name ;\ + containername = _cname ;\ + containertype = /obj/structure/closet/crate/secure;\ + access = list( _access );\ + cost = _cost ;\ + contains = list( _type , _type );\ + group = "Reagent Cartridges"\ + }\ + } +#define PACK(_tname, _type, _name, _cname, _cost)\ + datum/supply_pack/dispenser_cartridges{\ + _tname {\ + name = _name ;\ + containername = _cname ;\ + containertype = /obj/structure/closet/crate;\ + cost = _cost ;\ + contains = list( _type , _type );\ + group = "Reagent Cartridges"\ + }\ + } + +// Chemistry-restricted (raw reagents excluding sugar/water) +// Datum path Contents type Supply pack name Container name Cost Container access +SEC_PACK(hydrogen, /obj/item/weapon/reagent_containers/chem_disp_cartridge/hydrogen, "Reagent refill - Hydrogen", "hydrogen reagent cartridge crate", 15, access_chemistry) +SEC_PACK(lithium, /obj/item/weapon/reagent_containers/chem_disp_cartridge/lithium, "Reagent refill - Lithium", "lithium reagent cartridge crate", 15, access_chemistry) +SEC_PACK(carbon, /obj/item/weapon/reagent_containers/chem_disp_cartridge/carbon, "Reagent refill - Carbon", "carbon reagent cartridge crate", 15, access_chemistry) +SEC_PACK(nitrogen, /obj/item/weapon/reagent_containers/chem_disp_cartridge/nitrogen, "Reagent refill - Nitrogen", "nitrogen reagent cartridge crate", 15, access_chemistry) +SEC_PACK(oxygen, /obj/item/weapon/reagent_containers/chem_disp_cartridge/oxygen, "Reagent refill - Oxygen", "oxygen reagent cartridge crate", 15, access_chemistry) +SEC_PACK(fluorine, /obj/item/weapon/reagent_containers/chem_disp_cartridge/fluorine, "Reagent refill - Fluorine", "fluorine reagent cartridge crate", 15, access_chemistry) +SEC_PACK(sodium, /obj/item/weapon/reagent_containers/chem_disp_cartridge/sodium, "Reagent refill - Sodium", "sodium reagent cartridge crate", 15, access_chemistry) +SEC_PACK(aluminium, /obj/item/weapon/reagent_containers/chem_disp_cartridge/aluminum, "Reagent refill - Aluminum", "aluminum reagent cartridge crate", 15, access_chemistry) +SEC_PACK(silicon, /obj/item/weapon/reagent_containers/chem_disp_cartridge/silicon, "Reagent refill - Silicon", "silicon reagent cartridge crate", 15, access_chemistry) +SEC_PACK(phosphorus,/obj/item/weapon/reagent_containers/chem_disp_cartridge/phosphorus, "Reagent refill - Phosphorus", "phosphorus reagent cartridge crate", 15, access_chemistry) +SEC_PACK(sulfur, /obj/item/weapon/reagent_containers/chem_disp_cartridge/sulfur, "Reagent refill - Sulfur", "sulfur reagent cartridge crate", 15, access_chemistry) +SEC_PACK(chlorine, /obj/item/weapon/reagent_containers/chem_disp_cartridge/chlorine, "Reagent refill - Chlorine", "chlorine reagent cartridge crate", 15, access_chemistry) +SEC_PACK(potassium, /obj/item/weapon/reagent_containers/chem_disp_cartridge/potassium, "Reagent refill - Potassium", "potassium reagent cartridge crate", 15, access_chemistry) +SEC_PACK(iron, /obj/item/weapon/reagent_containers/chem_disp_cartridge/iron, "Reagent refill - Iron", "iron reagent cartridge crate", 15, access_chemistry) +SEC_PACK(copper, /obj/item/weapon/reagent_containers/chem_disp_cartridge/copper, "Reagent refill - Copper", "copper reagent cartridge crate", 15, access_chemistry) +SEC_PACK(mercury, /obj/item/weapon/reagent_containers/chem_disp_cartridge/mercury, "Reagent refill - Mercury", "mercury reagent cartridge crate", 15, access_chemistry) +SEC_PACK(radium, /obj/item/weapon/reagent_containers/chem_disp_cartridge/radium, "Reagent refill - Radium", "radium reagent cartridge crate", 15, access_chemistry) +SEC_PACK(ethanol, /obj/item/weapon/reagent_containers/chem_disp_cartridge/ethanol, "Reagent refill - Ethanol", "ethanol reagent cartridge crate", 15, access_chemistry) +SEC_PACK(sacid, /obj/item/weapon/reagent_containers/chem_disp_cartridge/sacid, "Reagent refill - Sulfuric Acid", "sulfuric acid reagent cartridge crate", 15, access_chemistry) +SEC_PACK(tungsten, /obj/item/weapon/reagent_containers/chem_disp_cartridge/tungsten, "Reagent refill - Tungsten", "tungsten reagent cartridge crate", 15, access_chemistry) +SEC_PACK(calcium, /obj/item/weapon/reagent_containers/chem_disp_cartridge/calcium, "Reagent refill - Calcium", "calcium reagent cartridge crate", 15, access_chemistry) + +// Bar-restricted (alcoholic drinks) +// Datum path Contents type Supply pack name Container name Cost Container access +SEC_PACK(beer, /obj/item/weapon/reagent_containers/chem_disp_cartridge/beer, "Reagent refill - Beer", "beer reagent cartridge crate", 15, access_bar) +SEC_PACK(kahlua, /obj/item/weapon/reagent_containers/chem_disp_cartridge/kahlua, "Reagent refill - Kahlua", "kahlua reagent cartridge crate", 15, access_bar) +SEC_PACK(whiskey, /obj/item/weapon/reagent_containers/chem_disp_cartridge/whiskey, "Reagent refill - Whiskey", "whiskey reagent cartridge crate", 15, access_bar) +SEC_PACK(wine, /obj/item/weapon/reagent_containers/chem_disp_cartridge/wine, "Reagent refill - Wine", "wine reagent cartridge crate", 15, access_bar) +SEC_PACK(vodka, /obj/item/weapon/reagent_containers/chem_disp_cartridge/vodka, "Reagent refill - Vodka", "vodka reagent cartridge crate", 15, access_bar) +SEC_PACK(gin, /obj/item/weapon/reagent_containers/chem_disp_cartridge/gin, "Reagent refill - Gin", "gin reagent cartridge crate", 15, access_bar) +SEC_PACK(rum, /obj/item/weapon/reagent_containers/chem_disp_cartridge/rum, "Reagent refill - Rum", "rum reagent cartridge crate", 15, access_bar) +SEC_PACK(tequila, /obj/item/weapon/reagent_containers/chem_disp_cartridge/tequila, "Reagent refill - Tequila", "tequila reagent cartridge crate", 15, access_bar) +SEC_PACK(vermouth, /obj/item/weapon/reagent_containers/chem_disp_cartridge/vermouth, "Reagent refill - Vermouth", "vermouth reagent cartridge crate", 15, access_bar) +SEC_PACK(cognac, /obj/item/weapon/reagent_containers/chem_disp_cartridge/cognac, "Reagent refill - Cognac", "cognac reagent cartridge crate", 15, access_bar) +SEC_PACK(ale, /obj/item/weapon/reagent_containers/chem_disp_cartridge/ale, "Reagent refill - Ale", "ale reagent cartridge crate", 15, access_bar) +SEC_PACK(mead, /obj/item/weapon/reagent_containers/chem_disp_cartridge/mead, "Reagent refill - Mead", "mead reagent cartridge crate", 15, access_bar) + +// Unrestricted (water, sugar, non-alcoholic drinks) +// Datum path Contents type Supply pack name Container name Cost +PACK(water, /obj/item/weapon/reagent_containers/chem_disp_cartridge/water, "Reagent refill - Water", "water reagent cartridge crate", 15) +PACK(sugar, /obj/item/weapon/reagent_containers/chem_disp_cartridge/sugar, "Reagent refill - Sugar", "sugar reagent cartridge crate", 15) +PACK(ice, /obj/item/weapon/reagent_containers/chem_disp_cartridge/ice, "Reagent refill - Ice", "ice reagent cartridge crate", 15) +PACK(tea, /obj/item/weapon/reagent_containers/chem_disp_cartridge/tea, "Reagent refill - Tea", "tea reagent cartridge crate", 15) +PACK(icetea, /obj/item/weapon/reagent_containers/chem_disp_cartridge/icetea, "Reagent refill - Iced Tea", "iced tea reagent cartridge crate", 15) +PACK(cola, /obj/item/weapon/reagent_containers/chem_disp_cartridge/cola, "Reagent refill - Space Cola", "\improper Space Cola reagent cartridge crate", 15) +PACK(smw, /obj/item/weapon/reagent_containers/chem_disp_cartridge/smw, "Reagent refill - Space Mountain Wind", "\improper Space Mountain Wind reagent cartridge crate", 15) +PACK(dr_gibb, /obj/item/weapon/reagent_containers/chem_disp_cartridge/dr_gibb, "Reagent refill - Dr. Gibb", "\improper Dr. Gibb reagent cartridge crate", 15) +PACK(spaceup, /obj/item/weapon/reagent_containers/chem_disp_cartridge/spaceup, "Reagent refill - Space-Up", "\improper Space-Up reagent cartridge crate", 15) +PACK(tonic, /obj/item/weapon/reagent_containers/chem_disp_cartridge/tonic, "Reagent refill - Tonic Water", "tonic water reagent cartridge crate", 15) +PACK(sodawater, /obj/item/weapon/reagent_containers/chem_disp_cartridge/sodawater, "Reagent refill - Soda Water", "soda water reagent cartridge crate", 15) +PACK(lemon_lime, /obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon_lime, "Reagent refill - Lemon-Lime Juice", "lemon-lime juice reagent cartridge crate", 15) +PACK(orange, /obj/item/weapon/reagent_containers/chem_disp_cartridge/orange, "Reagent refill - Orange Juice", "orange juice reagent cartridge crate", 15) +PACK(lime, /obj/item/weapon/reagent_containers/chem_disp_cartridge/lime, "Reagent refill - Lime Juice", "lime juice reagent cartridge crate", 15) +PACK(lemon, /obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon, "Reagent refill - Lemon Juice", "lemon juice reagent cartridge crate", 15) +PACK(watermelon, /obj/item/weapon/reagent_containers/chem_disp_cartridge/watermelon, "Reagent refill - Watermelon Juice", "watermelon juice reagent cartridge crate", 15) +PACK(coffee, /obj/item/weapon/reagent_containers/chem_disp_cartridge/coffee, "Reagent refill - Coffee", "coffee reagent cartridge crate", 15) +PACK(cafe_latte, /obj/item/weapon/reagent_containers/chem_disp_cartridge/cafe_latte, "Reagent refill - Cafe Latte", "cafe latte reagent cartridge crate", 15) +PACK(soy_latte, /obj/item/weapon/reagent_containers/chem_disp_cartridge/soy_latte, "Reagent refill - Soy Latte", "soy latte reagent cartridge crate", 15) +PACK(hot_coco, /obj/item/weapon/reagent_containers/chem_disp_cartridge/hot_coco, "Reagent refill - Hot Coco", "hot coco reagent cartridge crate", 15) +PACK(milk, /obj/item/weapon/reagent_containers/chem_disp_cartridge/milk, "Reagent refill - Milk", "milk reagent cartridge crate", 15) +PACK(cream, /obj/item/weapon/reagent_containers/chem_disp_cartridge/cream, "Reagent refill - Cream", "cream reagent cartridge crate", 15) + +#undef SEC_PACK +#undef PACK diff --git a/code/modules/reagents/distilling/distilling.dm b/code/modules/reagents/machinery/distillery.dm similarity index 92% rename from code/modules/reagents/distilling/distilling.dm rename to code/modules/reagents/machinery/distillery.dm index 4bd8bd163ee..d64d8b32114 100644 --- a/code/modules/reagents/distilling/distilling.dm +++ b/code/modules/reagents/machinery/distillery.dm @@ -53,31 +53,16 @@ var/image/overlay_dumping var/image/overlay_connected -// Our unique beaker, used in its unique recipes to ensure things can only react inside this machine and minimize oddities from trying to transfer to a machine and back. - var/obj/item/weapon/reagent_containers/glass/distilling/Reservoir - var/obj/item/weapon/reagent_containers/glass/InputBeaker var/obj/item/weapon/reagent_containers/glass/OutputBeaker // A multiplier for the production amount. This should really only ever be lower than one, otherwise you end up with duping. var/efficiency = 1 -/obj/item/weapon/reagent_containers/glass/distilling - name = "distilling chamber" - desc = "You should not be seeing this." - volume = 600 - - var/obj/machinery/portable_atmospherics/powered/reagent_distillery/Master - -/obj/item/weapon/reagent_containers/glass/distilling/Destroy() - Master = null - ..() - /obj/machinery/portable_atmospherics/powered/reagent_distillery/Initialize() . = ..() - Reservoir = new (src) - Reservoir.Master = src + create_reagents(600, /datum/reagents/distilling) if(!base_state) base_state = icon_state @@ -107,8 +92,6 @@ overlay_connected = image(icon = src.icon, icon_state = "[base_state]-connector") /obj/machinery/portable_atmospherics/powered/reagent_distillery/Destroy() - qdel(Reservoir) - Reservoir = null if(InputBeaker) qdel(InputBeaker) InputBeaker = null @@ -134,8 +117,8 @@ else . += "\The [src]'s input beaker is empty!" - if(Reservoir.reagents.reagent_list.len) - . += "\The [src]'s internal buffer holds [Reservoir.reagents.total_volume] units of liquid." + if(reagents.reagent_list.len) + . += "\The [src]'s internal buffer holds [reagents.total_volume] units of liquid." else . += "\The [src]'s internal buffer is empty!" @@ -164,7 +147,7 @@ to_chat(user, "You press \the [src]'s chamber agitator button.") if(on) visible_message("\The [src] rattles to life.") - Reservoir.reagents.handle_reactions() + reagents.handle_reactions() else spawn(1 SECOND) to_chat(user, "Nothing happens..") @@ -341,12 +324,12 @@ visible_message("\The [src]'s motors wind down.") on = FALSE - if(InputBeaker && Reservoir.reagents.total_volume < Reservoir.reagents.maximum_volume) - InputBeaker.reagents.trans_to_holder(Reservoir.reagents, amount = rand(10,20)) + if(InputBeaker && reagents.total_volume < reagents.maximum_volume) + InputBeaker.reagents.trans_to_holder(reagents, amount = rand(10,20)) if(OutputBeaker && OutputBeaker.reagents.total_volume < OutputBeaker.reagents.maximum_volume) use_power(power_rating * CELLRATE * 0.5) - Reservoir.reagents.trans_to_holder(OutputBeaker.reagents, amount = rand(1, 5)) + reagents.trans_to_holder(OutputBeaker.reagents, amount = rand(1, 5)) update_icon() diff --git a/code/modules/reagents/machinery/grinder.dm b/code/modules/reagents/machinery/grinder.dm new file mode 100644 index 00000000000..f913f7947b2 --- /dev/null +++ b/code/modules/reagents/machinery/grinder.dm @@ -0,0 +1,268 @@ +/obj/machinery/reagentgrinder + + name = "All-In-One Grinder" + desc = "Grinds stuff into itty bitty bits." + icon = 'icons/obj/kitchen.dmi' + icon_state = "juicer1" + density = 0 + anchored = 0 + use_power = USE_POWER_IDLE + idle_power_usage = 5 + active_power_usage = 100 + circuit = /obj/item/weapon/circuitboard/grinder + var/inuse = 0 + var/obj/item/weapon/reagent_containers/beaker = null + var/limit = 10 + var/list/holdingitems = list() + var/list/sheet_reagents = list( //have a number of reageents divisible by REAGENTS_PER_SHEET (default 20) unless you like decimals, + /obj/item/stack/material/iron = list("iron"), + /obj/item/stack/material/uranium = list("uranium"), + /obj/item/stack/material/phoron = list("phoron"), + /obj/item/stack/material/gold = list("gold"), + /obj/item/stack/material/silver = list("silver"), + /obj/item/stack/material/platinum = list("platinum"), + /obj/item/stack/material/mhydrogen = list("hydrogen"), + /obj/item/stack/material/steel = list("iron", "carbon"), + /obj/item/stack/material/plasteel = list("iron", "iron", "carbon", "carbon", "platinum"), //8 iron, 8 carbon, 4 platinum, + /obj/item/stack/material/snow = list("water"), + /obj/item/stack/material/sandstone = list("silicon", "oxygen"), + /obj/item/stack/material/glass = list("silicon"), + /obj/item/stack/material/glass/phoronglass = list("platinum", "silicon", "silicon", "silicon"), //5 platinum, 15 silicon, + ) + + var/static/radial_examine = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_examine") + var/static/radial_eject = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_eject") + var/static/radial_grind = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_grind") + // var/static/radial_juice = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_juice") + // var/static/radial_mix = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_mix") + +/obj/machinery/reagentgrinder/Initialize() + . = ..() + beaker = new /obj/item/weapon/reagent_containers/glass/beaker/large(src) + default_apply_parts() + +/obj/machinery/reagentgrinder/examine(mob/user) + . = ..() + if(!in_range(user, src) && !issilicon(user) && !isobserver(user)) + . += "You're too far away to examine [src]'s contents and display!" + return + + if(inuse) + . += "\The [src] is operating." + return + + if(beaker || length(holdingitems)) + . += "\The [src] contains:" + if(beaker) + . += "- \A [beaker]." + for(var/i in holdingitems) + var/obj/item/O = i + . += "- \A [O.name]." + + if(!(stat & (NOPOWER|BROKEN))) + . += "The status display reads:\n" + if(beaker) + for(var/datum/reagent/R in beaker.reagents.reagent_list) + . += "- [R.volume] units of [R.name]." + +/obj/machinery/reagentgrinder/update_icon() + icon_state = "juicer"+num2text(!isnull(beaker)) + return + +/obj/machinery/reagentgrinder/attackby(var/obj/item/O as obj, var/mob/user as mob) + if(beaker) + if(default_deconstruction_screwdriver(user, O)) + return + if(default_deconstruction_crowbar(user, O)) + return + + //VOREStation edit start - for solargrubs + if (istype(O, /obj/item/device/multitool)) + return ..() + //VOREStation edit end + + if (istype(O,/obj/item/weapon/reagent_containers/glass) || \ + istype(O,/obj/item/weapon/reagent_containers/food/drinks/glass2) || \ + istype(O,/obj/item/weapon/reagent_containers/food/drinks/shaker)) + + if (beaker) + return 1 + else + src.beaker = O + user.drop_item() + O.loc = src + update_icon() + src.updateUsrDialog() + return 0 + + if(holdingitems && holdingitems.len >= limit) + to_chat(user, "The machine cannot hold anymore items.") + return 1 + + if(!istype(O)) + return + + if(istype(O,/obj/item/weapon/storage/bag/plants)) + var/obj/item/weapon/storage/bag/plants/bag = O + var/failed = 1 + for(var/obj/item/G in O.contents) + if(!G.reagents || !G.reagents.total_volume) + continue + failed = 0 + bag.remove_from_storage(G, src) + holdingitems += G + if(holdingitems && holdingitems.len >= limit) + break + + if(failed) + to_chat(user, "Nothing in the plant bag is usable.") + return 1 + + if(!O.contents.len) + to_chat(user, "You empty \the [O] into \the [src].") + else + to_chat(user, "You fill \the [src] from \the [O].") + + src.updateUsrDialog() + return 0 + + if(istype(O,/obj/item/weapon/gripper)) + var/obj/item/weapon/gripper/B = O //B, for Borg. + if(!B.wrapped) + to_chat(user, "\The [B] is not holding anything.") + return 0 + else + var/B_held = B.wrapped + to_chat(user, "You use \the [B] to load \the [src] with \the [B_held].") + + return 0 + + if(!sheet_reagents[O.type] && (!O.reagents || !O.reagents.total_volume)) + to_chat(user, "\The [O] is not suitable for blending.") + return 1 + + user.remove_from_mob(O) + O.loc = src + holdingitems += O + return 0 + +/obj/machinery/reagentgrinder/AltClick(mob/user) + . = ..() + if(user.incapacitated() || !Adjacent(user)) + return + replace_beaker(user) + +/obj/machinery/reagentgrinder/attack_hand(mob/user as mob) + interact(user) + +/obj/machinery/reagentgrinder/interact(mob/user as mob) // The microwave Menu //I am reasonably certain that this is not a microwave + if(inuse || user.incapacitated()) + return + + var/list/options = list() + + if(beaker || length(holdingitems)) + options["eject"] = radial_eject + + if(isAI(user)) + if(stat & NOPOWER) + return + options["examine"] = radial_examine + + // if there is no power or it's broken, the procs will fail but the buttons will still show + if(length(holdingitems)) + options["grind"] = radial_grind + + var/choice + if(length(options) < 1) + return + if(length(options) == 1) + for(var/key in options) + choice = key + else + choice = show_radial_menu(user, src, options, require_near = !issilicon(user)) + + // post choice verification + if(inuse || (isAI(user) && stat & NOPOWER) || user.incapacitated()) + return + + switch(choice) + if("eject") + eject(user) + if("grind") + grind(user) + if("examine") + examine(user) + +/obj/machinery/reagentgrinder/proc/eject(mob/user) + if(user.incapacitated()) + return + for(var/obj/item/O in holdingitems) + O.loc = src.loc + holdingitems -= O + holdingitems.Cut() + if(beaker) + replace_beaker(user) + +/obj/machinery/reagentgrinder/proc/grind() + + power_change() + if(stat & (NOPOWER|BROKEN)) + return + + // Sanity check. + if (!beaker || (beaker && beaker.reagents.total_volume >= beaker.reagents.maximum_volume)) + return + + playsound(src, 'sound/machines/blender.ogg', 50, 1) + inuse = 1 + + // Reset the machine. + spawn(60) + inuse = 0 + + // Process. + for (var/obj/item/O in holdingitems) + + var/remaining_volume = beaker.reagents.maximum_volume - beaker.reagents.total_volume + if(remaining_volume <= 0) + break + + if(sheet_reagents[O.type]) + var/obj/item/stack/stack = O + if(istype(stack)) + var/list/sheet_components = sheet_reagents[stack.type] + var/amount_to_take = max(0,min(stack.amount,round(remaining_volume/REAGENTS_PER_SHEET))) + if(amount_to_take) + stack.use(amount_to_take) + if(QDELETED(stack)) + holdingitems -= stack + if(islist(sheet_components)) + amount_to_take = (amount_to_take/(sheet_components.len)) + for(var/i in sheet_components) + beaker.reagents.add_reagent(i, (amount_to_take*REAGENTS_PER_SHEET)) + else + beaker.reagents.add_reagent(sheet_components, (amount_to_take*REAGENTS_PER_SHEET)) + continue + + if(O.reagents) + O.reagents.trans_to_obj(beaker, min(O.reagents.total_volume, remaining_volume)) + if(O.reagents.total_volume == 0) + holdingitems -= O + qdel(O) + if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume) + break + +/obj/machinery/reagentgrinder/proc/replace_beaker(mob/living/user, obj/item/weapon/reagent_containers/new_beaker) + if(!user) + return FALSE + if(beaker) + if(!user.incapacitated() && Adjacent(user)) + user.put_in_hands(beaker) + else + beaker.forceMove(drop_location()) + beaker = null + if(new_beaker) + beaker = new_beaker + update_icon() + return TRUE \ No newline at end of file diff --git a/code/modules/reagents/reactions/_reactions.dm b/code/modules/reagents/reactions/_reactions.dm new file mode 100644 index 00000000000..d63967d9007 --- /dev/null +++ b/code/modules/reagents/reactions/_reactions.dm @@ -0,0 +1,128 @@ +//helper that ensures the reaction rate holds after iterating +//Ex. REACTION_RATE(0.3) means that 30% of the reagents will react each chemistry tick (~2 seconds by default). +#define REACTION_RATE(rate) (1.0 - (1.0-rate)**(1.0/PROCESS_REACTION_ITER)) + +//helper to define reaction rate in terms of half-life +//Ex. +//HALF_LIFE(0) -> Reaction completes immediately (default chems) +//HALF_LIFE(1) -> Half of the reagents react immediately, the rest over the following ticks. +//HALF_LIFE(2) -> Half of the reagents are consumed after 2 chemistry ticks. +//HALF_LIFE(3) -> Half of the reagents are consumed after 3 chemistry ticks. +#define HALF_LIFE(ticks) (ticks? 1.0 - (0.5)**(1.0/(ticks*PROCESS_REACTION_ITER)) : 1.0) + +/decl/chemical_reaction + var/name = null + var/id = null + var/result = null + var/list/required_reagents = list() + var/list/catalysts = list() + var/list/inhibitors = list() + var/result_amount = 0 + + //how far the reaction proceeds each time it is processed. Used with either REACTION_RATE or HALF_LIFE macros. + var/reaction_rate = HALF_LIFE(0) + + //if less than 1, the reaction will be inhibited if the ratio of products/reagents is too high. + //0.5 = 50% yield -> reaction will only proceed halfway until products are removed. + var/yield = 1.0 + + //If limits on reaction rate would leave less than this amount of any reagent (adjusted by the reaction ratios), + //the reaction goes to completion. This is to prevent reactions from going on forever with tiny reagent amounts. + var/min_reaction = 2 + + var/mix_message = "The solution begins to bubble." + var/reaction_sound = 'sound/effects/bubbles.ogg' + + var/log_is_important = 0 // If this reaction should be considered important for logging. Important recipes message admins when mixed, non-important ones just log to file. + +/decl/chemical_reaction/proc/can_happen(var/datum/reagents/holder) + //check that all the required reagents are present + if(!holder.has_all_reagents(required_reagents)) + return FALSE + + //check that all the required catalysts are present in the required amount + if(!holder.has_all_reagents(catalysts)) + return FALSE + + //check that none of the inhibitors are present in the required amount + if(holder.has_any_reagent(inhibitors)) + return FALSE + + return TRUE + +/decl/chemical_reaction/proc/calc_reaction_progress(var/datum/reagents/holder, var/reaction_limit) + var/progress = reaction_limit * reaction_rate //simple exponential progression + + //calculate yield + if(1-yield > 0.001) //if yield ratio is big enough just assume it goes to completion + /* + Determine the max amount of product by applying the yield condition: + (max_product/result_amount) / reaction_limit == yield/(1-yield) + + We make use of the fact that: + reaction_limit = (holder.get_reagent_amount(reactant) / required_reagents[reactant]) of the limiting reagent. + */ + var/yield_ratio = yield/(1-yield) + var/max_product = yield_ratio * reaction_limit * result_amount //rearrange to obtain max_product + var/yield_limit = max(0, max_product - holder.get_reagent_amount(result))/result_amount + + progress = min(progress, yield_limit) //apply yield limit + + //apply min reaction progress - wasn't sure if this should go before or after applying yield + //I guess people can just have their miniscule reactions go to completion regardless of yield. + for(var/reactant in required_reagents) + var/remainder = holder.get_reagent_amount(reactant) - progress*required_reagents[reactant] + if(remainder <= min_reaction*required_reagents[reactant]) + progress = reaction_limit + break + + return progress + +/decl/chemical_reaction/process(var/datum/reagents/holder) + //determine how far the reaction can proceed + var/list/reaction_limits = list() + for(var/reactant in required_reagents) + reaction_limits += holder.get_reagent_amount(reactant) / required_reagents[reactant] + + //determine how far the reaction proceeds + var/reaction_limit = min(reaction_limits) + var/progress_limit = calc_reaction_progress(holder, reaction_limit) + + var/reaction_progress = min(reaction_limit, progress_limit) //no matter what, the reaction progress cannot exceed the stoichiometric limit. + + //need to obtain the new reagent's data before anything is altered + var/data = send_data(holder, reaction_progress) + + //remove the reactants + for(var/reactant in required_reagents) + var/amt_used = required_reagents[reactant] * reaction_progress + holder.remove_reagent(reactant, amt_used, safety = 1) + + //add the product + var/amt_produced = result_amount * reaction_progress + if(result) + holder.add_reagent(result, amt_produced, data, safety = 1) + + on_reaction(holder, amt_produced) + + return reaction_progress + +//called when a reaction processes +/decl/chemical_reaction/proc/on_reaction(var/datum/reagents/holder, var/created_volume) + return + +//called after processing reactions, if they occurred +/decl/chemical_reaction/proc/post_reaction(var/datum/reagents/holder) + var/atom/container = holder.my_atom + if(mix_message && container && !ismob(container)) + var/turf/T = get_turf(container) + var/list/seen = viewers(4, T) + for(var/mob/M in seen) + if(M.client) + M.show_message("[bicon(container)] [mix_message]", 1) + playsound(T, reaction_sound, 80, 1) + +//obtains any special data that will be provided to the reaction products +//this is called just before reactants are removed. +/decl/chemical_reaction/proc/send_data(var/datum/reagents/holder, var/reaction_limit) + return null \ No newline at end of file diff --git a/code/modules/reagents/distilling/Distilling-Recipes.dm b/code/modules/reagents/reactions/distilling/distilling.dm similarity index 74% rename from code/modules/reagents/distilling/Distilling-Recipes.dm rename to code/modules/reagents/reactions/distilling/distilling.dm index 0736ac7e61d..5944a758462 100644 --- a/code/modules/reagents/distilling/Distilling-Recipes.dm +++ b/code/modules/reagents/reactions/distilling/distilling.dm @@ -1,4 +1,4 @@ -/datum/chemical_reaction/distilling +/decl/chemical_reaction/distilling // name = null // id = null // result = null @@ -26,32 +26,19 @@ var/list/temp_range = list(T0C, T20C) var/temp_shift = 0 // How much the temperature changes when the reaction occurs. -/datum/chemical_reaction/distilling/can_happen(var/datum/reagents/holder) - //check that all the required reagents are present - if(!holder.has_all_reagents(required_reagents)) - return 0 +/decl/chemical_reaction/distilling/can_happen(var/datum/reagents/holder) + if(!istype(holder, /datum/reagents/distilling) || !istype(holder.my_atom, /obj/machinery/portable_atmospherics/powered/reagent_distillery)) + return FALSE - //check that all the required catalysts are present in the required amount - if(!holder.has_all_reagents(catalysts)) - return 0 + // Super special temperature check. + var/obj/machinery/portable_atmospherics/powered/reagent_distillery/RD = holder.my_atom + if(RD.current_temp < temp_range[1] || RD.current_temp > temp_range[2]) + return FALSE - //check that none of the inhibitors are present in the required amount - if(holder.has_any_reagent(inhibitors)) - return 0 - - if(!istype(holder.my_atom, /obj/item/weapon/reagent_containers/glass/distilling)) - return 0 - - else // Super special temperature check. - var/obj/item/weapon/reagent_containers/glass/distilling/D = holder.my_atom - var/obj/machinery/portable_atmospherics/powered/reagent_distillery/RD = D.Master - if(RD.current_temp < temp_range[1] || RD.current_temp > temp_range[2]) - return 0 - - return 1 + return ..() /* -/datum/chemical_reaction/distilling/on_reaction(var/datum/reagents/holder, var/created_volume) +/decl/chemical_reaction/distilling/on_reaction(var/datum/reagents/holder, var/created_volume) if(istype(holder.my_atom, /obj/item/weapon/reagent_containers/glass/distilling)) var/obj/item/weapon/reagent_containers/glass/distilling/D = holder.my_atom var/obj/machinery/portable_atmospherics/powered/reagent_distillery/RD = D.Master @@ -62,7 +49,7 @@ // Subtypes // // Biomass -/datum/chemical_reaction/distilling/biomass +/decl/chemical_reaction/distilling/biomass name = "Distilling Biomass" id = "distill_biomass" result = "biomass" @@ -73,7 +60,7 @@ temp_shift = -2 // Medicinal -/datum/chemical_reaction/distilling/inaprovalaze +/decl/chemical_reaction/distilling/inaprovalaze name = "Distilling Inaprovalaze" id = "distill_inaprovalaze" result = "inaprovalaze" @@ -84,7 +71,7 @@ temp_range = list(T0C + 100, T0C + 120) -/datum/chemical_reaction/distilling/bicaridaze +/decl/chemical_reaction/distilling/bicaridaze name = "Distilling Bicaridaze" id = "distill_bicaridaze" result = "bicaridaze" @@ -95,7 +82,7 @@ temp_range = list(T0C + 110, T0C + 130) -/datum/chemical_reaction/distilling/dermalaze +/decl/chemical_reaction/distilling/dermalaze name = "Distilling Dermalaze" id = "distill_dermalaze" result = "dermalaze" @@ -106,7 +93,7 @@ temp_range = list(T0C + 115, T0C + 130) -/datum/chemical_reaction/distilling/spacomycaze +/decl/chemical_reaction/distilling/spacomycaze name = "Distilling Spacomycaze" id = "distill_spacomycaze" result = "spacomycaze" @@ -117,7 +104,7 @@ temp_range = list(T0C + 100, T0C + 120) -/datum/chemical_reaction/distilling/tricorlidaze +/decl/chemical_reaction/distilling/tricorlidaze name = "Distilling Tricorlidaze" id = "distill_tricorlidaze" result = "tricorlidaze" @@ -128,7 +115,7 @@ temp_range = list(T0C + 100, T0C + 120) -/datum/chemical_reaction/distilling/synthplas +/decl/chemical_reaction/distilling/synthplas name = "Distilling Synthplas" id = "distill_synthplas" result = "synthblood_dilute" @@ -140,7 +127,7 @@ temp_range = list(T0C + 110, T0C + 130) // Alcohol -/datum/chemical_reaction/distilling/beer +/decl/chemical_reaction/distilling/beer name = "Distilling Beer" id = "distill_beer" result = "beer" @@ -151,7 +138,7 @@ temp_range = list(T20C, T20C + 2) -/datum/chemical_reaction/distilling/ale +/decl/chemical_reaction/distilling/ale name = "Distilling Ale" id = "distill_ale" result = "ale" @@ -165,7 +152,7 @@ temp_range = list(T0C + 7, T0C + 13) // Unique -/datum/chemical_reaction/distilling/berserkjuice +/decl/chemical_reaction/distilling/berserkjuice name = "Distilling Brute Juice" id = "distill_brutejuice" result = "berserkmed" @@ -175,7 +162,7 @@ temp_range = list(T0C + 600, T0C + 700) temp_shift = 4 -/datum/chemical_reaction/distilling/berserkjuice/on_reaction(var/datum/reagents/holder, var/created_volume) +/decl/chemical_reaction/distilling/berserkjuice/on_reaction(var/datum/reagents/holder, var/created_volume) ..() if(prob(1)) @@ -183,7 +170,7 @@ explosion(T, -1, rand(-1, 1), rand(1,2), rand(3,5)) return -/datum/chemical_reaction/distilling/cryogel +/decl/chemical_reaction/distilling/cryogel name = "Distilling Cryogellatin" id = "distill_cryoslurry" result = "cryoslurry" @@ -194,7 +181,7 @@ temp_range = list(0, 15) temp_shift = 20 -/datum/chemical_reaction/distilling/cryogel/on_reaction(var/datum/reagents/holder, var/created_volume) +/decl/chemical_reaction/distilling/cryogel/on_reaction(var/datum/reagents/holder, var/created_volume) ..() if(prob(1)) @@ -204,7 +191,7 @@ F.start() return -/datum/chemical_reaction/distilling/lichpowder +/decl/chemical_reaction/distilling/lichpowder name = "Distilling Lichpowder" id = "distill_lichpowder" result = "lichpowder" @@ -215,7 +202,7 @@ temp_range = list(T0C + 100, T0C + 150) -/datum/chemical_reaction/distilling/necroxadone +/decl/chemical_reaction/distilling/necroxadone name = "Distilling Necroxadone" id = "distill_necroxadone" result = "necroxadone" diff --git a/code/modules/reagents/reactions/fusion/fusion.dm b/code/modules/reagents/reactions/fusion/fusion.dm new file mode 100644 index 00000000000..7b0acfec96a --- /dev/null +++ b/code/modules/reagents/reactions/fusion/fusion.dm @@ -0,0 +1,6 @@ +// TDOD: Port R-UST fusion reactions to the chemistry system. +//They'll operate in a similar manner to distillery reactions, +// but will have distinct behaviours (mostly relating to the fusion field) that warrants a separate type +/* +/decl/chemical_reaction/fusion + name = "Fusion"*/ \ No newline at end of file diff --git a/code/modules/reagents/reactions/instant/drinks.dm b/code/modules/reagents/reactions/instant/drinks.dm new file mode 100644 index 00000000000..2722d7843bc --- /dev/null +++ b/code/modules/reagents/reactions/instant/drinks.dm @@ -0,0 +1,1223 @@ +/decl/chemical_reaction/instant/drinks/coffee + name = "Coffee" + id = "coffee" + result = "coffee" + required_reagents = list("water" = 5, "coffeepowder" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/drinks/tea + name = "Black tea" + id = "tea" + result = "tea" + required_reagents = list("water" = 5, "teapowder" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/drinks/hot_coco + name = "Hot Coco" + id = "hot_coco" + result = "hot_coco" + required_reagents = list("water" = 5, "coco" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/drinks/grapejuice + name = "Grape Juice" + id = "grapejuice" + result = "grapejuice" + required_reagents = list("water" = 3, "instantgrape" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/orangejuice + name = "Orange Juice" + id = "orangejuice" + result = "orangejuice" + required_reagents = list("water" = 3, "instantorange" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/watermelonjuice + name = "Watermelon Juice" + id = "watermelonjuice" + result = "watermelonjuice" + required_reagents = list("water" = 3, "instantwatermelon" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/applejuice + name = "Apple Juice" + id = "applejuice" + result = "applejuice" + required_reagents = list("water" = 3, "instantapple" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/goldschlager + name = "Goldschlager" + id = "goldschlager" + result = "goldschlager" + required_reagents = list("vodka" = 10, "gold" = 1) + result_amount = 10 + +/decl/chemical_reaction/instant/drinks/patron + name = "Patron" + id = "patron" + result = "patron" + required_reagents = list("tequilla" = 10, "silver" = 1) + result_amount = 10 + +/decl/chemical_reaction/instant/drinks/bilk + name = "Bilk" + id = "bilk" + result = "bilk" + required_reagents = list("milk" = 1, "beer" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/icetea + name = "Iced Tea" + id = "icetea" + result = "icetea" + required_reagents = list("ice" = 1, "tea" = 2) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/icecoffee + name = "Iced Coffee" + id = "icecoffee" + result = "icecoffee" + required_reagents = list("ice" = 1, "coffee" = 2) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/nuka_cola + name = "Nuclear Cola" + id = "nuka_cola" + result = "nuka_cola" + required_reagents = list("uranium" = 1, "cola" = 5) + result_amount = 5 + +/decl/chemical_reaction/instant/drinks/moonshine + name = "Moonshine" + id = "moonshine" + result = "moonshine" + required_reagents = list("nutriment" = 10) + catalysts = list("enzyme" = 5) + result_amount = 10 + +/decl/chemical_reaction/instant/drinks/grenadine + name = "Grenadine Syrup" + id = "grenadine" + result = "grenadine" + required_reagents = list("berryjuice" = 10) + catalysts = list("enzyme" = 5) + result_amount = 10 + +/decl/chemical_reaction/instant/drinks/wine + name = "Wine" + id = "wine" + result = "wine" + required_reagents = list("grapejuice" = 10) + catalysts = list("enzyme" = 5) + result_amount = 10 + +/decl/chemical_reaction/instant/drinks/pwine + name = "Poison Wine" + id = "pwine" + result = "pwine" + required_reagents = list("poisonberryjuice" = 10) + catalysts = list("enzyme" = 5) + result_amount = 10 + +/decl/chemical_reaction/instant/drinks/melonliquor + name = "Melon Liquor" + id = "melonliquor" + result = "melonliquor" + required_reagents = list("watermelonjuice" = 10) + catalysts = list("enzyme" = 5) + result_amount = 10 + +/decl/chemical_reaction/instant/drinks/bluecuracao + name = "Blue Curacao" + id = "bluecuracao" + result = "bluecuracao" + required_reagents = list("orangejuice" = 10) + catalysts = list("enzyme" = 5) + result_amount = 10 + +/decl/chemical_reaction/instant/drinks/spacebeer + name = "Space Beer" + id = "spacebeer" + result = "beer" + required_reagents = list("cornoil" = 10) + catalysts = list("enzyme" = 5) + result_amount = 10 + +/decl/chemical_reaction/instant/drinks/vodka + name = "Vodka" + id = "vodka" + result = "vodka" + required_reagents = list("potatojuice" = 10) + catalysts = list("enzyme" = 5) + result_amount = 10 + +/decl/chemical_reaction/instant/drinks/cider + name = "Cider" + id = "cider" + result = "cider" + required_reagents = list("applejuice" = 10) + catalysts = list("enzyme" = 5) + result_amount = 10 + + +/decl/chemical_reaction/instant/drinks/sake + name = "Sake" + id = "sake" + result = "sake" + required_reagents = list("rice" = 10) + catalysts = list("enzyme" = 5) + result_amount = 10 + +/decl/chemical_reaction/instant/drinks/kahlua + name = "Kahlua" + id = "kahlua" + result = "kahlua" + required_reagents = list("coffee" = 5, "sugar" = 5) + catalysts = list("enzyme" = 5) + result_amount = 5 + +/decl/chemical_reaction/instant/drinks/gin_tonic + name = "Gin and Tonic" + id = "gintonic" + result = "gintonic" + required_reagents = list("gin" = 2, "tonic" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/cuba_libre + name = "Cuba Libre" + id = "cubalibre" + result = "cubalibre" + required_reagents = list("rum" = 2, "cola" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/martini + name = "Classic Martini" + id = "martini" + result = "martini" + required_reagents = list("gin" = 2, "vermouth" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/vodkamartini + name = "Vodka Martini" + id = "vodkamartini" + result = "vodkamartini" + required_reagents = list("vodka" = 2, "vermouth" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/white_russian + name = "White Russian" + id = "whiterussian" + result = "whiterussian" + required_reagents = list("blackrussian" = 2, "cream" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/whiskey_cola + name = "Whiskey Cola" + id = "whiskeycola" + result = "whiskeycola" + required_reagents = list("whiskey" = 2, "cola" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/screwdriver + name = "Screwdriver" + id = "screwdrivercocktail" + result = "screwdrivercocktail" + required_reagents = list("vodka" = 2, "orangejuice" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/bloody_mary + name = "Bloody Mary" + id = "bloodymary" + result = "bloodymary" + required_reagents = list("vodka" = 2, "tomatojuice" = 3, "limejuice" = 1) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/gargle_blaster + name = "Pan-Galactic Gargle Blaster" + id = "gargleblaster" + result = "gargleblaster" + required_reagents = list("vodka" = 2, "gin" = 1, "whiskey" = 1, "cognac" = 1, "limejuice" = 1) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/brave_bull + name = "Brave Bull" + id = "bravebull" + result = "bravebull" + required_reagents = list("tequilla" = 2, "kahlua" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/tequilla_sunrise + name = "Tequilla Sunrise" + id = "tequillasunrise" + result = "tequillasunrise" + required_reagents = list("tequilla" = 2, "orangejuice" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/phoron_special + name = "Toxins Special" + id = "phoronspecial" + result = "phoronspecial" + required_reagents = list("rum" = 2, "vermouth" = 2, "phoron" = 2) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/beepsky_smash + name = "Beepksy Smash" + id = "beepksysmash" + result = "beepskysmash" + required_reagents = list("limejuice" = 1, "whiskey" = 1, "iron" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/doctor_delight + name = "The Doctor's Delight" + id = "doctordelight" + result = "doctorsdelight" + required_reagents = list("limejuice" = 1, "tomatojuice" = 1, "orangejuice" = 1, "cream" = 2, "tricordrazine" = 1) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/irish_cream + name = "Irish Cream" + id = "irishcream" + result = "irishcream" + required_reagents = list("whiskey" = 2, "cream" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/manly_dorf + name = "The Manly Dorf" + id = "manlydorf" + result = "manlydorf" + required_reagents = list ("beer" = 1, "ale" = 2) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/hooch + name = "Hooch" + id = "hooch" + result = "hooch" + required_reagents = list ("sugar" = 1, "ethanol" = 2, "fuel" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/irish_coffee + name = "Irish Coffee" + id = "irishcoffee" + result = "irishcoffee" + required_reagents = list("irishcream" = 1, "coffee" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/b52 + name = "B-52" + id = "b52" + result = "b52" + required_reagents = list("irishcream" = 1, "kahlua" = 1, "cognac" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/atomicbomb + name = "Atomic Bomb" + id = "atomicbomb" + result = "atomicbomb" + required_reagents = list("b52" = 10, "uranium" = 1) + result_amount = 10 + +/decl/chemical_reaction/instant/drinks/margarita + name = "Margarita" + id = "margarita" + result = "margarita" + required_reagents = list("tequilla" = 2, "limejuice" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/longislandicedtea + name = "Long Island Iced Tea" + id = "longislandicedtea" + result = "longislandicedtea" + required_reagents = list("vodka" = 1, "gin" = 1, "tequilla" = 1, "cubalibre" = 3) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/icedtea + name = "Long Island Iced Tea" + id = "longislandicedtea" + result = "longislandicedtea" + required_reagents = list("vodka" = 1, "gin" = 1, "tequilla" = 1, "cubalibre" = 3) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/threemileisland + name = "Three Mile Island Iced Tea" + id = "threemileisland" + result = "threemileisland" + required_reagents = list("longislandicedtea" = 10, "uranium" = 1) + result_amount = 10 + +/decl/chemical_reaction/instant/drinks/whiskeysoda + name = "Whiskey Soda" + id = "whiskeysoda" + result = "whiskeysoda" + required_reagents = list("whiskey" = 2, "sodawater" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/black_russian + name = "Black Russian" + id = "blackrussian" + result = "blackrussian" + required_reagents = list("vodka" = 2, "kahlua" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/manhattan + name = "Manhattan" + id = "manhattan" + result = "manhattan" + required_reagents = list("whiskey" = 2, "vermouth" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/manhattan_proj + name = "Manhattan Project" + id = "manhattan_proj" + result = "manhattan_proj" + required_reagents = list("manhattan" = 10, "uranium" = 1) + result_amount = 10 + +/decl/chemical_reaction/instant/drinks/vodka_tonic + name = "Vodka and Tonic" + id = "vodkatonic" + result = "vodkatonic" + required_reagents = list("vodka" = 2, "tonic" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/gin_fizz + name = "Gin Fizz" + id = "ginfizz" + result = "ginfizz" + required_reagents = list("gin" = 1, "sodawater" = 1, "limejuice" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/bahama_mama + name = "Bahama mama" + id = "bahama_mama" + result = "bahama_mama" + required_reagents = list("rum" = 2, "orangejuice" = 2, "limejuice" = 1, "ice" = 1) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/singulo + name = "Singulo" + id = "singulo" + result = "singulo" + required_reagents = list("vodka" = 5, "radium" = 1, "wine" = 5) + result_amount = 10 + +/decl/chemical_reaction/instant/drinks/alliescocktail + name = "Allies Cocktail" + id = "alliescocktail" + result = "alliescocktail" + required_reagents = list("martini" = 1, "vodka" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/demonsblood + name = "Demons Blood" + id = "demonsblood" + result = "demonsblood" + required_reagents = list("rum" = 3, "spacemountainwind" = 1, "blood" = 1, "dr_gibb" = 1) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/booger + name = "Booger" + id = "booger" + result = "booger" + required_reagents = list("cream" = 2, "banana" = 1, "rum" = 1, "watermelonjuice" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/drinks/antifreeze + name = "Anti-freeze" + id = "antifreeze" + result = "antifreeze" + required_reagents = list("vodka" = 1, "cream" = 1, "ice" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/barefoot + name = "Barefoot" + id = "barefoot" + result = "barefoot" + required_reagents = list("berryjuice" = 1, "cream" = 1, "vermouth" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/grapesoda + name = "Grape Soda" + id = "grapesoda" + result = "grapesoda" + required_reagents = list("grapejuice" = 2, "cola" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/sbiten + name = "Sbiten" + id = "sbiten" + result = "sbiten" + required_reagents = list("vodka" = 10, "capsaicin" = 1) + result_amount = 10 + +/decl/chemical_reaction/instant/drinks/red_mead + name = "Red Mead" + id = "red_mead" + result = "red_mead" + required_reagents = list("blood" = 1, "mead" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/mead + name = "Mead" + id = "mead" + result = "mead" + required_reagents = list("sugar" = 1, "water" = 1) + catalysts = list("enzyme" = 5) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/iced_beer + name = "Iced Beer" + id = "iced_beer" + result = "iced_beer" + required_reagents = list("beer" = 10, "frostoil" = 1) + result_amount = 10 + +/decl/chemical_reaction/instant/drinks/iced_beer2 + name = "Iced Beer" + id = "iced_beer" + result = "iced_beer" + required_reagents = list("beer" = 5, "ice" = 1) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/grog + name = "Grog" + id = "grog" + result = "grog" + required_reagents = list("rum" = 1, "water" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/soy_latte + name = "Soy Latte" + id = "soy_latte" + result = "soy_latte" + required_reagents = list("coffee" = 1, "soymilk" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/cafe_latte + name = "Cafe Latte" + id = "cafe_latte" + result = "cafe_latte" + required_reagents = list("coffee" = 1, "milk" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/acidspit + name = "Acid Spit" + id = "acidspit" + result = "acidspit" + required_reagents = list("sacid" = 1, "wine" = 5) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/amasec + name = "Amasec" + id = "amasec" + result = "amasec" + required_reagents = list("iron" = 1, "wine" = 5, "vodka" = 5) + result_amount = 10 + +/decl/chemical_reaction/instant/drinks/changelingsting + name = "Changeling Sting" + id = "changelingsting" + result = "changelingsting" + required_reagents = list("screwdrivercocktail" = 1, "limejuice" = 1, "lemonjuice" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/aloe + name = "Aloe" + id = "aloe" + result = "aloe" + required_reagents = list("cream" = 1, "whiskey" = 1, "watermelonjuice" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/andalusia + name = "Andalusia" + id = "andalusia" + result = "andalusia" + required_reagents = list("rum" = 1, "whiskey" = 1, "lemonjuice" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/snowwhite + name = "Snow White" + id = "snowwhite" + result = "snowwhite" + required_reagents = list("pineapplejuice" = 1, "rum" = 1, "lemon_lime" = 1, "egg" = 1, "kahlua" = 1, "sugar" = 1) //VoreStation Edit + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/irishcarbomb + name = "Irish Car Bomb" + id = "irishcarbomb" + result = "irishcarbomb" + required_reagents = list("ale" = 1, "irishcream" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/syndicatebomb + name = "Syndicate Bomb" + id = "syndicatebomb" + result = "syndicatebomb" + required_reagents = list("beer" = 1, "whiskeycola" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/erikasurprise + name = "Erika Surprise" + id = "erikasurprise" + result = "erikasurprise" + required_reagents = list("ale" = 2, "limejuice" = 1, "whiskey" = 1, "banana" = 1, "ice" = 1) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/devilskiss + name = "Devils Kiss" + id = "devilskiss" + result = "devilskiss" + required_reagents = list("blood" = 1, "kahlua" = 1, "rum" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/hippiesdelight + name = "Hippies Delight" + id = "hippiesdelight" + result = "hippiesdelight" + required_reagents = list("psilocybin" = 1, "gargleblaster" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/bananahonk + name = "Banana Honk" + id = "bananahonk" + result = "bananahonk" + required_reagents = list("banana" = 1, "cream" = 1, "sugar" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/silencer + name = "Silencer" + id = "silencer" + result = "silencer" + required_reagents = list("nothing" = 1, "cream" = 1, "sugar" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/driestmartini + name = "Driest Martini" + id = "driestmartini" + result = "driestmartini" + required_reagents = list("nothing" = 1, "gin" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/lemonade + name = "Lemonade" + id = "lemonade" + result = "lemonade" + required_reagents = list("lemonjuice" = 1, "sugar" = 1, "water" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/melonade + name = "Melonade" + id = "melonade" + result = "melonade" + required_reagents = list("watermelonjuice" = 1, "sugar" = 1, "sodawater" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/appleade + name = "Appleade" + id = "appleade" + result = "appleade" + required_reagents = list("applejuice" = 1, "sugar" = 1, "sodawater" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/pineappleade + name = "Pineappleade" + id = "pineappleade" + result = "pineappleade" + required_reagents = list("pineapplejuice" = 2, "limejuice" = 1, "sodawater" = 2, "honey" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/drinks/driverspunch + name = "Driver`s Punch" + id = "driverspunch" + result = "driverspunch" + required_reagents = list("appleade" = 2, "orangejuice" = 1, "mint" = 1, "sodawater" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/mintapplesparkle + name = "Mint Apple Sparkle" + id = "mintapplesparkle" + result = "mintapplesparkle" + required_reagents = list("appleade" = 2, "mint" = 1) + inhibitors = list("sodawater" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/berrycordial + name = "Berry Cordial" + id = "berrycordial" + result = "berrycordial" + required_reagents = list("berryjuice" = 4, "sugar" = 1, "lemonjuice" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/drinks/tropicalfizz + name = "Tropical Fizz" + id = "tropicalfizz" + result = "tropicalfizz" + required_reagents = list("sodawater" = 6, "berryjuice" = 1, "mint" = 1, "limejuice" = 1, "lemonjuice" = 1, "pineapplejuice" = 1) + inhibitors = list("sugar" = 1) + result_amount = 8 + +/decl/chemical_reaction/instant/drinks/melonspritzer + name = "Melon Spritzer" + id = "melonspritzer" + result = "melonspritzer" + required_reagents = list("watermelonjuice" = 2, "wine" = 2, "applejuice" = 1, "limejuice" = 1) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/fauxfizz + name = "Faux Fizz" + id = "fauxfizz" + result = "fauxfizz" + required_reagents = list("sodawater" = 2, "berryjuice" = 1, "applejuice" = 1, "limejuice" = 1, "honey" = 1) + inhibitors = list("sugar" = 1) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/firepunch + name = "Fire Punch" + id = "firepunch" + result = "firepunch" + required_reagents = list("sugar" = 1, "rum" = 2) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/kiraspecial + name = "Kira Special" + id = "kiraspecial" + result = "kiraspecial" + required_reagents = list("orangejuice" = 1, "limejuice" = 1, "sodawater" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/brownstar + name = "Brown Star" + id = "brownstar" + result = "brownstar" + required_reagents = list("orangejuice" = 2, "cola" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/milkshake + name = "Milkshake" + id = "milkshake" + result = "milkshake" + required_reagents = list("cream" = 1, "ice" = 2, "milk" = 2) + result_amount = 5 + +/decl/chemical_reaction/instant/drinks/peanutmilkshake + name = "Peanutbutter Milkshake" + id = "peanutmilkshake" + result = "peanutmilkshake" + required_reagents = list("cream" = 1, "ice" = 1, "peanutbutter" = 2, "milk" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/drinks/rewriter + name = "Rewriter" + id = "rewriter" + result = "rewriter" + required_reagents = list("spacemountainwind" = 1, "coffee" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/suidream + name = "Sui Dream" + id = "suidream" + result = "suidream" + required_reagents = list("space_up" = 1, "bluecuracao" = 1, "melonliquor" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/shirleytemple + name = "Shirley Temple" + id = "shirley_temple" + result = "shirley_temple" + required_reagents = list("gingerale" = 4, "grenadine" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/drinks/royrogers + name = "Roy Rogers" + id = "roy_rogers" + result = "roy_rogers" + required_reagents = list("shirley_temple" = 5, "lemon_lime" = 2) + result_amount = 7 + +/decl/chemical_reaction/instant/drinks/collinsmix + name = "Collins Mix" + id = "collins_mix" + result = "collins_mix" + required_reagents = list("lemon_lime" = 3, "sodawater" = 1) + result_amount = 4 + +/decl/chemical_reaction/instant/drinks/arnoldpalmer + name = "Arnold Palmer" + id = "arnold_palmer" + result = "arnold_palmer" + required_reagents = list("icetea" = 1, "lemonade" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/minttea + name = "Mint Tea" + id = "minttea" + result = "minttea" + required_reagents = list("tea" = 5, "mint" = 1) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/lemontea + name = "Lemon Tea" + id = "lemontea" + result = "lemontea" + required_reagents = list("tea" = 5, "lemonjuice" = 1) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/limetea + name = "Lime Tea" + id = "limetea" + result = "limetea" + required_reagents = list("tea" = 5, "limejuice" = 1) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/orangetea + name = "Orange Tea" + id = "orangetea" + result = "orangetea" + required_reagents = list("tea" = 5, "orangejuice" = 1) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/berrytea + name = "Berry Tea" + id = "berrytea" + result = "berrytea" + required_reagents = list("tea" = 5, "berryjuice" = 1) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/sakebomb + name = "Sake Bomb" + id = "sakebomb" + result = "sakebomb" + required_reagents = list("beer" = 2, "sake" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/tamagozake + name = "Tamagozake" + id = "tamagozake" + result = "tamagozake" + required_reagents = list("sake" = 10, "sugar" = 5, "egg" = 3) + result_amount = 15 + +/decl/chemical_reaction/instant/drinks/ginzamary + name = "Ginza Mary" + id = "ginzamary" + result = "ginzamary" + required_reagents = list("sake" = 2, "vodka" = 2, "tomatojuice" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/drinks/tokyorose + name = "Tokyo Rose" + id = "tokyorose" + result = "tokyorose" + required_reagents = list("sake" = 1, "berryjuice" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/saketini + name = "Saketini" + id = "saketini" + result = "saketini" + required_reagents = list("sake" = 1, "gin" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/elysiumfacepunch + name = "Elysium Facepunch" + id = "elysiumfacepunch" + result = "elysiumfacepunch" + required_reagents = list("kahlua" = 1, "lemonjuice" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/erebusmoonrise + name = "Erebus Moonrise" + id = "erebusmoonrise" + result = "erebusmoonrise" + required_reagents = list("whiskey" = 1, "vodka" = 1, "tequilla" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/balloon + name = "Balloon" + id = "balloon" + result = "balloon" + required_reagents = list("cream" = 1, "bluecuracao" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/natunabrandy + name = "Natuna Brandy" + id = "natunabrandy" + result = "natunabrandy" + required_reagents = list("beer" = 1, "sodawater" = 2) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/euphoria + name = "Euphoria" + id = "euphoria" + result = "euphoria" + required_reagents = list("specialwhiskey" = 1, "cognac" = 2) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/xanaducannon + name = "Xanadu Cannon" + id = "xanaducannon" + result = "xanaducannon" + required_reagents = list("ale" = 1, "dr_gibb" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/debugger + name = "Debugger" + id = "debugger" + result = "debugger" + required_reagents = list("fuel" = 1, "sugar" = 2, "cornoil" = 2) + result_amount = 5 + +/decl/chemical_reaction/instant/drinks/spacersbrew + name = "Spacer's Brew" + id = "spacersbrew" + result = "spacersbrew" + required_reagents = list("brownstar" = 4, "ethanol" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/drinks/binmanbliss + name = "Binman Bliss" + id = "binmanbliss" + result = "binmanbliss" + required_reagents = list("sake" = 1, "tequilla" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/chrysanthemum + name = "Chrysanthemum" + id = "chrysanthemum" + result = "chrysanthemum" + required_reagents = list("sake" = 1, "melonliquor" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/deathbell + name = "Deathbell" + id = "deathbell" + result = "deathbell" + required_reagents = list("antifreeze" = 1, "gargleblaster" = 1, "syndicatebomb" =1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/bitters + name = "Bitters" + id = "bitters" + result = "bitters" + required_reagents = list("mint" = 5) + catalysts = list("enzyme" = 5) + result_amount = 5 + +/decl/chemical_reaction/instant/drinks/soemmerfire + name = "Soemmer Fire" + id = "soemmerfire" + result = "soemmerfire" + required_reagents = list("manhattan" = 2, "condensedcapsaicin" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/winebrandy + name = "Wine brandy" + id = "winebrandy" + result = "winebrandy" + required_reagents = list("wine" = 10) + catalysts = list("enzyme" = 10) //10u enzyme so it requires more than is usually added. Stops overlap with wine recipe + result_amount = 5 + +/decl/chemical_reaction/instant/drinks/lovepotion + name = "Love Potion" + id = "lovepotion" + result = "lovepotion" + required_reagents = list("cream" = 1, "berryjuice" = 1, "sugar" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/morningafter + name = "Morning After" + id = "morningafter" + result = "morningafter" + required_reagents = list("sbiten" = 1, "coffee" = 5) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/vesper + name = "Vesper" + id = "vesper" + result = "vesper" + required_reagents = list("gin" = 3, "vodka" = 1, "wine" = 1) + result_amount = 4 + +/decl/chemical_reaction/instant/drinks/rotgut + name = "Rotgut Fever Dream" + id = "rotgut" + result = "rotgut" + required_reagents = list("vodka" = 3, "rum" = 1, "whiskey" = 1, "cola" = 3) + result_amount = 8 + +/decl/chemical_reaction/instant/drinks/entdraught + name = "Ent's Draught" + id = "entdraught" + result = "entdraught" + required_reagents = list("tonic" = 1, "holywater" = 1, "honey" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/voxdelight + name = "Vox's Delight" + id = "voxdelight" + result = "voxdelight" + required_reagents = list("phoron" = 3, "fuel" = 1, "water" = 1) + result_amount = 4 + +/decl/chemical_reaction/instant/drinks/screamingviking + name = "Screaming Viking" + id = "screamingviking" + result = "screamingviking" + required_reagents = list("martini" = 2, "vodkatonic" = 2, "limejuice" = 1, "rum" = 1) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/vilelemon + name = "Vile Lemon" + id = "vilelemon" + result = "vilelemon" + required_reagents = list("lemonade" = 5, "spacemountainwind" = 1) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/dreamcream + name = "Dream Cream" + id = "dreamcream" + result = "dreamcream" + required_reagents = list("milk" = 2, "cream" = 1, "honey" = 1) + result_amount = 4 + +/decl/chemical_reaction/instant/drinks/robustin + name = "Robustin" + id = "robustin" + result = "robustin" + required_reagents = list("antifreeze" = 1, "phoron" = 1, "fuel" = 1, "vodka" = 1) + result_amount = 4 + +/decl/chemical_reaction/instant/drinks/virginsip + name = "Virgin Sip" + id = "virginsip" + result = "virginsip" + required_reagents = list("driestmartini" = 1, "water" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/chocoshake + name = "Chocolate Milkshake" + id = "chocoshake" + result = "chocoshake" + required_reagents = list("milkshake" = 1, "coco" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/berryshake + name = "Berry Milkshake" + id = "berryshake" + result = "berryshake" + required_reagents = list("milkshake" = 1, "berryjuice" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/coffeeshake + name = "Coffee Milkshake" + id = "coffeeshake" + result = "coffeeshake" + required_reagents = list("milkshake" = 1, "coffee" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/jellyshot + name = "Jelly Shot" + id = "jellyshot" + result = "jellyshot" + required_reagents = list("cherryjelly" = 4, "vodka" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/drinks/slimeshot + name = "Named Bullet" + id = "slimeshot" + result = "slimeshot" + required_reagents = list("slimejelly" = 4, "vodka" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/drinks/negroni + name = "Negroni" + id = "negroni" + result = "negroni" + required_reagents = list("gin" = 1, "bitters" = 1, "vermouth" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/cloverclub + name = "Clover Club" + id = "cloverclub" + result = "cloverclub" + required_reagents = list("berryjuice" = 1, "lemonjuice" = 1, "gin" = 3) + result_amount = 5 + +/decl/chemical_reaction/instant/drinks/oldfashioned + name = "Old Fashioned" + id = "oldfashioned" + result = "oldfashioned" + required_reagents = list("whiskey" = 3, "bitters" = 1, "sugar" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/drinks/whiskeysour + name = "Whiskey Sour" + id = "whiskeysour" + result = "whiskeysour" + required_reagents = list("whiskey" = 2, "lemonjuice" = 1, "sugar" = 1) + result_amount = 4 + +/decl/chemical_reaction/instant/drinks/daiquiri + name = "Daiquiri" + id = "daiquiri" + result = "daiquiri" + required_reagents = list("rum" = 3, "limejuice" = 2, "sugar" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/drinks/mintjulep + name = "Mint Julep" + id = "mintjulep" + result = "mintjulep" + required_reagents = list("whiskey" = 2, "water" = 1, "mint" = 1) + result_amount = 4 + +/decl/chemical_reaction/instant/drinks/paloma + name = "Paloma" + id = "paloma" + result = "paloma" + required_reagents = list("orangejuice" = 1, "sodawater" = 1, "tequilla" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/mojito + name = "Mojito" + id = "mojito" + result = "mojito" + required_reagents = list("rum" = 3, "limejuice" = 1, "mint" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/drinks/virginmojito + name = "Mojito" + id = "virginmojito" + result = "virginmojito" + required_reagents = list("sodawater" = 3, "limejuice" = 1, "mint" = 1, "sugar" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/drinks/piscosour + name = "Pisco Sour" + id = "piscosour" + result = "piscosour" + required_reagents = list("winebrandy" = 1, "lemonjuice" = 1, "sugar" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/coldfront + name = "Cold Front" + id = "coldfront" + result = "coldfront" + required_reagents = list("icecoffee" = 1, "whiskey" = 1, "mint" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/godsake + name = "Gods Sake" + id = "godsake" + result = "godsake" + required_reagents = list("sake" = 2, "holywater" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/godka //Why you would put this in your body, I don't know. + name = "Godka" + id = "godka" + result = "godka" + required_reagents = list("vodka" = 1, "holywater" = 1, "ethanol" = 1, "carthatoline" = 1) + catalysts = list("enzyme" = 5, "holywater" = 5) + result_amount = 1 + +/decl/chemical_reaction/instant/drinks/holywine + name = "Angel Ichor" + id = "holywine" + result = "holywine" + required_reagents = list("grapejuice" = 5, "gold" = 5) + catalysts = list("holywater" = 5) + result_amount = 10 + +/decl/chemical_reaction/instant/drinks/holy_mary + name = "Holy Mary" + id = "holymary" + result = "holymary" + required_reagents = list("vodka" = 2, "holywine" = 3, "limejuice" = 1) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/angelskiss + name = "Angels Kiss" + id = "angelskiss" + result = "angelskiss" + required_reagents = list("holywine" = 1, "kahlua" = 1, "rum" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/angelswrath + name = "Angels Wrath" + id = "angelswrath" + result = "angelswrath" + required_reagents = list("rum" = 3, "spacemountainwind" = 1, "holywine" = 1, "dr_gibb" = 1) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/ichor_mead + name = "Ichor Mead" + id = "ichor_mead" + result = "ichor_mead" + required_reagents = list("holywine" = 1, "mead" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/oilslick + name = "Oil Slick" + id = "oilslick" + result = "oilslick" + required_reagents = list("cornoil" = 2, "honey" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/slimeslam + name = "Slick Slime Slammer" + id = "slimeslammer" + result = "slimeslammer" + required_reagents = list("cornoil" = 2, "peanutbutter" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/virginsexonthebeach + name = "Virgin Sex On The Beach" + id = "virginsexonthebeach" + result = "virginsexonthebeach" + required_reagents = list("orangejuice" = 3, "grenadine" = 2) + result_amount = 5 + +/decl/chemical_reaction/instant/drinks/sexonthebeach + name = "Sex On The Beach" + id = "sexonthebeach" + result = "sexonthebeach" + required_reagents = list("virginsexonthebeach" = 5, "vodka" = 1) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/eggnog + name = "Eggnog" + id = "eggnog" + result = "eggnog" + required_reagents = list("milk" = 5, "cream" = 5, "sugar" = 5, "egg" = 3) + result_amount = 15 + +/decl/chemical_reaction/instant/drinks/nuclearwaste_radium + name = "Nuclear Waste" + id = "nuclearwasterad" + result = "nuclearwaste" + required_reagents = list("oilslick" = 1, "radium" = 1, "limejuice" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/nuclearwaste_uranium + name = "Nuclear Waste" + id = "nuclearwasteuran" + result = "nuclearwaste" + required_reagents = list("oilslick" = 2, "uranium" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/sodaoil + name = "Soda Oil" + id = "sodaoil" + result = "sodaoil" + required_reagents = list("cornoil" = 4, "sodawater" = 1, "carbon" = 1, "tricordrazine" = 1) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/fusionnaire + name = "Fusionnaire" + id = "fusionnaire" + result = "fusionnaire" + required_reagents = list("lemonjuice" = 3, "vodka" = 2, "schnapps_pep" = 1, "schnapps_lem" = 1, "rum" = 1, "ice" = 1) + result_amount = 9 diff --git a/code/modules/reagents/reactions/instant/drinks_vr.dm b/code/modules/reagents/reactions/instant/drinks_vr.dm new file mode 100644 index 00000000000..261934c2e62 --- /dev/null +++ b/code/modules/reagents/reactions/instant/drinks_vr.dm @@ -0,0 +1,198 @@ +/////////////////////////////////////////////////////////////////////////////////// +/// Special drinks +/decl/chemical_reaction/instant/drinks/grubshake + name = "Grub protein drink" + id = "grubshake" + result = "grubshake" + required_reagents = list("shockchem" = 5, "water" = 25) + result_amount = 30 + +/decl/chemical_reaction/instant/drinks/deathbell + name = "Deathbell" + id = "deathbell" + result = "deathbell" + required_reagents = list("antifreeze" = 1, "gargleblaster" = 1, "syndicatebomb" =1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/monstertamer + name = "Monster Tamer" + id = "monstertamer" + result = "monstertamer" + required_reagents = list("whiskey" = 1, "protein" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/bigbeer + name = "Giant Beer" + id = "bigbeer" + result = "bigbeer" + required_reagents = list("syndicatebomb" = 1, "manlydorf" = 1, "grog" =1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/sweettea + name = "Sweetened Tea" + id = "sweettea" + result = "sweettea" + required_reagents = list("icetea" = 2, "sugar" = 1,) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/unsweettea + name = "Unsweetened Tea" + id = "unsweettea" + result = "unsweettea" + required_reagents = list("sweettea" = 3, "phoron" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/galacticpanic + name = "Galactic Panic Attack" + id = "galacticpanic" + result = "galacticpanic" + required_reagents = list("gargleblaster" = 1, "singulo" = 1, "phoronspecial" =1, "neurotoxin" = 1, "atomicbomb" = 1, "hippiesdelight" = 1) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/bulldog + name = "Space Bulldog" + id = "bulldog" + result = "bulldog" + required_reagents = list("whiterussian" = 4, "cola" =1) + result_amount = 4 + +/decl/chemical_reaction/instant/drinks/sbagliato + name = "Negroni Sbagliato" + id = "sbagliato" + result = "sbagliato" + required_reagents = list("wine" = 1, "vermouth" = 1, "sodawater" =1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/italiancrisis + name = "Italian Crisis" + id = "italiancrisis" + result = "italiancrisis" + required_reagents = list("bulldog" = 1, "sbagliato" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/sugarrush + name = "Sweet Rush" + id = "sugarrush" + result = "sugarrush" + required_reagents = list("sugar" = 1, "sodawater" = 1, "vodka" =1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/lotus + name = "Lotus" + id = "lotus" + result = "lotus" + required_reagents = list("sbagliato" = 1, "sugarrush" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/shroomjuice + name = "Dumb Shroom Juice" + id = "shroomjuice" + result = "shroomjuice" + required_reagents = list("psilocybin" = 1, "applejuice" = 1, "limejuice" =1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/russianroulette + name = "Russian Roulette" + id = "russianroulette" + result = "russianroulette" + required_reagents = list("whiterussian" = 5, "iron" = 1) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/lovemaker + name = "The Love Maker" + id = "lovemaker" + result = "lovemaker" + required_reagents = list("honey" = 1, "sexonthebeach" = 5) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/honeyshot + name = "Honey Shot" + id = "honeyshot" + result = "honeyshot" + required_reagents = list("honey" = 1, "vodka" = 1, "grenadine" =1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/appletini + name = "Appletini" + id = "appletini" + result = "appletini" + required_reagents = list("applejuice" = 2, "vodka" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/glowingappletini + name = "Glowing Appletini" + id = "glowingappletini" + result = "glowingappletini" + required_reagents = list("appletini" = 5, "uranium" = 1) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/scsatw + name = "Slow Comfortable Screw Against the Wall" + id = "scsatw" + result = "scsatw" + required_reagents = list("screwdrivercocktail" = 3, "rum" =1, "whiskey" =1, "gin" =1) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/choccymilk + name = "Choccy Milk" + id = "choccymilk" + result = "choccymilk" + required_reagents = list("milk" = 3, "coco" = 1) + result_amount = 4 + +/decl/chemical_reaction/instant/drinks/redspaceflush + name = "Redspace Flush" + id = "redspaceflush" + result = "redspaceflush" + required_reagents = list("rum" = 2, "whiskey" = 2, "blood" =1, "phoron" =1) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/graveyard + name = "Graveyard" + id = "graveyard" + result = "graveyard" + required_reagents = list("cola" = 1, "spacemountainwind" = 1, "dr_gibb" =1, "space_up" = 1) + result_amount = 4 + +/decl/chemical_reaction/instant/drinks/hairoftherat + name = "Hair of the Rat" + id = "hairoftherat" + result = "hairoftherat" + required_reagents = list("monstertamer" = 2, "nutriment" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/pink_moo + name = "Pink Moo" + id = "pinkmoo" + result = "pinkmoo" + required_reagents = list("blackrussian" = 2, "berryshake" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/originalsin + name = "Original Sin" + id = "originalsin" + result = "originalsin" + required_reagents = list("holywine" = 1) + catalysts = list("applejuice" = 1) + result_amount = 1 + +/decl/chemical_reaction/instant/drinks/windgarita + name = "WND-Garita" + id = "windgarita" + result = "windgarita" + required_reagents = list("margarita" = 3, "spacemountainwind" = 2, "melonliquor" = 1) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/newyorksour + name = "New York Sour" + id = "newyorksour" + result = "newyorksour" + required_reagents = list("whiskeysour" = 3, "wine" = 2, "egg" = 1) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/mudslide + name = "Mudslide" + id = "mudslide" + result = "mudslide" + required_reagents = list("blackrussian" = 1, "irishcream" = 1) + result_amount = 2 diff --git a/code/modules/reagents/reactions/instant/food.dm b/code/modules/reagents/reactions/instant/food.dm new file mode 100644 index 00000000000..952af8014b4 --- /dev/null +++ b/code/modules/reagents/reactions/instant/food.dm @@ -0,0 +1,183 @@ +/decl/chemical_reaction/instant/food/hot_ramen + name = "Hot Ramen" + id = "hot_ramen" + result = "hot_ramen" + required_reagents = list("water" = 1, "dry_ramen" = 3) + result_amount = 3 + +/decl/chemical_reaction/instant/food/hell_ramen + name = "Hell Ramen" + id = "hell_ramen" + result = "hell_ramen" + required_reagents = list("capsaicin" = 1, "hot_ramen" = 6) + result_amount = 6 + +/decl/chemical_reaction/instant/food/tofu + name = "Tofu" + id = "tofu" + result = null + required_reagents = list("soymilk" = 10) + catalysts = list("enzyme" = 5) + result_amount = 1 + +/decl/chemical_reaction/instant/food/tofu/on_reaction(var/datum/reagents/holder, var/created_volume) + var/location = get_turf(holder.my_atom) + for(var/i = 1, i <= created_volume, i++) + new /obj/item/weapon/reagent_containers/food/snacks/tofu(location) + return + +/decl/chemical_reaction/instant/food/chocolate_bar + name = "Chocolate Bar" + id = "chocolate_bar" + result = null + required_reagents = list("soymilk" = 2, "coco" = 2, "sugar" = 2) + result_amount = 1 + +/decl/chemical_reaction/instant/food/chocolate_bar/on_reaction(var/datum/reagents/holder, var/created_volume) + var/location = get_turf(holder.my_atom) + for(var/i = 1, i <= created_volume, i++) + new /obj/item/weapon/reagent_containers/food/snacks/chocolatebar(location) + return + +/decl/chemical_reaction/instant/food/chocolate_bar2 + name = "Chocolate Bar" + id = "chocolate_bar" + result = null + required_reagents = list("milk" = 2, "coco" = 2, "sugar" = 2) + result_amount = 1 + +/decl/chemical_reaction/instant/food/chocolate_bar2/on_reaction(var/datum/reagents/holder, var/created_volume) + var/location = get_turf(holder.my_atom) + for(var/i = 1, i <= created_volume, i++) + new /obj/item/weapon/reagent_containers/food/snacks/chocolatebar(location) + return + +/decl/chemical_reaction/instant/food/soysauce + name = "Soy Sauce" + id = "soysauce" + result = "soysauce" + required_reagents = list("soymilk" = 4, "sacid" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/food/ketchup + name = "Ketchup" + id = "ketchup" + result = "ketchup" + required_reagents = list("tomatojuice" = 2, "water" = 1, "sugar" = 1) + result_amount = 4 + +/decl/chemical_reaction/instant/food/barbecue + name = "Barbeque Sauce" + id = "barbecue" + result = "barbecue" + required_reagents = list("tomatojuice" = 2, "applejuice" = 1, "sugar" = 1, "spacespice" = 1) + result_amount = 4 + +/decl/chemical_reaction/instant/food/peanutbutter + name = "Peanut Butter" + id = "peanutbutter" + result = "peanutbutter" + required_reagents = list("peanutoil" = 2, "sugar" = 1, "sodiumchloride" = 1) + catalysts = list("enzyme" = 5) + result_amount = 3 + +/decl/chemical_reaction/instant/food/mayonnaise + name = "mayonnaise" + id = "mayo" + result = "mayo" + required_reagents = list("egg" = 9, "cornoil" = 5, "lemonjuice" = 5, "sodiumchloride" = 1) + result_amount = 15 + +/decl/chemical_reaction/instant/food/cheesewheel + name = "Cheesewheel" + id = "cheesewheel" + result = null + required_reagents = list("milk" = 40) + catalysts = list("enzyme" = 5) + result_amount = 1 + +/decl/chemical_reaction/instant/food/cheesewheel/on_reaction(var/datum/reagents/holder, var/created_volume) + var/location = get_turf(holder.my_atom) + for(var/i = 1, i <= created_volume, i++) + new /obj/item/weapon/reagent_containers/food/snacks/sliceable/cheesewheel(location) + return + +/decl/chemical_reaction/instant/food/meatball + name = "Meatball" + id = "meatball" + result = null + required_reagents = list("protein" = 3, "flour" = 5) + result_amount = 3 + +/decl/chemical_reaction/instant/food/meatball/on_reaction(var/datum/reagents/holder, var/created_volume) + var/location = get_turf(holder.my_atom) + for(var/i = 1, i <= created_volume, i++) + new /obj/item/weapon/reagent_containers/food/snacks/meatball(location) + return + +/decl/chemical_reaction/instant/food/dough + name = "Dough" + id = "dough" + result = null + required_reagents = list("egg" = 3, "flour" = 10) + inhibitors = list("water" = 1, "beer" = 1) //To prevent it messing with batter recipes + result_amount = 1 + +/decl/chemical_reaction/instant/food/dough/on_reaction(var/datum/reagents/holder, var/created_volume) + var/location = get_turf(holder.my_atom) + for(var/i = 1, i <= created_volume, i++) + new /obj/item/weapon/reagent_containers/food/snacks/dough(location) + return + +/decl/chemical_reaction/instant/food/syntiflesh + name = "Syntiflesh" + id = "syntiflesh" + result = null + required_reagents = list("blood" = 5, "clonexadone" = 5) + result_amount = 1 + +/decl/chemical_reaction/instant/food/syntiflesh/on_reaction(var/datum/reagents/holder, var/created_volume) + var/location = get_turf(holder.my_atom) + for(var/i = 1, i <= created_volume, i++) + new /obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh(location) + return + +/* +==================== + Aurora Food +==================== +*/ + +/decl/chemical_reaction/instant/food/coating/batter + name = "Batter" + id = "batter" + result = "batter" + required_reagents = list("egg" = 3, "flour" = 10, "water" = 5, "sodiumchloride" = 2) + result_amount = 20 + +/decl/chemical_reaction/instant/food/coating/beerbatter + name = "Beer Batter" + id = "beerbatter" + result = "beerbatter" + required_reagents = list("egg" = 3, "flour" = 10, "beer" = 5, "sodiumchloride" = 2) + result_amount = 20 + +/decl/chemical_reaction/instant/food/browniemix + name = "Brownie Mix" + id = "browniemix" + result = "browniemix" + required_reagents = list("flour" = 5, "coco" = 5, "sugar" = 5) + result_amount = 15 + +/decl/chemical_reaction/instant/food/butter + name = "Butter" + id = "butter" + result = null + required_reagents = list("cream" = 20, "sodiumchloride" = 1) + result_amount = 1 + +/decl/chemical_reaction/instant/food/butter/on_reaction(var/datum/reagents/holder, var/created_volume) + var/location = get_turf(holder.my_atom) + for(var/i = 1, i <= created_volume, i++) + new /obj/item/weapon/reagent_containers/food/snacks/spreads/butter(location) + return \ No newline at end of file diff --git a/code/modules/reagents/reactions/instant/food_vr.dm b/code/modules/reagents/reactions/instant/food_vr.dm new file mode 100644 index 00000000000..684c23e9440 --- /dev/null +++ b/code/modules/reagents/reactions/instant/food_vr.dm @@ -0,0 +1,2 @@ +/decl/chemical_reaction/instant/food/syntiflesh + required_reagents = list("blood" = 5, "clonexadone" = 1) diff --git a/code/modules/reagents/reactions/instant/instant.dm b/code/modules/reagents/reactions/instant/instant.dm new file mode 100644 index 00000000000..bb9e443f592 --- /dev/null +++ b/code/modules/reagents/reactions/instant/instant.dm @@ -0,0 +1,1135 @@ +// These reactions happen instantaneously, when added to a container that has all other necessary reagents +// They are a subtype of chemical_reaction so that such containers can iterate over only these reactions, and not have to skip other reaction types + +/* Common reactions */ + +/decl/chemical_reaction/instant/inaprovaline + name = "Inaprovaline" + id = "inaprovaline" + result = "inaprovaline" + required_reagents = list("oxygen" = 1, "carbon" = 1, "sugar" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/dylovene + name = "Dylovene" + id = "anti_toxin" + result = "anti_toxin" + required_reagents = list("silicon" = 1, "potassium" = 1, "nitrogen" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/carthatoline + name = "Carthatoline" + id = "carthatoline" + result = "carthatoline" + required_reagents = list("anti_toxin" = 1, "carbon" = 2, "phoron" = 0.1) + catalysts = list("phoron" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/paracetamol + name = "Paracetamol" + id = "paracetamol" + result = "paracetamol" + required_reagents = list("inaprovaline" = 1, "nitrogen" = 1, "water" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/tramadol + name = "Tramadol" + id = "tramadol" + result = "tramadol" + required_reagents = list("paracetamol" = 1, "ethanol" = 1, "oxygen" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/oxycodone + name = "Oxycodone" + id = "oxycodone" + result = "oxycodone" + required_reagents = list("ethanol" = 1, "tramadol" = 1) + catalysts = list("phoron" = 5) + result_amount = 1 + +/decl/chemical_reaction/instant/sterilizine + name = "Sterilizine" + id = "sterilizine" + result = "sterilizine" + required_reagents = list("ethanol" = 1, "anti_toxin" = 1, "chlorine" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/silicate + name = "Silicate" + id = "silicate" + result = "silicate" + required_reagents = list("aluminum" = 1, "silicon" = 1, "oxygen" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/mutagen + name = "Unstable mutagen" + id = "mutagen" + result = "mutagen" + required_reagents = list("radium" = 1, "phosphorus" = 1, "chlorine" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/water + name = "Water" + id = "water" + result = "water" + required_reagents = list("oxygen" = 1, "hydrogen" = 2) + result_amount = 1 + +/decl/chemical_reaction/instant/thermite + name = "Thermite" + id = "thermite" + result = "thermite" + required_reagents = list("aluminum" = 1, "iron" = 1, "oxygen" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/space_drugs + name = "Space Drugs" + id = "space_drugs" + result = "space_drugs" + required_reagents = list("mercury" = 1, "sugar" = 1, "lithium" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/lube + name = "Space Lube" + id = "lube" + result = "lube" + required_reagents = list("water" = 1, "silicon" = 1, "oxygen" = 1) + result_amount = 4 + +/decl/chemical_reaction/instant/pacid + name = "Polytrinic acid" + id = "pacid" + result = "pacid" + required_reagents = list("sacid" = 1, "chlorine" = 1, "potassium" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/synaptizine + name = "Synaptizine" + id = "synaptizine" + result = "synaptizine" + required_reagents = list("sugar" = 1, "lithium" = 1, "water" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/hyronalin + name = "Hyronalin" + id = "hyronalin" + result = "hyronalin" + required_reagents = list("radium" = 1, "anti_toxin" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/arithrazine + name = "Arithrazine" + id = "arithrazine" + result = "arithrazine" + required_reagents = list("hyronalin" = 1, "hydrogen" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/impedrezene + name = "Impedrezene" + id = "impedrezene" + result = "impedrezene" + required_reagents = list("mercury" = 1, "oxygen" = 1, "sugar" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/kelotane + name = "Kelotane" + id = "kelotane" + result = "kelotane" + required_reagents = list("silicon" = 1, "carbon" = 1) + result_amount = 2 + log_is_important = 1 + +/decl/chemical_reaction/instant/peridaxon + name = "Peridaxon" + id = "peridaxon" + result = "peridaxon" + required_reagents = list("bicaridine" = 2, "clonexadone" = 2) + catalysts = list("phoron" = 5) + result_amount = 2 + +/decl/chemical_reaction/instant/osteodaxon + name = "Osteodaxon" + id = "osteodaxon" + result = "osteodaxon" + required_reagents = list("bicaridine" = 2, "phoron" = 0.1, "carpotoxin" = 1) + catalysts = list("phoron" = 5) + inhibitors = list("clonexadone" = 1) // Messes with cryox + result_amount = 2 + +/decl/chemical_reaction/instant/respirodaxon + name = "Respirodaxon" + id = "respirodaxon" + result = "respirodaxon" + required_reagents = list("dexalinp" = 2, "biomass" = 2, "phoron" = 1) + catalysts = list("phoron" = 5) + inhibitors = list("dexalin" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/gastirodaxon + name = "Gastirodaxon" + id = "gastirodaxon" + result = "gastirodaxon" + required_reagents = list("carthatoline" = 1, "biomass" = 2, "tungsten" = 2) + catalysts = list("phoron" = 5) + inhibitors = list("lithium" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/hepanephrodaxon + name = "Hepanephrodaxon" + id = "hepanephrodaxon" + result = "hepanephrodaxon" + required_reagents = list("carthatoline" = 2, "biomass" = 2, "lithium" = 1) + catalysts = list("phoron" = 5) + inhibitors = list("tungsten" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/cordradaxon + name = "Cordradaxon" + id = "cordradaxon" + result = "cordradaxon" + required_reagents = list("potassium_chlorophoride" = 1, "biomass" = 2, "bicaridine" = 2) + catalysts = list("phoron" = 5) + inhibitors = list("clonexadone" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/virus_food + name = "Virus Food" + id = "virusfood" + result = "virusfood" + required_reagents = list("water" = 1, "milk" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/leporazine + name = "Leporazine" + id = "leporazine" + result = "leporazine" + required_reagents = list("silicon" = 1, "copper" = 1) + catalysts = list("phoron" = 5) + result_amount = 2 + +/decl/chemical_reaction/instant/cryptobiolin + name = "Cryptobiolin" + id = "cryptobiolin" + result = "cryptobiolin" + required_reagents = list("potassium" = 1, "oxygen" = 1, "sugar" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/tricordrazine + name = "Tricordrazine" + id = "tricordrazine" + result = "tricordrazine" + required_reagents = list("inaprovaline" = 1, "anti_toxin" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/alkysine + name = "Alkysine" + id = "alkysine" + result = "alkysine" + required_reagents = list("chlorine" = 1, "nitrogen" = 1, "anti_toxin" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/dexalin + name = "Dexalin" + id = "dexalin" + result = "dexalin" + required_reagents = list("oxygen" = 2, "phoron" = 0.1) + catalysts = list("phoron" = 1) + inhibitors = list("water" = 1) // Messes with cryox + result_amount = 1 + +/decl/chemical_reaction/instant/dermaline + name = "Dermaline" + id = "dermaline" + result = "dermaline" + required_reagents = list("oxygen" = 1, "phosphorus" = 1, "kelotane" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/dexalinp + name = "Dexalin Plus" + id = "dexalinp" + result = "dexalinp" + required_reagents = list("dexalin" = 1, "carbon" = 1, "iron" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/bicaridine + name = "Bicaridine" + id = "bicaridine" + result = "bicaridine" + required_reagents = list("inaprovaline" = 1, "carbon" = 1) + inhibitors = list("sugar" = 1) // Messes up with inaprovaline + result_amount = 2 + +/decl/chemical_reaction/instant/myelamine + name = "Myelamine" + id = "myelamine" + result = "myelamine" + required_reagents = list("bicaridine" = 1, "iron" = 2, "spidertoxin" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/hyperzine + name = "Hyperzine" + id = "hyperzine" + result = "hyperzine" + required_reagents = list("sugar" = 1, "phosphorus" = 1, "sulfur" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/stimm + name = "Stimm" + id = "stimm" + result = "stimm" + required_reagents = list("left4zed" = 1, "fuel" = 1) + catalysts = list("fuel" = 5) + result_amount = 2 + +/decl/chemical_reaction/instant/ryetalyn + name = "Ryetalyn" + id = "ryetalyn" + result = "ryetalyn" + required_reagents = list("arithrazine" = 1, "carbon" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/cryoxadone + name = "Cryoxadone" + id = "cryoxadone" + result = "cryoxadone" + required_reagents = list("dexalin" = 1, "water" = 1, "oxygen" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/clonexadone + name = "Clonexadone" + id = "clonexadone" + result = "clonexadone" + required_reagents = list("cryoxadone" = 1, "sodium" = 1, "phoron" = 0.1) + catalysts = list("phoron" = 5) + result_amount = 2 + +/decl/chemical_reaction/instant/mortiferin + name = "Mortiferin" + id = "mortiferin" + result = "mortiferin" + required_reagents = list("cryptobiolin" = 1, "clonexadone" = 1, "corophizine" = 1) + result_amount = 2 + catalysts = list("phoron" = 5) + +/decl/chemical_reaction/instant/spaceacillin + name = "Spaceacillin" + id = "spaceacillin" + result = "spaceacillin" + required_reagents = list("cryptobiolin" = 1, "inaprovaline" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/corophizine + name = "Corophizine" + id = "corophizine" + result = "corophizine" + required_reagents = list("spaceacillin" = 1, "carbon" = 1, "phoron" = 0.1) + catalysts = list("phoron" = 5) + result_amount = 2 + +/decl/chemical_reaction/instant/immunosuprizine + name = "Immunosuprizine" + id = "immunosuprizine" + result = "immunosuprizine" + required_reagents = list("corophizine" = 1, "tungsten" = 1, "sacid" = 1) + catalysts = list("phoron" = 5) + result_amount = 2 + +/decl/chemical_reaction/instant/imidazoline + name = "imidazoline" + id = "imidazoline" + result = "imidazoline" + required_reagents = list("carbon" = 1, "hydrogen" = 1, "anti_toxin" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/ethylredoxrazine + name = "Ethylredoxrazine" + id = "ethylredoxrazine" + result = "ethylredoxrazine" + required_reagents = list("oxygen" = 1, "anti_toxin" = 1, "carbon" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/calciumcarbonate + name = "Calcium Carbonate" + id = "calciumcarbonate" + result = "calciumcarbonate" + required_reagents = list("oxygen" = 3, "calcium" = 1, "carbon" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/soporific + name = "Soporific" + id = "stoxin" + result = "stoxin" + required_reagents = list("chloralhydrate" = 1, "sugar" = 4) + inhibitors = list("phosphorus") // Messes with the smoke + result_amount = 5 + +/decl/chemical_reaction/instant/chloralhydrate + name = "Chloral Hydrate" + id = "chloralhydrate" + result = "chloralhydrate" + required_reagents = list("ethanol" = 1, "chlorine" = 3, "water" = 1) + result_amount = 1 + +/decl/chemical_reaction/instant/potassium_chloride + name = "Potassium Chloride" + id = "potassium_chloride" + result = "potassium_chloride" + required_reagents = list("sodiumchloride" = 1, "potassium" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/potassium_chlorophoride + name = "Potassium Chlorophoride" + id = "potassium_chlorophoride" + result = "potassium_chlorophoride" + required_reagents = list("potassium_chloride" = 1, "phoron" = 1, "chloralhydrate" = 1) + result_amount = 4 + +/decl/chemical_reaction/instant/zombiepowder + name = "Zombie Powder" + id = "zombiepowder" + result = "zombiepowder" + required_reagents = list("carpotoxin" = 5, "stoxin" = 5, "copper" = 5) + result_amount = 2 + +/decl/chemical_reaction/instant/carpotoxin + name = "Carpotoxin" + id = "carpotoxin" + result = "carpotoxin" + required_reagents = list("spidertoxin" = 2, "biomass" = 1, "sifsap" = 2) + catalysts = list("sifsap" = 10) + inhibitors = list("radium" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/mindbreaker + name = "Mindbreaker Toxin" + id = "mindbreaker" + result = "mindbreaker" + required_reagents = list("silicon" = 1, "hydrogen" = 1, "anti_toxin" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/lipozine + name = "Lipozine" + id = "Lipozine" + result = "lipozine" + required_reagents = list("sodiumchloride" = 1, "ethanol" = 1, "radium" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/surfactant + name = "Foam surfactant" + id = "foam surfactant" + result = "fluorosurfactant" + required_reagents = list("fluorine" = 2, "carbon" = 2, "sacid" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/ammonia + name = "Ammonia" + id = "ammonia" + result = "ammonia" + required_reagents = list("hydrogen" = 3, "nitrogen" = 1) + inhibitors = list("phoron" = 1) // Messes with lexorin + result_amount = 3 + +/decl/chemical_reaction/instant/diethylamine + name = "Diethylamine" + id = "diethylamine" + result = "diethylamine" + required_reagents = list ("ammonia" = 1, "ethanol" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/left4zed + name = "Left4Zed" + id = "left4zed" + result = "left4zed" + required_reagents = list ("diethylamine" = 2, "mutagen" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/robustharvest + name = "RobustHarvest" + id = "robustharvest" + result = "robustharvest" + required_reagents = list ("ammonia" = 1, "calcium" = 1, "neurotoxic_protein" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/space_cleaner + name = "Space cleaner" + id = "cleaner" + result = "cleaner" + required_reagents = list("ammonia" = 1, "water" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/plantbgone + name = "Plant-B-Gone" + id = "plantbgone" + result = "plantbgone" + required_reagents = list("toxin" = 1, "water" = 4) + result_amount = 5 + +/decl/chemical_reaction/instant/foaming_agent + name = "Foaming Agent" + id = "foaming_agent" + result = "foaming_agent" + required_reagents = list("lithium" = 1, "hydrogen" = 1) + result_amount = 1 + +/decl/chemical_reaction/instant/glycerol + name = "Glycerol" + id = "glycerol" + result = "glycerol" + required_reagents = list("cornoil" = 3, "sacid" = 1) + result_amount = 1 + +/decl/chemical_reaction/instant/sodiumchloride + name = "Sodium Chloride" + id = "sodiumchloride" + result = "sodiumchloride" + required_reagents = list("sodium" = 1, "chlorine" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/condensedcapsaicin + name = "Condensed Capsaicin" + id = "condensedcapsaicin" + result = "condensedcapsaicin" + required_reagents = list("capsaicin" = 2) + catalysts = list("phoron" = 5) + result_amount = 1 + +/decl/chemical_reaction/instant/coolant + name = "Coolant" + id = "coolant" + result = "coolant" + required_reagents = list("tungsten" = 1, "oxygen" = 1, "water" = 1) + result_amount = 3 + log_is_important = 1 + +/decl/chemical_reaction/instant/rezadone + name = "Rezadone" + id = "rezadone" + result = "rezadone" + required_reagents = list("carpotoxin" = 1, "cryptobiolin" = 1, "copper" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/lexorin + name = "Lexorin" + id = "lexorin" + result = "lexorin" + required_reagents = list("phoron" = 1, "hydrogen" = 1, "nitrogen" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/methylphenidate + name = "Methylphenidate" + id = "methylphenidate" + result = "methylphenidate" + required_reagents = list("mindbreaker" = 1, "hydrogen" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/citalopram + name = "Citalopram" + id = "citalopram" + result = "citalopram" + required_reagents = list("mindbreaker" = 1, "carbon" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/paroxetine + name = "Paroxetine" + id = "paroxetine" + result = "paroxetine" + required_reagents = list("mindbreaker" = 1, "oxygen" = 1, "inaprovaline" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/neurotoxin + name = "Neurotoxin" + id = "neurotoxin" + result = "neurotoxin" + required_reagents = list("gargleblaster" = 1, "stoxin" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/luminol + name = "Luminol" + id = "luminol" + result = "luminol" + required_reagents = list("hydrogen" = 2, "carbon" = 2, "ammonia" = 2) + result_amount = 6 + +/* Solidification */ + +/decl/chemical_reaction/instant/solidification + name = "Solid Iron" + id = "solidiron" + result = null + required_reagents = list("frostoil" = 5, "iron" = REAGENTS_PER_SHEET) + result_amount = 1 + var/sheet_to_give = /obj/item/stack/material/iron + +/decl/chemical_reaction/instant/solidification/on_reaction(var/datum/reagents/holder, var/created_volume) + new sheet_to_give(get_turf(holder.my_atom), created_volume) + return + + +/decl/chemical_reaction/instant/solidification/phoron + name = "Solid Phoron" + id = "solidphoron" + required_reagents = list("frostoil" = 5, "phoron" = REAGENTS_PER_SHEET) + sheet_to_give = /obj/item/stack/material/phoron + + +/decl/chemical_reaction/instant/solidification/silver + name = "Solid Silver" + id = "solidsilver" + required_reagents = list("frostoil" = 5, "silver" = REAGENTS_PER_SHEET) + sheet_to_give = /obj/item/stack/material/silver + + +/decl/chemical_reaction/instant/solidification/gold + name = "Solid Gold" + id = "solidgold" + required_reagents = list("frostoil" = 5, "gold" = REAGENTS_PER_SHEET) + sheet_to_give = /obj/item/stack/material/gold + + +/decl/chemical_reaction/instant/solidification/platinum + name = "Solid Platinum" + id = "solidplatinum" + required_reagents = list("frostoil" = 5, "platinum" = REAGENTS_PER_SHEET) + sheet_to_give = /obj/item/stack/material/platinum + + +/decl/chemical_reaction/instant/solidification/uranium + name = "Solid Uranium" + id = "soliduranium" + required_reagents = list("frostoil" = 5, "uranium" = REAGENTS_PER_SHEET) + sheet_to_give = /obj/item/stack/material/uranium + + +/decl/chemical_reaction/instant/solidification/hydrogen + name = "Solid Hydrogen" + id = "solidhydrogen" + required_reagents = list("frostoil" = 100, "hydrogen" = REAGENTS_PER_SHEET) + sheet_to_give = /obj/item/stack/material/mhydrogen + + +// These are from Xenobio. +/decl/chemical_reaction/instant/solidification/steel + name = "Solid Steel" + id = "solidsteel" + required_reagents = list("frostoil" = 5, "steel" = REAGENTS_PER_SHEET) + sheet_to_give = /obj/item/stack/material/steel + + +/decl/chemical_reaction/instant/solidification/plasteel + name = "Solid Plasteel" + id = "solidplasteel" + required_reagents = list("frostoil" = 10, "plasteel" = REAGENTS_PER_SHEET) + sheet_to_give = /obj/item/stack/material/plasteel + + +/decl/chemical_reaction/instant/plastication + name = "Plastic" + id = "solidplastic" + result = null + required_reagents = list("pacid" = 1, "plasticide" = 2) + result_amount = 1 + +/decl/chemical_reaction/instant/plastication/on_reaction(var/datum/reagents/holder, var/created_volume) + new /obj/item/stack/material/plastic(get_turf(holder.my_atom), created_volume) + return + +/* Grenade reactions */ + +/decl/chemical_reaction/instant/explosion_potassium + name = "Explosion" + id = "explosion_potassium" + result = null + required_reagents = list("water" = 1, "potassium" = 1) + result_amount = 2 + mix_message = null + +/decl/chemical_reaction/instant/explosion_potassium/on_reaction(var/datum/reagents/holder, var/created_volume) + var/datum/effect/effect/system/reagents_explosion/e = new() + e.set_up(round (created_volume/10, 1), holder.my_atom, 0, 0) + if(isliving(holder.my_atom)) + e.amount *= 0.5 + var/mob/living/L = holder.my_atom + if(L.stat != DEAD) + e.amount *= 0.5 + //VOREStation Add Start + else + holder.clear_reagents() //No more powergaming by creating a tiny amount of this + //VORESTation Add End + e.start() + //holder.clear_reagents() //VOREStation Removal + return + +/decl/chemical_reaction/instant/flash_powder + name = "Flash powder" + id = "flash_powder" + result = null + required_reagents = list("aluminum" = 1, "potassium" = 1, "sulfur" = 1 ) + result_amount = null + +/decl/chemical_reaction/instant/flash_powder/on_reaction(var/datum/reagents/holder, var/created_volume) + var/location = get_turf(holder.my_atom) + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread + s.set_up(2, 1, location) + s.start() + for(var/mob/living/carbon/M in viewers(world.view, location)) + switch(get_dist(M, location)) + if(0 to 3) + if(hasvar(M, "glasses")) + if(istype(M:glasses, /obj/item/clothing/glasses/sunglasses)) + continue + + M.flash_eyes() + M.Weaken(15) + + if(4 to 5) + if(hasvar(M, "glasses")) + if(istype(M:glasses, /obj/item/clothing/glasses/sunglasses)) + continue + + M.flash_eyes() + M.Stun(5) + +/decl/chemical_reaction/instant/emp_pulse + name = "EMP Pulse" + id = "emp_pulse" + result = null + required_reagents = list("uranium" = 1, "iron" = 1) // Yes, laugh, it's the best recipe I could think of that makes a little bit of sense + result_amount = 2 + +/decl/chemical_reaction/instant/emp_pulse/on_reaction(var/datum/reagents/holder, var/created_volume) + var/location = get_turf(holder.my_atom) + // 100 created volume = 4 heavy range & 7 light range. A few tiles smaller than traitor EMP grandes. + // 200 created volume = 8 heavy range & 14 light range. 4 tiles larger than traitor EMP grenades. + empulse(location, round(created_volume / 24), round(created_volume / 20), round(created_volume / 18), round(created_volume / 14), 1) + //VOREStation Edit Start + if(!isliving(holder.my_atom)) //No more powergaming by creating a tiny amount of this + holder.clear_reagents() + //VOREStation Edit End + return + +/decl/chemical_reaction/instant/nitroglycerin + name = "Nitroglycerin" + id = "nitroglycerin" + result = "nitroglycerin" + required_reagents = list("glycerol" = 1, "pacid" = 1, "sacid" = 1) + result_amount = 2 + log_is_important = 1 + +/decl/chemical_reaction/instant/nitroglycerin/on_reaction(var/datum/reagents/holder, var/created_volume) + var/datum/effect/effect/system/reagents_explosion/e = new() + e.set_up(round (created_volume/2, 1), holder.my_atom, 0, 0) + if(isliving(holder.my_atom)) + e.amount *= 0.5 + var/mob/living/L = holder.my_atom + if(L.stat!=DEAD) + e.amount *= 0.5 + //VOREStation Add Start + else + holder.clear_reagents() //No more powergaming by creating a tiny amount of this + //VOREStation Add End + e.start() + + //holder.clear_reagents() //VOREStation Removal + return + +/decl/chemical_reaction/instant/napalm + name = "Napalm" + id = "napalm" + result = null + required_reagents = list("aluminum" = 1, "phoron" = 1, "sacid" = 1 ) + result_amount = 1 + +/decl/chemical_reaction/instant/napalm/on_reaction(var/datum/reagents/holder, var/created_volume) + var/turf/location = get_turf(holder.my_atom.loc) + for(var/turf/simulated/floor/target_tile in range(0,location)) + target_tile.assume_gas("volatile_fuel", created_volume, 400+T0C) + spawn (0) target_tile.hotspot_expose(700, 400) + holder.del_reagent("napalm") + return + +/decl/chemical_reaction/instant/chemsmoke + name = "Chemsmoke" + id = "chemsmoke" + result = null + required_reagents = list("potassium" = 1, "sugar" = 1, "phosphorus" = 1) + result_amount = 0.4 + +/decl/chemical_reaction/instant/chemsmoke/on_reaction(var/datum/reagents/holder, var/created_volume) + var/location = get_turf(holder.my_atom) + var/datum/effect/effect/system/smoke_spread/chem/S = new /datum/effect/effect/system/smoke_spread/chem + S.attach(location) + S.set_up(holder, created_volume, 0, location) + playsound(location, 'sound/effects/smoke.ogg', 50, 1, -3) + spawn(0) + S.start() + //VOREStation Edit Start + if(!isliving(holder.my_atom)) //No more powergaming by creating a tiny amount of this + holder.clear_reagents() + //VOREStation Edit End + return + +/decl/chemical_reaction/instant/foam + name = "Foam" + id = "foam" + result = null + required_reagents = list("fluorosurfactant" = 1, "water" = 1) + result_amount = 2 + mix_message = "The solution violently bubbles!" + +/decl/chemical_reaction/instant/foam/on_reaction(var/datum/reagents/holder, var/created_volume) + var/location = get_turf(holder.my_atom) + + for(var/mob/M in viewers(5, location)) + to_chat(M, "The solution spews out foam!") + + var/datum/effect/effect/system/foam_spread/s = new() + s.set_up(created_volume, location, holder, 0) + s.start() + //VOREStation Edit Start + if(!isliving(holder.my_atom)) //No more powergaming by creating a tiny amount of this + holder.clear_reagents() + //VOREStation Edit End + return + +/decl/chemical_reaction/instant/metalfoam + name = "Metal Foam" + id = "metalfoam" + result = null + required_reagents = list("aluminum" = 3, "foaming_agent" = 1, "pacid" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/metalfoam/on_reaction(var/datum/reagents/holder, var/created_volume) + var/location = get_turf(holder.my_atom) + + for(var/mob/M in viewers(5, location)) + to_chat(M, "The solution spews out a metalic foam!") + + var/datum/effect/effect/system/foam_spread/s = new() + s.set_up(created_volume, location, holder, 1) + s.start() + return + +/decl/chemical_reaction/instant/ironfoam + name = "Iron Foam" + id = "ironlfoam" + result = null + required_reagents = list("iron" = 3, "foaming_agent" = 1, "pacid" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/ironfoam/on_reaction(var/datum/reagents/holder, var/created_volume) + var/location = get_turf(holder.my_atom) + + for(var/mob/M in viewers(5, location)) + to_chat(M, "The solution spews out a metalic foam!") + + var/datum/effect/effect/system/foam_spread/s = new() + s.set_up(created_volume, location, holder, 2) + s.start() + return + +/* Paint */ + +/decl/chemical_reaction/instant/red_paint + name = "Red paint" + id = "red_paint" + result = "paint" + required_reagents = list("plasticide" = 1, "water" = 3, "marker_ink_red" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/red_paint/send_data() + return "#FE191A" + +/decl/chemical_reaction/instant/orange_paint + name = "Orange paint" + id = "orange_paint" + result = "paint" + required_reagents = list("plasticide" = 1, "water" = 3, "marker_ink_orange" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/orange_paint/send_data() + return "#FFBE4F" + +/decl/chemical_reaction/instant/yellow_paint + name = "Yellow paint" + id = "yellow_paint" + result = "paint" + required_reagents = list("plasticide" = 1, "water" = 3, "marker_ink_yellow" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/yellow_paint/send_data() + return "#FDFE7D" + +/decl/chemical_reaction/instant/green_paint + name = "Green paint" + id = "green_paint" + result = "paint" + required_reagents = list("plasticide" = 1, "water" = 3, "marker_ink_green" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/green_paint/send_data() + return "#18A31A" + +/decl/chemical_reaction/instant/blue_paint + name = "Blue paint" + id = "blue_paint" + result = "paint" + required_reagents = list("plasticide" = 1, "water" = 3, "marker_ink_blue" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/blue_paint/send_data() + return "#247CFF" + +/decl/chemical_reaction/instant/purple_paint + name = "Purple paint" + id = "purple_paint" + result = "paint" + required_reagents = list("plasticide" = 1, "water" = 3, "marker_ink_purple" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/purple_paint/send_data() + return "#CC0099" + +/decl/chemical_reaction/instant/grey_paint //mime + name = "Grey paint" + id = "grey_paint" + result = "paint" + required_reagents = list("plasticide" = 1, "water" = 3, "marker_ink_grey" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/grey_paint/send_data() + return "#808080" + +/decl/chemical_reaction/instant/brown_paint + name = "Brown paint" + id = "brown_paint" + result = "paint" + required_reagents = list("plasticide" = 1, "water" = 3, "marker_ink_brown" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/brown_paint/send_data() + return "#846F35" + +/decl/chemical_reaction/instant/blood_paint + name = "Blood paint" + id = "blood_paint" + result = "paint" + required_reagents = list("plasticide" = 1, "water" = 3, "blood" = 2) + result_amount = 5 + +/decl/chemical_reaction/instant/blood_paint/send_data(var/datum/reagents/T) + var/t = T.get_data("blood") + if(t && t["blood_colour"]) + return t["blood_colour"] + return "#FE191A" // Probably red + +/decl/chemical_reaction/instant/milk_paint + name = "Milk paint" + id = "milk_paint" + result = "paint" + required_reagents = list("plasticide" = 1, "water" = 3, "milk" = 5) + result_amount = 5 + +/decl/chemical_reaction/instant/milk_paint/send_data() + return "#F0F8FF" + +/decl/chemical_reaction/instant/orange_juice_paint + name = "Orange juice paint" + id = "orange_juice_paint" + result = "paint" + required_reagents = list("plasticide" = 1, "water" = 3, "orangejuice" = 5) + result_amount = 5 + +/decl/chemical_reaction/instant/orange_juice_paint/send_data() + return "#E78108" + +/decl/chemical_reaction/instant/tomato_juice_paint + name = "Tomato juice paint" + id = "tomato_juice_paint" + result = "paint" + required_reagents = list("plasticide" = 1, "water" = 3, "tomatojuice" = 5) + result_amount = 5 + +/decl/chemical_reaction/instant/tomato_juice_paint/send_data() + return "#731008" + +/decl/chemical_reaction/instant/lime_juice_paint + name = "Lime juice paint" + id = "lime_juice_paint" + result = "paint" + required_reagents = list("plasticide" = 1, "water" = 3, "limejuice" = 5) + result_amount = 5 + +/decl/chemical_reaction/instant/lime_juice_paint/send_data() + return "#365E30" + +/decl/chemical_reaction/instant/carrot_juice_paint + name = "Carrot juice paint" + id = "carrot_juice_paint" + result = "paint" + required_reagents = list("plasticide" = 1, "water" = 3, "carrotjuice" = 5) + result_amount = 5 + +/decl/chemical_reaction/instant/carrot_juice_paint/send_data() + return "#973800" + +/decl/chemical_reaction/instant/berry_juice_paint + name = "Berry juice paint" + id = "berry_juice_paint" + result = "paint" + required_reagents = list("plasticide" = 1, "water" = 3, "berryjuice" = 5) + result_amount = 5 + +/decl/chemical_reaction/instant/berry_juice_paint/send_data() + return "#990066" + +/decl/chemical_reaction/instant/grape_juice_paint + name = "Grape juice paint" + id = "grape_juice_paint" + result = "paint" + required_reagents = list("plasticide" = 1, "water" = 3, "grapejuice" = 5) + result_amount = 5 + +/decl/chemical_reaction/instant/grape_juice_paint/send_data() + return "#863333" + +/decl/chemical_reaction/instant/poisonberry_juice_paint + name = "Poison berry juice paint" + id = "poisonberry_juice_paint" + result = "paint" + required_reagents = list("plasticide" = 1, "water" = 3, "poisonberryjuice" = 5) + result_amount = 5 + +/decl/chemical_reaction/instant/poisonberry_juice_paint/send_data() + return "#863353" + +/decl/chemical_reaction/instant/watermelon_juice_paint + name = "Watermelon juice paint" + id = "watermelon_juice_paint" + result = "paint" + required_reagents = list("plasticide" = 1, "water" = 3, "watermelonjuice" = 5) + result_amount = 5 + +/decl/chemical_reaction/instant/watermelon_juice_paint/send_data() + return "#B83333" + +/decl/chemical_reaction/instant/lemon_juice_paint + name = "Lemon juice paint" + id = "lemon_juice_paint" + result = "paint" + required_reagents = list("plasticide" = 1, "water" = 3, "lemonjuice" = 5) + result_amount = 5 + +/decl/chemical_reaction/instant/lemon_juice_paint/send_data() + return "#AFAF00" + +/decl/chemical_reaction/instant/banana_juice_paint + name = "Banana juice paint" + id = "banana_juice_paint" + result = "paint" + required_reagents = list("plasticide" = 1, "water" = 3, "banana" = 5) + result_amount = 5 + +/decl/chemical_reaction/instant/banana_juice_paint/send_data() + return "#C3AF00" + +/decl/chemical_reaction/instant/potato_juice_paint + name = "Potato juice paint" + id = "potato_juice_paint" + result = "paint" + required_reagents = list("plasticide" = 1, "water" = 3, "potatojuice" = 5) + result_amount = 5 + +/decl/chemical_reaction/instant/potato_juice_paint/send_data() + return "#302000" + +/decl/chemical_reaction/instant/carbon_paint + name = "Carbon paint" + id = "carbon_paint" + result = "paint" + required_reagents = list("plasticide" = 1, "water" = 3, "carbon" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/carbon_paint/send_data() + return "#333333" + +/decl/chemical_reaction/instant/aluminum_paint + name = "Aluminum paint" + id = "aluminum_paint" + result = "paint" + required_reagents = list("plasticide" = 1, "water" = 3, "aluminum" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/aluminum_paint/send_data() + return "#F0F8FF" + +//R-UST Port +/decl/chemical_reaction/instant/hydrophoron + name = "Hydrophoron" + id = "hydrophoron" + result = "hydrophoron" + required_reagents = list("hydrogen" = 1, "phoron" = 1) + inhibitors = list("nitrogen" = 1) //So it doesn't mess with lexorin + result_amount = 2 + +/decl/chemical_reaction/instant/deuterium + name = "Deuterium" + id = "deuterium" + result = "deuterium" + required_reagents = list("hydrophoron" = 1, "water" = 2) + result_amount = 3 + +//Skrellian crap. +/decl/chemical_reaction/instant/talum_quem + name = "Talum-quem" + id = "talum_quem" + result = "talum_quem" + required_reagents = list("space_drugs" = 2, "sugar" = 1, "amatoxin" = 1) + result_amount = 4 + +/decl/chemical_reaction/instant/qerr_quem + name = "Qerr-quem" + id = "qerr_quem" + result = "qerr_quem" + required_reagents = list("nicotine" = 1, "carbon" = 1, "sugar" = 2) + result_amount = 4 + +/decl/chemical_reaction/instant/malish_qualem + name = "Malish-Qualem" + id = "malish-qualem" + result = "malish-qualem" + required_reagents = list("immunosuprizine" = 1, "qerr_quem" = 1, "inaprovaline" = 1) + catalysts = list("phoron" = 5) + result_amount = 2 + +// Biomass, for cloning and bioprinters +/decl/chemical_reaction/instant/biomass + name = "Biomass" + id = "biomass" + result = "biomass" + required_reagents = list("protein" = 1, "sugar" = 1, "phoron" = 1) + result_amount = 1 // Roughly 20u per phoron sheet + +// Neutralization. + +/decl/chemical_reaction/instant/neutralize_neurotoxic_protein + name = "Neutralize Toxic Proteins" + id = "neurotoxic_protein_neutral" + result = "protein" + required_reagents = list("anti_toxin" = 1, "neurotoxic_protein" = 2) + result_amount = 2 + +/decl/chemical_reaction/instant/neutralize_carpotoxin + name = "Neutralize Carpotoxin" + id = "carpotoxin_neutral" + result = "protein" + required_reagents = list("radium" = 1, "carpotoxin" = 1, "sifsap" = 1) + catalysts = list("sifsap" = 10) + result_amount = 2 + +/decl/chemical_reaction/instant/neutralize_spidertoxin + name = "Neutralize Spidertoxin" + id = "spidertoxin_neutral" + result = "protein" + required_reagents = list("radium" = 1, "spidertoxin" = 1, "sifsap" = 1) + catalysts = list("sifsap" = 10) + result_amount = 2 \ No newline at end of file diff --git a/code/modules/reagents/Chemistry-Recipes_vr.dm b/code/modules/reagents/reactions/instant/instant_vr.dm similarity index 67% rename from code/modules/reagents/Chemistry-Recipes_vr.dm rename to code/modules/reagents/reactions/instant/instant_vr.dm index e08b3bd8f1e..b2fef2977c7 100644 --- a/code/modules/reagents/Chemistry-Recipes_vr.dm +++ b/code/modules/reagents/reactions/instant/instant_vr.dm @@ -1,7 +1,7 @@ /////////////////////////////////////////////////////////////////////////////////// /// Micro/Macro chemicals -/datum/chemical_reaction/sizeoxadone +/decl/chemical_reaction/instant/sizeoxadone name = "sizeoxadone" id = "sizeoxadone" result = "sizeoxadone" @@ -9,7 +9,7 @@ catalysts = list("phoron" = 5) result_amount = 5 -/datum/chemical_reaction/macrocillin +/decl/chemical_reaction/instant/macrocillin name = "Macrocillin" id = "macrocillin" result = "macrocillin" @@ -17,7 +17,7 @@ required_reagents = list("sizeoxadone" = 20, "diethylamine" = 20) result_amount = 1 -/datum/chemical_reaction/microcillin +/decl/chemical_reaction/instant/microcillin name = "Microcillin" id = "microcillin" result = "microcillin" @@ -25,7 +25,7 @@ required_reagents = list("sizeoxadone" = 20, "sodiumchloride" = 20) result_amount = 1 -/datum/chemical_reaction/normalcillin +/decl/chemical_reaction/instant/normalcillin name = "Normalcillin" id = "normalcillin" result = "normalcillin" @@ -33,13 +33,13 @@ required_reagents = list("sizeoxadone" = 20, "leporazine" = 20) result_amount = 1 -/datum/chemical_reaction/dontcrossthebeams +/decl/chemical_reaction/instant/dontcrossthebeams name = "Don't Cross The Beams" id = "dontcrossthebeams" result = null required_reagents = list("microcillin" = 1, "macrocillin" = 1) -/datum/chemical_reaction/dontcrossthebeams/on_reaction(var/datum/reagents/holder, var/created_volume) +/decl/chemical_reaction/instant/dontcrossthebeams/on_reaction(var/datum/reagents/holder, var/created_volume) var/location = get_turf(holder.my_atom) playsound(location, 'sound/weapons/gauss_shoot.ogg', 50, 1) var/datum/effect/effect/system/grav_pull/s = new /datum/effect/effect/system/grav_pull @@ -50,13 +50,13 @@ /////////////////////////////////////////////////////////////////////////////////// /// Miscellaneous Reactions -/datum/chemical_reaction/xenolazarus +/decl/chemical_reaction/instant/xenolazarus name = "Discount Lazarus" id = "discountlazarus" result = null required_reagents = list("monstertamer" = 5, "clonexadone" = 5) -/datum/chemical_reaction/xenolazarus/on_reaction(var/datum/reagents/holder, var/created_volume) //literally all this does is mash the regenerate button +/decl/chemical_reaction/instant/xenolazarus/on_reaction(var/datum/reagents/holder, var/created_volume) //literally all this does is mash the regenerate button if(ishuman(holder.my_atom)) var/mob/living/carbon/human/H = holder.my_atom if(H.stat == DEAD && (/mob/living/carbon/human/proc/reconstitute_form in H.verbs)) //no magical regen for non-regenners, and can't force the reaction on live ones @@ -75,10 +75,10 @@ H.visible_message("[H] twitches for a moment, but remains still.") // no nutriment -/datum/chemical_reaction/foam/softdrink +/decl/chemical_reaction/instant/foam/softdrink required_reagents = list("cola" = 1, "mint" = 1) -/datum/chemical_reaction/firefightingfoam //TODO: Make it so we can add this to the foam tanks to refill them +/decl/chemical_reaction/instant/firefightingfoam //TODO: Make it so we can add this to the foam tanks to refill them name = "Firefighting Foam" id = "firefighting foam" result = "firefoam" @@ -86,7 +86,7 @@ catalysts = list("fluorine" = 10) result_amount = 1 -/datum/chemical_reaction/firefightingfoamqol //Please don't abuse this and make us remove it. Seriously. +/decl/chemical_reaction/instant/firefightingfoamqol //Please don't abuse this and make us remove it. Seriously. name = "Firefighting Foam EZ" id = "firefighting foam ez" result = "firefoam" @@ -98,14 +98,14 @@ /////////////////////////////////////////////////////////////////////////////////// /// Vore Drugs -/datum/chemical_reaction/ickypak +/decl/chemical_reaction/instant/ickypak name = "Ickypak" id = "ickypak" result = "ickypak" required_reagents = list("hyperzine" = 4, "fluorosurfactant" = 1) result_amount = 5 -/datum/chemical_reaction/unsorbitol +/decl/chemical_reaction/instant/unsorbitol name = "Unsorbitol" id = "unsorbitol" result = "unsorbitol" @@ -114,14 +114,14 @@ /////////////////////////////////////////////////////////////////////////////////// /// Other Drugs -/datum/chemical_reaction/adranol +/decl/chemical_reaction/instant/adranol name = "Adranol" id = "adranol" result = "adranol" required_reagents = list("milk" = 2, "hydrogen" = 1, "potassium" = 1) result_amount = 3 -/datum/chemical_reaction/vermicetol +/decl/chemical_reaction/instant/vermicetol name = "Vermicetol" id = "vermicetol" result = "vermicetol" @@ -129,215 +129,16 @@ catalysts = list("phoron" = 5) result_amount = 3 -/////////////////////////////////////////////////////////////////////////////////// -/// Special drinks -/datum/chemical_reaction/drinks/grubshake - name = "Grub protein drink" - id = "grubshake" - result = "grubshake" - required_reagents = list("shockchem" = 5, "water" = 25) - result_amount = 30 - -/datum/chemical_reaction/drinks/deathbell - name = "Deathbell" - id = "deathbell" - result = "deathbell" - required_reagents = list("antifreeze" = 1, "gargleblaster" = 1, "syndicatebomb" =1) - result_amount = 3 - -/datum/chemical_reaction/drinks/monstertamer - name = "Monster Tamer" - id = "monstertamer" - result = "monstertamer" - required_reagents = list("whiskey" = 1, "protein" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/bigbeer - name = "Giant Beer" - id = "bigbeer" - result = "bigbeer" - required_reagents = list("syndicatebomb" = 1, "manlydorf" = 1, "grog" =1) - result_amount = 3 - -/datum/chemical_reaction/drinks/sweettea - name = "Sweetened Tea" - id = "sweettea" - result = "sweettea" - required_reagents = list("icetea" = 2, "sugar" = 1,) - result_amount = 3 - -/datum/chemical_reaction/drinks/unsweettea - name = "Unsweetened Tea" - id = "unsweettea" - result = "unsweettea" - required_reagents = list("sweettea" = 3, "phoron" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/galacticpanic - name = "Galactic Panic Attack" - id = "galacticpanic" - result = "galacticpanic" - required_reagents = list("gargleblaster" = 1, "singulo" = 1, "phoronspecial" =1, "neurotoxin" = 1, "atomicbomb" = 1, "hippiesdelight" = 1) - result_amount = 6 - -/datum/chemical_reaction/drinks/bulldog - name = "Space Bulldog" - id = "bulldog" - result = "bulldog" - required_reagents = list("whiterussian" = 4, "cola" =1) - result_amount = 4 - -/datum/chemical_reaction/drinks/sbagliato - name = "Negroni Sbagliato" - id = "sbagliato" - result = "sbagliato" - required_reagents = list("wine" = 1, "vermouth" = 1, "sodawater" =1) - result_amount = 3 - -/datum/chemical_reaction/drinks/italiancrisis - name = "Italian Crisis" - id = "italiancrisis" - result = "italiancrisis" - required_reagents = list("bulldog" = 1, "sbagliato" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/sugarrush - name = "Sweet Rush" - id = "sugarrush" - result = "sugarrush" - required_reagents = list("sugar" = 1, "sodawater" = 1, "vodka" =1) - result_amount = 3 - -/datum/chemical_reaction/drinks/lotus - name = "Lotus" - id = "lotus" - result = "lotus" - required_reagents = list("sbagliato" = 1, "sugarrush" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/shroomjuice - name = "Dumb Shroom Juice" - id = "shroomjuice" - result = "shroomjuice" - required_reagents = list("psilocybin" = 1, "applejuice" = 1, "limejuice" =1) - result_amount = 3 - -/datum/chemical_reaction/drinks/russianroulette - name = "Russian Roulette" - id = "russianroulette" - result = "russianroulette" - required_reagents = list("whiterussian" = 5, "iron" = 1) - result_amount = 6 - -/datum/chemical_reaction/drinks/lovemaker - name = "The Love Maker" - id = "lovemaker" - result = "lovemaker" - required_reagents = list("honey" = 1, "sexonthebeach" = 5) - result_amount = 6 - -/datum/chemical_reaction/drinks/honeyshot - name = "Honey Shot" - id = "honeyshot" - result = "honeyshot" - required_reagents = list("honey" = 1, "vodka" = 1, "grenadine" =1) - result_amount = 3 - -/datum/chemical_reaction/drinks/appletini - name = "Appletini" - id = "appletini" - result = "appletini" - required_reagents = list("applejuice" = 2, "vodka" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/glowingappletini - name = "Glowing Appletini" - id = "glowingappletini" - result = "glowingappletini" - required_reagents = list("appletini" = 5, "uranium" = 1) - result_amount = 6 - -/datum/chemical_reaction/drinks/scsatw - name = "Slow Comfortable Screw Against the Wall" - id = "scsatw" - result = "scsatw" - required_reagents = list("screwdrivercocktail" = 3, "rum" =1, "whiskey" =1, "gin" =1) - result_amount = 6 - -/datum/chemical_reaction/drinks/choccymilk - name = "Choccy Milk" - id = "choccymilk" - result = "choccymilk" - required_reagents = list("milk" = 3, "coco" = 1) - result_amount = 4 - -/datum/chemical_reaction/drinks/redspaceflush - name = "Redspace Flush" - id = "redspaceflush" - result = "redspaceflush" - required_reagents = list("rum" = 2, "whiskey" = 2, "blood" =1, "phoron" =1) - result_amount = 6 - -/datum/chemical_reaction/drinks/graveyard - name = "Graveyard" - id = "graveyard" - result = "graveyard" - required_reagents = list("cola" = 1, "spacemountainwind" = 1, "dr_gibb" =1, "space_up" = 1) - result_amount = 4 - -/datum/chemical_reaction/drinks/hairoftherat - name = "Hair of the Rat" - id = "hairoftherat" - result = "hairoftherat" - required_reagents = list("monstertamer" = 2, "nutriment" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/pink_moo - name = "Pink Moo" - id = "pinkmoo" - result = "pinkmoo" - required_reagents = list("blackrussian" = 2, "berryshake" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/originalsin - name = "Original Sin" - id = "originalsin" - result = "originalsin" - required_reagents = list("holywine" = 1) - catalysts = list("applejuice" = 1) - result_amount = 1 - -/datum/chemical_reaction/drinks/windgarita - name = "WND-Garita" - id = "windgarita" - result = "windgarita" - required_reagents = list("margarita" = 3, "spacemountainwind" = 2, "melonliquor" = 1) - result_amount = 6 - -/datum/chemical_reaction/drinks/newyorksour - name = "New York Sour" - id = "newyorksour" - result = "newyorksour" - required_reagents = list("whiskeysour" = 3, "wine" = 2, "egg" = 1) - result_amount = 6 - -/datum/chemical_reaction/drinks/mudslide - name = "Mudslide" - id = "mudslide" - result = "mudslide" - required_reagents = list("blackrussian" = 1, "irishcream" = 1) - result_amount = 2 - /////////////////////////////////////////////////////////////////////////////////// /// Reagent colonies. -/datum/chemical_reaction/meatcolony +/decl/chemical_reaction/instant/meatcolony name = "protein" id = "meatcolony" result = "protein" required_reagents = list("meatcolony" = 5, "virusfood" = 5) result_amount = 60 -/datum/chemical_reaction/plantcolony +/decl/chemical_reaction/instant/plantcolony name = "nutriment" id = "plantcolony" result = "nutriment" @@ -350,7 +151,7 @@ -/datum/chemical_reaction/slime_food +/decl/chemical_reaction/instant/slime_food name = "Slime Bork" id = "m_tele2" result = null @@ -378,7 +179,7 @@ -/datum/chemical_reaction/materials +/decl/chemical_reaction/instant/materials name = "Slime materials" id = "slimematerial" result = null @@ -435,7 +236,7 @@ C.loc = get_turf(holder.my_atom) -/datum/chemical_reaction/slimelight +/decl/chemical_reaction/instant/slimelight name = "Slime Glow" id = "m_glow" result = null @@ -448,7 +249,7 @@ F.loc = get_turf(holder.my_atom) -/datum/chemical_reaction/slimephoron +/decl/chemical_reaction/instant/slimephoron name = "Slime Phoron" id = "m_plasma" result = null @@ -459,7 +260,7 @@ P.amount = 10 P.loc = get_turf(holder.my_atom) -/datum/chemical_reaction/slimefreeze +/decl/chemical_reaction/instant/slimefreeze name = "Slime Freeze" id = "m_freeze" result = null @@ -477,7 +278,7 @@ -/datum/chemical_reaction/slimefrost +/decl/chemical_reaction/instant/slimefrost name = "Slime Frost Oil" id = "m_frostoil" result = "frostoil" @@ -487,7 +288,7 @@ -/datum/chemical_reaction/slimefire +/decl/chemical_reaction/instant/slimefire name = "Slime fire" id = "m_fire" result = null @@ -503,7 +304,7 @@ spawn (0) target_tile.hotspot_expose(700, 400) -/datum/chemical_reaction/slimeify +/decl/chemical_reaction/instant/slimeify name = "Advanced Mutation Toxin" id = "advmutationtoxin2" result = "advmutationtoxin" @@ -514,7 +315,7 @@ -/datum/chemical_reaction/slimeheal //A slime healing mixture. Why not. +/decl/chemical_reaction/instant/slimeheal //A slime healing mixture. Why not. name = "Slime Health" id = "slimeheal" result = "null" @@ -530,14 +331,14 @@ C.adjustCloneLoss(-25) C.updatehealth() -/datum/chemical_reaction/slimejelly +/decl/chemical_reaction/instant/slimejelly name = "Slime Jam" id = "m_jam" result = "slimejelly" required_reagents = list("phoron" = 20, "sugar" = 50, "lithium" = 50) //In case a xenobiologist is impatient and is willing to drain their dispenser resources, along with plasma! result_amount = 5 -/datum/chemical_reaction/slimevore +/decl/chemical_reaction/instant/slimevore name = "Slime Vore" // Hostile vore mobs only id = "m_tele" result = null @@ -600,9 +401,13 @@ for(var/j = 1, j <= rand(1, 3), j++) step(C, pick(NORTH,SOUTH,EAST,WEST)) +/decl/chemical_reaction/instant/slime/sapphire_mutation + name = "Slime Mutation Toxins" + id = "slime_mutation_tox" + result = "mutationtoxin" + required_reagents = list("blood" = 5) + result_amount = 30 + required = /obj/item/slime_extract/sapphire -/datum/chemical_reaction/food/syntiflesh - required_reagents = list("blood" = 5, "clonexadone" = 1) - -/datum/chemical_reaction/biomass +/decl/chemical_reaction/instant/biomass result_amount = 6 // Roughly 120u per phoron sheet diff --git a/code/modules/reagents/Chemistry-Readme.dm b/code/modules/reagents/readme.md similarity index 97% rename from code/modules/reagents/Chemistry-Readme.dm rename to code/modules/reagents/readme.md index 2b7e3a832a3..f9dac66b08d 100644 --- a/code/modules/reagents/Chemistry-Readme.dm +++ b/code/modules/reagents/readme.md @@ -1,305 +1,305 @@ -/* -NOTE: IF YOU UPDATE THE REAGENT-SYSTEM, ALSO UPDATE THIS README. - -Structure: /////////////////// ////////////////////////// - // Mob or object // -------> // Reagents var (datum) // Is a reference to the datum that holds the reagents. - /////////////////// ////////////////////////// - | | - The object that holds everything. V - reagent_list var (list) A List of datums, each datum is a reagent. - - | | | - V V V - - reagents (datums) Reagents. I.e. Water , antitoxins or mercury. - - -Random important notes: - - An objects on_reagent_change will be called every time the objects reagents change. - Useful if you want to update the objects icon etc. - -About the Holder: - - The holder (reagents datum) is the datum that holds a list of all reagents - currently in the object.It also has all the procs needed to manipulate reagents - - Vars: - list/datum/reagent/reagent_list - List of reagent datums. - - total_volume - Total volume of all reagents. - - maximum_volume - Maximum volume. - - atom/my_atom - Reference to the object that contains this. - - Procs: - - get_free_space() - Returns the remaining free volume in the holder. - - get_master_reagent() - Returns the reference to the reagent with the largest volume - - get_master_reagent_name() - Ditto, but returns the name. - - get_master_reagent_id() - Ditto, but returns ID. - - update_total() - Updates total volume, called automatically. - - handle_reactions() - Checks reagents and triggers any reactions that happen. Usually called automatically. - - add_reagent(var/id, var/amount, var/data = null, var/safety = 0) - Adds [amount] units of [id] reagent. [data] will be passed to reagent's mix_data() or initialize_data(). If [safety] is 0, handle_reactions() will be called. Returns 1 if successful, 0 otherwise. - - remove_reagent(var/id, var/amount, var/safety = 0) - Ditto, but removes reagent. Returns 1 if successful, 0 otherwise. - - del_reagent(var/id) - Removes all of the reagent. - - has_reagent(var/id, var/amount = 0) - Checks if holder has at least [amount] of [id] reagent. Returns 1 if the reagent is found and volume is above [amount]. Returns 0 otherwise. - - clear_reagents() - Removes all reagents. - - get_reagent_amount(var/id) - Returns reagent volume. Returns 0 if reagent is not found. - - get_data(var/id) - Returns get_data() of the reagent. - - get_reagents() - Returns a string containing all reagent ids and volumes, e.g. "carbon(4),nittrogen(5)". - - remove_any(var/amount = 1) - Removes up to [amount] of reagents from [src]. Returns actual amount removed. - - trans_to_holder(var/datum/reagents/target, var/amount = 1, var/multiplier = 1, var/copy = 0) - Transfers [amount] reagents from [src] to [target], multiplying them by [multiplier]. Returns actual amount removed from [src] (not amount transferred to [target]). If [copy] is 1, copies reagents instead. - - touch(var/atom/target) - When applying reagents to an atom externally, touch() is called to trigger any on-touch effects of the reagent. - This does not handle transferring reagents to things. - For example, splashing someone with water will get them wet and extinguish them if they are on fire, - even if they are wearing an impermeable suit that prevents the reagents from contacting the skin. - Basically just defers to touch_mob(target), touch_turf(target), or touch_obj(target), depending on target's type. - Not recommended to use this directly, since trans_to() calls it before attempting to transfer. - - touch_mob(var/mob/target) - Calls each reagent's touch_mob(target). - - touch_turf(var/turf/target) - Calls each reagent's touch_turf(target). - - touch_obj(var/obj/target) - Calls each reagent's touch_obj(target). - - trans_to(var/atom/target, var/amount = 1, var/multiplier = 1, var/copy = 0) - The general proc for applying reagents to things externally (as opposed to directly injected into the contents). - It first calls touch, then the appropriate trans_to_*() or splash_mob(). - If for some reason you want touch effects to be bypassed (e.g. injecting stuff directly into a reagent container or person), call the appropriate trans_to_*() proc. - - Calls touch() before checking the type of [target], calling splash_mob(target, amount), trans_to_turf(target, amount, multiplier, copy), or trans_to_obj(target, amount, multiplier, copy). - - trans_id_to(var/atom/target, var/id, var/amount = 1) - Transfers [amount] of [id] to [target]. Returns amount transferred. - - splash_mob(var/mob/target, var/amount = 1, var/clothes = 1) - Checks mob's clothing if [clothes] is 1 and transfers [amount] reagents to mob's skin. - Don't call this directly. Call apply_to() instead. - - trans_to_mob(var/mob/target, var/amount = 1, var/type = CHEM_BLOOD, var/multiplier = 1, var/copy = 0) - Transfers [amount] reagents to the mob's appropriate holder, depending on [type]. Ignores protection. - - trans_to_turf(var/turf/target, var/amount = 1, var/multiplier = 1, var/copy = 0) - Turfs don't currently have any reagents. Puts [amount] reagents into a temporary holder, calls touch_turf(target) from it, and deletes it. - - trans_to_obj(var/turf/target, var/amount = 1, var/multiplier = 1, var/copy = 0) - If target has reagents, transfers [amount] to it. Otherwise, same as trans_to_turf(). - - atom/proc/create_reagents(var/max_vol) - Creates a new reagent datum. - -About Reagents: - - Reagents are all the things you can mix and fille in bottles etc. This can be anything from - rejuvs over water to... iron. - - Vars: - - name - Name that shows up in-game. - - id - ID that is used for internal tracking. MUST BE UNIQUE. - - description - Description that shows up in-game. - - datum/reagents/holder - Reference to holder. - - reagent_state - Could be GAS, LIQUID, or SOLID. Affects nothing. Reserved for future use. - - list/data - Use varies by reagent. Custom variable. For example, blood stores blood group and viruses. - - volume - Current volume. - - metabolism - How quickly reagent is processed in mob's bloodstream; by default aslo affects ingest and touch metabolism. - - ingest_met - How quickly reagent is processed when ingested; [metabolism] is used if zero. - - touch_met - Ditto when touching. - - dose - How much of the reagent has been processed, limited by [max_dose]. Used for reagents with varying effects (e.g. ethanol or rezadone) and overdosing. - - max_dose - Maximum amount of reagent that has ever been in a mob. Exists so dose won't grow infinitely when small amounts of reagent are added over time. - - overdose - If [dose] is bigger than [overdose], overdose() proc is called every tick. - - scannable - If set to 1, will show up on health analyzers by name. - - affects_dead - If set to 1, will affect dead players. Used by Adminordrazine. - - glass_icon_state - Used by drinks. icon_state of the glass when this reagent is the master reagent. - - glass_name - Ditto for glass name. - - glass_desc - Ditto for glass desciption. - - glass_center_of_mass - Used for glass placement on tables. - - color - "#RRGGBB" or "#RRGGBBAA" where A is alpha channel. - - color_weight - How much reagent affects color of holder. Used by paint. - - Procs: - - remove_self(var/amount) - Removes [amount] of itself. - - touch_mob(var/mob/M) - Called when reagent is in another holder and not splashing the mob. Can be used with noncarbons. - - touch_obj(var/obj/O) - How reagent reacts with objects. - - touch_turf(var/turf/T) - How reagent reacts with turfs. - - on_mob_life(var/mob/living/carbon/M, var/alien, var/location) - Makes necessary checks and calls one of affect procs. - - affect_blood(var/mob/living/carbon/M, var/alien, var/removed) - How reagent affects mob when injected. [removed] is the amount of reagent that has been removed this tick. [alien] is the mob's reagent flag. - - affect_ingest(var/mob/living/carbon/M, var/alien, var/removed) - Ditto, ingested. Defaults to affect_blood with halved dose. - - affect_touch(var/mob/living/carbon/M, var/alien, var/removed) - Ditto, touching. - - overdose(var/mob/living/carbon/M, var/alien) - Called when dose is above overdose. Defaults to M.adjustToxLoss(REM). - - initialize_data(var/newdata) - Called when reagent is created. Defaults to setting [data] to [newdata]. - - mix_data(var/newdata, var/newamount) - Called when [newamount] of reagent with [newdata] data is added to the current reagent. Used by paint. - - get_data() - Returns data. Can be overriden. - -About Recipes: - - Recipes are simple datums that contain a list of required reagents and a result. - They also have a proc that is called when the recipe is matched. - - Vars: - - name - Name of the reaction, currently unused. - - id - ID of the reaction, must be unique. - - result - ID of the resulting reagent. Can be null. - - list/required_reagents - Reagents that are required for the reaction and are used up during it. - - list/catalysts - Ditto, but not used up. - - list/inhibitors - Opposite, prevent the reaction from happening. - - result_amount - Amount of resulting reagent. - - mix_message - Message that is shown to mobs when reaction happens. - - Procs: - - can_happen(var/datum/reagents/holder) - Customizable. If it returns 0, reaction will not happen. Defaults to always returning 1. Used by slime core reactions. - - on_reaction(var/datum/reagents/holder, var/created_volume) - Called when reaction happens. Used by explosives. - - send_data(var/datum/reagents/T) - Sets resulting reagent's data. Used by blood paint. - -About the Tools: - - By default, all atom have a reagents var - but its empty. if you want to use an object for the chem. - system you'll need to add something like this in its new proc: - - atom/proc/create_reagents(var/max_volume) - - Other important stuff: - - amount_per_transfer_from_this var - This var is mostly used by beakers and bottles. - It simply tells us how much to transfer when - 'pouring' our reagents into something else. - - atom/proc/is_open_container() - Checks atom/var/flags & OPENCONTAINER. - If this returns 1 , you can use syringes, beakers etc - to manipulate the contents of this object. - If it's 0, you'll need to write your own custom reagent - transfer code since you will not be able to use the standard - tools to manipulate it. - +/* +NOTE: IF YOU UPDATE THE REAGENT-SYSTEM, ALSO UPDATE THIS README. + +Structure: /////////////////// ////////////////////////// + // Mob or object // -------> // Reagents var (datum) // Is a reference to the datum that holds the reagents. + /////////////////// ////////////////////////// + | | + The object that holds everything. V + reagent_list var (list) A List of datums, each datum is a reagent. + + | | | + V V V + + reagents (datums) Reagents. I.e. Water , antitoxins or mercury. + + +Random important notes: + + An objects on_reagent_change will be called every time the objects reagents change. + Useful if you want to update the objects icon etc. + +About the Holder: + + The holder (reagents datum) is the datum that holds a list of all reagents + currently in the object.It also has all the procs needed to manipulate reagents + + Vars: + list/datum/reagent/reagent_list + List of reagent datums. + + total_volume + Total volume of all reagents. + + maximum_volume + Maximum volume. + + atom/my_atom + Reference to the object that contains this. + + Procs: + + get_free_space() + Returns the remaining free volume in the holder. + + get_master_reagent() + Returns the reference to the reagent with the largest volume + + get_master_reagent_name() + Ditto, but returns the name. + + get_master_reagent_id() + Ditto, but returns ID. + + update_total() + Updates total volume, called automatically. + + handle_reactions() + Checks reagents and triggers any reactions that happen. Usually called automatically. + + add_reagent(var/id, var/amount, var/data = null, var/safety = 0) + Adds [amount] units of [id] reagent. [data] will be passed to reagent's mix_data() or initialize_data(). If [safety] is 0, handle_reactions() will be called. Returns 1 if successful, 0 otherwise. + + remove_reagent(var/id, var/amount, var/safety = 0) + Ditto, but removes reagent. Returns 1 if successful, 0 otherwise. + + del_reagent(var/id) + Removes all of the reagent. + + has_reagent(var/id, var/amount = 0) + Checks if holder has at least [amount] of [id] reagent. Returns 1 if the reagent is found and volume is above [amount]. Returns 0 otherwise. + + clear_reagents() + Removes all reagents. + + get_reagent_amount(var/id) + Returns reagent volume. Returns 0 if reagent is not found. + + get_data(var/id) + Returns get_data() of the reagent. + + get_reagents() + Returns a string containing all reagent ids and volumes, e.g. "carbon(4),nittrogen(5)". + + remove_any(var/amount = 1) + Removes up to [amount] of reagents from [src]. Returns actual amount removed. + + trans_to_holder(var/datum/reagents/target, var/amount = 1, var/multiplier = 1, var/copy = 0) + Transfers [amount] reagents from [src] to [target], multiplying them by [multiplier]. Returns actual amount removed from [src] (not amount transferred to [target]). If [copy] is 1, copies reagents instead. + + touch(var/atom/target) + When applying reagents to an atom externally, touch() is called to trigger any on-touch effects of the reagent. + This does not handle transferring reagents to things. + For example, splashing someone with water will get them wet and extinguish them if they are on fire, + even if they are wearing an impermeable suit that prevents the reagents from contacting the skin. + Basically just defers to touch_mob(target), touch_turf(target), or touch_obj(target), depending on target's type. + Not recommended to use this directly, since trans_to() calls it before attempting to transfer. + + touch_mob(var/mob/target) + Calls each reagent's touch_mob(target). + + touch_turf(var/turf/target) + Calls each reagent's touch_turf(target). + + touch_obj(var/obj/target) + Calls each reagent's touch_obj(target). + + trans_to(var/atom/target, var/amount = 1, var/multiplier = 1, var/copy = 0) + The general proc for applying reagents to things externally (as opposed to directly injected into the contents). + It first calls touch, then the appropriate trans_to_*() or splash_mob(). + If for some reason you want touch effects to be bypassed (e.g. injecting stuff directly into a reagent container or person), call the appropriate trans_to_*() proc. + + Calls touch() before checking the type of [target], calling splash_mob(target, amount), trans_to_turf(target, amount, multiplier, copy), or trans_to_obj(target, amount, multiplier, copy). + + trans_id_to(var/atom/target, var/id, var/amount = 1) + Transfers [amount] of [id] to [target]. Returns amount transferred. + + splash_mob(var/mob/target, var/amount = 1, var/clothes = 1) + Checks mob's clothing if [clothes] is 1 and transfers [amount] reagents to mob's skin. + Don't call this directly. Call apply_to() instead. + + trans_to_mob(var/mob/target, var/amount = 1, var/type = CHEM_BLOOD, var/multiplier = 1, var/copy = 0) + Transfers [amount] reagents to the mob's appropriate holder, depending on [type]. Ignores protection. + + trans_to_turf(var/turf/target, var/amount = 1, var/multiplier = 1, var/copy = 0) + Turfs don't currently have any reagents. Puts [amount] reagents into a temporary holder, calls touch_turf(target) from it, and deletes it. + + trans_to_obj(var/turf/target, var/amount = 1, var/multiplier = 1, var/copy = 0) + If target has reagents, transfers [amount] to it. Otherwise, same as trans_to_turf(). + + atom/proc/create_reagents(var/max_vol) + Creates a new reagent datum. + +About Reagents: + + Reagents are all the things you can mix and fille in bottles etc. This can be anything from + rejuvs over water to... iron. + + Vars: + + name + Name that shows up in-game. + + id + ID that is used for internal tracking. MUST BE UNIQUE. + + description + Description that shows up in-game. + + datum/reagents/holder + Reference to holder. + + reagent_state + Could be GAS, LIQUID, or SOLID. Affects nothing. Reserved for future use. + + list/data + Use varies by reagent. Custom variable. For example, blood stores blood group and viruses. + + volume + Current volume. + + metabolism + How quickly reagent is processed in mob's bloodstream; by default aslo affects ingest and touch metabolism. + + ingest_met + How quickly reagent is processed when ingested; [metabolism] is used if zero. + + touch_met + Ditto when touching. + + dose + How much of the reagent has been processed, limited by [max_dose]. Used for reagents with varying effects (e.g. ethanol or rezadone) and overdosing. + + max_dose + Maximum amount of reagent that has ever been in a mob. Exists so dose won't grow infinitely when small amounts of reagent are added over time. + + overdose + If [dose] is bigger than [overdose], overdose() proc is called every tick. + + scannable + If set to 1, will show up on health analyzers by name. + + affects_dead + If set to 1, will affect dead players. Used by Adminordrazine. + + glass_icon_state + Used by drinks. icon_state of the glass when this reagent is the master reagent. + + glass_name + Ditto for glass name. + + glass_desc + Ditto for glass desciption. + + glass_center_of_mass + Used for glass placement on tables. + + color + "#RRGGBB" or "#RRGGBBAA" where A is alpha channel. + + color_weight + How much reagent affects color of holder. Used by paint. + + Procs: + + remove_self(var/amount) + Removes [amount] of itself. + + touch_mob(var/mob/M) + Called when reagent is in another holder and not splashing the mob. Can be used with noncarbons. + + touch_obj(var/obj/O) + How reagent reacts with objects. + + touch_turf(var/turf/T) + How reagent reacts with turfs. + + on_mob_life(var/mob/living/carbon/M, var/alien, var/location) + Makes necessary checks and calls one of affect procs. + + affect_blood(var/mob/living/carbon/M, var/alien, var/removed) + How reagent affects mob when injected. [removed] is the amount of reagent that has been removed this tick. [alien] is the mob's reagent flag. + + affect_ingest(var/mob/living/carbon/M, var/alien, var/removed) + Ditto, ingested. Defaults to affect_blood with halved dose. + + affect_touch(var/mob/living/carbon/M, var/alien, var/removed) + Ditto, touching. + + overdose(var/mob/living/carbon/M, var/alien) + Called when dose is above overdose. Defaults to M.adjustToxLoss(REM). + + initialize_data(var/newdata) + Called when reagent is created. Defaults to setting [data] to [newdata]. + + mix_data(var/newdata, var/newamount) + Called when [newamount] of reagent with [newdata] data is added to the current reagent. Used by paint. + + get_data() + Returns data. Can be overriden. + +About Recipes: + + Recipes are simple datums that contain a list of required reagents and a result. + They also have a proc that is called when the recipe is matched. + + Vars: + + name + Name of the reaction, currently unused. + + id + ID of the reaction, must be unique. + + result + ID of the resulting reagent. Can be null. + + list/required_reagents + Reagents that are required for the reaction and are used up during it. + + list/catalysts + Ditto, but not used up. + + list/inhibitors + Opposite, prevent the reaction from happening. + + result_amount + Amount of resulting reagent. + + mix_message + Message that is shown to mobs when reaction happens. + + Procs: + + can_happen(var/datum/reagents/holder) + Customizable. If it returns 0, reaction will not happen. Defaults to always returning 1. Used by slime core reactions. + + on_reaction(var/datum/reagents/holder, var/created_volume) + Called when reaction happens. Used by explosives. + + send_data(var/datum/reagents/T) + Sets resulting reagent's data. Used by blood paint. + +About the Tools: + + By default, all atom have a reagents var - but its empty. if you want to use an object for the chem. + system you'll need to add something like this in its new proc: + + atom/proc/create_reagents(var/max_volume) + + Other important stuff: + + amount_per_transfer_from_this var + This var is mostly used by beakers and bottles. + It simply tells us how much to transfer when + 'pouring' our reagents into something else. + + atom/proc/is_open_container() + Checks atom/var/flags & OPENCONTAINER. + If this returns 1 , you can use syringes, beakers etc + to manipulate the contents of this object. + If it's 0, you'll need to write your own custom reagent + transfer code since you will not be able to use the standard + tools to manipulate it. + */ \ No newline at end of file diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers/_reagent_containers.dm similarity index 97% rename from code/modules/reagents/reagent_containers.dm rename to code/modules/reagents/reagent_containers/_reagent_containers.dm index 7a6927f49de..64dd2622d2e 100644 --- a/code/modules/reagents/reagent_containers.dm +++ b/code/modules/reagents/reagent_containers/_reagent_containers.dm @@ -1,145 +1,145 @@ -/obj/item/weapon/reagent_containers - name = "Container" - desc = "..." - icon = 'icons/obj/chemical.dmi' - icon_state = null - w_class = ITEMSIZE_SMALL - var/amount_per_transfer_from_this = 5 - var/possible_transfer_amounts = list(5,10,15,25,30) - var/volume = 30 - -/obj/item/weapon/reagent_containers/verb/set_APTFT() //set amount_per_transfer_from_this - set name = "Set transfer amount" - set category = "Object" - set src in range(0) - var/N = input("Amount per transfer from this:","[src]") as null|anything in possible_transfer_amounts - if(N) - amount_per_transfer_from_this = N - -/obj/item/weapon/reagent_containers/Initialize() - . = ..() - if(!possible_transfer_amounts) - src.verbs -= /obj/item/weapon/reagent_containers/verb/set_APTFT - create_reagents(volume) - -/obj/item/weapon/reagent_containers/attack_self(mob/user as mob) - return - -/obj/item/weapon/reagent_containers/afterattack(obj/target, mob/user, flag) - return - -/obj/item/weapon/reagent_containers/proc/reagentlist() // For attack logs - if(reagents) - return reagents.get_reagents() - return "No reagent holder" - -/obj/item/weapon/reagent_containers/proc/standard_dispenser_refill(var/mob/user, var/obj/structure/reagent_dispensers/target) // This goes into afterattack - if(!istype(target)) - return 0 - - if(!target.reagents || !target.reagents.total_volume) - to_chat(user, "[target] is empty.") - return 1 - - if(reagents && !reagents.get_free_space()) - to_chat(user, "[src] is full.") - return 1 - - var/trans = target.reagents.trans_to_obj(src, target:amount_per_transfer_from_this) - to_chat(user, "You fill [src] with [trans] units of the contents of [target].") - return 1 - -/obj/item/weapon/reagent_containers/proc/standard_splash_mob(var/mob/user, var/mob/target) // This goes into afterattack - if(!istype(target)) - return - - if(!reagents || !reagents.total_volume) - to_chat(user, "[src] is empty.") - return 1 - - if(target.reagents && !target.reagents.get_free_space()) - to_chat(user, "[target] is full.") - return 1 - - var/contained = reagentlist() - add_attack_logs(user,target,"Splashed with [src.name] containing [contained]") - user.visible_message("[target] has been splashed with something by [user]!", "You splash the solution onto [target].") - reagents.splash(target, reagents.total_volume) - return 1 - -/obj/item/weapon/reagent_containers/proc/self_feed_message(var/mob/user) - to_chat(user, "You eat \the [src]") - -/obj/item/weapon/reagent_containers/proc/other_feed_message_start(var/mob/user, var/mob/target) - user.visible_message("[user] is trying to feed [target] \the [src]!") - -/obj/item/weapon/reagent_containers/proc/other_feed_message_finish(var/mob/user, var/mob/target) - user.visible_message("[user] has fed [target] \the [src]!") - -/obj/item/weapon/reagent_containers/proc/feed_sound(var/mob/user) - return - -/obj/item/weapon/reagent_containers/proc/standard_feed_mob(var/mob/user, var/mob/target) // This goes into attack - if(!istype(target)) - return 0 - - if(!reagents || !reagents.total_volume) - to_chat(user, "\The [src] is empty.") - return 1 - - if(target == user) - if(istype(user, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = user - if(!H.check_has_mouth()) - to_chat(user, "Where do you intend to put \the [src]? You don't have a mouth!") - return - var/obj/item/blocked = H.check_mouth_coverage() - if(blocked) - to_chat(user, "\The [blocked] is in the way!") - return - - user.setClickCooldown(user.get_attack_speed(src)) //puts a limit on how fast people can eat/drink things - self_feed_message(user) - reagents.trans_to_mob(user, issmall(user) ? CEILING(amount_per_transfer_from_this/2, 1) : amount_per_transfer_from_this, CHEM_INGEST) - feed_sound(user) - return 1 - else - if(istype(target, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = target - if(!H.check_has_mouth()) - to_chat(user, "Where do you intend to put \the [src]? \The [H] doesn't have a mouth!") - return - var/obj/item/blocked = H.check_mouth_coverage() - if(blocked) - to_chat(user, "\The [blocked] is in the way!") - return - - other_feed_message_start(user, target) - - user.setClickCooldown(user.get_attack_speed(src)) - if(!do_mob(user, target)) - return - - other_feed_message_finish(user, target) - - var/contained = reagentlist() - add_attack_logs(user,target,"Fed from [src.name] containing [contained]") - reagents.trans_to_mob(target, amount_per_transfer_from_this, CHEM_INGEST) - feed_sound(user) - return 1 - -/obj/item/weapon/reagent_containers/proc/standard_pour_into(var/mob/user, var/atom/target) // This goes into afterattack and yes, it's atom-level - if(!target.is_open_container() || !target.reagents) - return 0 - - if(!reagents || !reagents.total_volume) - to_chat(user, "[src] is empty.") - return 1 - - if(!target.reagents.get_free_space()) - to_chat(user, "[target] is full.") - return 1 - - var/trans = reagents.trans_to(target, amount_per_transfer_from_this) - to_chat(user, "You transfer [trans] units of the solution to [target].") - return 1 +/obj/item/weapon/reagent_containers + name = "Container" + desc = "..." + icon = 'icons/obj/chemical.dmi' + icon_state = null + w_class = ITEMSIZE_SMALL + var/amount_per_transfer_from_this = 5 + var/possible_transfer_amounts = list(5,10,15,25,30) + var/volume = 30 + +/obj/item/weapon/reagent_containers/verb/set_APTFT() //set amount_per_transfer_from_this + set name = "Set transfer amount" + set category = "Object" + set src in range(0) + var/N = input("Amount per transfer from this:","[src]") as null|anything in possible_transfer_amounts + if(N) + amount_per_transfer_from_this = N + +/obj/item/weapon/reagent_containers/Initialize() + . = ..() + if(!possible_transfer_amounts) + src.verbs -= /obj/item/weapon/reagent_containers/verb/set_APTFT + create_reagents(volume) + +/obj/item/weapon/reagent_containers/attack_self(mob/user as mob) + return + +/obj/item/weapon/reagent_containers/afterattack(obj/target, mob/user, flag) + return + +/obj/item/weapon/reagent_containers/proc/reagentlist() // For attack logs + if(reagents) + return reagents.get_reagents() + return "No reagent holder" + +/obj/item/weapon/reagent_containers/proc/standard_dispenser_refill(var/mob/user, var/obj/structure/reagent_dispensers/target) // This goes into afterattack + if(!istype(target)) + return 0 + + if(!target.reagents || !target.reagents.total_volume) + to_chat(user, "[target] is empty.") + return 1 + + if(reagents && !reagents.get_free_space()) + to_chat(user, "[src] is full.") + return 1 + + var/trans = target.reagents.trans_to_obj(src, target:amount_per_transfer_from_this) + to_chat(user, "You fill [src] with [trans] units of the contents of [target].") + return 1 + +/obj/item/weapon/reagent_containers/proc/standard_splash_mob(var/mob/user, var/mob/target) // This goes into afterattack + if(!istype(target)) + return + + if(!reagents || !reagents.total_volume) + to_chat(user, "[src] is empty.") + return 1 + + if(target.reagents && !target.reagents.get_free_space()) + to_chat(user, "[target] is full.") + return 1 + + var/contained = reagentlist() + add_attack_logs(user,target,"Splashed with [src.name] containing [contained]") + user.visible_message("[target] has been splashed with something by [user]!", "You splash the solution onto [target].") + reagents.splash(target, reagents.total_volume) + return 1 + +/obj/item/weapon/reagent_containers/proc/self_feed_message(var/mob/user) + to_chat(user, "You eat \the [src]") + +/obj/item/weapon/reagent_containers/proc/other_feed_message_start(var/mob/user, var/mob/target) + user.visible_message("[user] is trying to feed [target] \the [src]!") + +/obj/item/weapon/reagent_containers/proc/other_feed_message_finish(var/mob/user, var/mob/target) + user.visible_message("[user] has fed [target] \the [src]!") + +/obj/item/weapon/reagent_containers/proc/feed_sound(var/mob/user) + return + +/obj/item/weapon/reagent_containers/proc/standard_feed_mob(var/mob/user, var/mob/target) // This goes into attack + if(!istype(target)) + return 0 + + if(!reagents || !reagents.total_volume) + to_chat(user, "\The [src] is empty.") + return 1 + + if(target == user) + if(istype(user, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = user + if(!H.check_has_mouth()) + to_chat(user, "Where do you intend to put \the [src]? You don't have a mouth!") + return + var/obj/item/blocked = H.check_mouth_coverage() + if(blocked) + to_chat(user, "\The [blocked] is in the way!") + return + + user.setClickCooldown(user.get_attack_speed(src)) //puts a limit on how fast people can eat/drink things + self_feed_message(user) + reagents.trans_to_mob(user, issmall(user) ? CEILING(amount_per_transfer_from_this/2, 1) : amount_per_transfer_from_this, CHEM_INGEST) + feed_sound(user) + return 1 + else + if(istype(target, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = target + if(!H.check_has_mouth()) + to_chat(user, "Where do you intend to put \the [src]? \The [H] doesn't have a mouth!") + return + var/obj/item/blocked = H.check_mouth_coverage() + if(blocked) + to_chat(user, "\The [blocked] is in the way!") + return + + other_feed_message_start(user, target) + + user.setClickCooldown(user.get_attack_speed(src)) + if(!do_mob(user, target)) + return + + other_feed_message_finish(user, target) + + var/contained = reagentlist() + add_attack_logs(user,target,"Fed from [src.name] containing [contained]") + reagents.trans_to_mob(target, amount_per_transfer_from_this, CHEM_INGEST) + feed_sound(user) + return 1 + +/obj/item/weapon/reagent_containers/proc/standard_pour_into(var/mob/user, var/atom/target) // This goes into afterattack and yes, it's atom-level + if(!target.is_open_container() || !target.reagents) + return 0 + + if(!reagents || !reagents.total_volume) + to_chat(user, "[src] is empty.") + return 1 + + if(!target.reagents.get_free_space()) + to_chat(user, "[target] is full.") + return 1 + + var/trans = reagents.trans_to(target, amount_per_transfer_from_this) + to_chat(user, "You transfer [trans] units of the solution to [target].") + return 1 diff --git a/code/modules/reagents/Chemistry-Reagents-Helpers.dm b/code/modules/reagents/reagents/_helpers.dm similarity index 100% rename from code/modules/reagents/Chemistry-Reagents-Helpers.dm rename to code/modules/reagents/reagents/_helpers.dm diff --git a/code/modules/reagents/Chemistry-Reagents.dm b/code/modules/reagents/reagents/_reagents.dm similarity index 97% rename from code/modules/reagents/Chemistry-Reagents.dm rename to code/modules/reagents/reagents/_reagents.dm index 3d32c006637..9ab8b125daa 100644 --- a/code/modules/reagents/Chemistry-Reagents.dm +++ b/code/modules/reagents/reagents/_reagents.dm @@ -1,237 +1,241 @@ - - - -/datum/reagent - var/name = "Reagent" - var/id = "reagent" - var/description = "A non-descript chemical." - var/taste_description = "bitterness" - var/taste_mult = 1 //how this taste compares to others. Higher values means it is more noticable - var/datum/reagents/holder = null - var/reagent_state = SOLID - var/list/data = null - var/volume = 0 - var/metabolism = REM // This would be 0.2 normally - var/list/filtered_organs = list() // Organs that will slow the processing of this chemical. - var/mrate_static = FALSE //If the reagent should always process at the same speed, regardless of species, make this TRUE - var/ingest_met = 0 - var/touch_met = 0 - var/dose = 0 - var/max_dose = 0 - var/overdose = 0 //Amount at which overdose starts - var/overdose_mod = 1 //Modifier to overdose damage - var/can_overdose_touch = FALSE // Can the chemical OD when processing on touch? - var/scannable = 0 // Shows up on health analyzers. - - var/affects_dead = 0 // Does this chem process inside a corpse? - var/affects_robots = 0 // Does this chem process inside a Synth? - - var/allergen_type = GENERIC // What potential allergens does this contain? - var/allergen_factor = 1 // If the potential allergens are mixed and low-volume, they're a bit less dangerous. Needed for drinks because they're a single reagent compared to food which contains multiple seperate reagents. - - var/cup_icon_state = null - var/cup_name = null - var/cup_desc = null - var/cup_center_of_mass = null - - var/color = "#000000" - var/color_weight = 1 - - var/glass_icon = DRINK_ICON_DEFAULT - var/glass_name = "something" - var/glass_desc = "It's a glass of... what, exactly?" - var/list/glass_special = null // null equivalent to list() - -/datum/reagent/proc/remove_self(var/amount) // Shortcut - if(holder) - holder.remove_reagent(id, amount) - -// This doesn't apply to skin contact - this is for, e.g. extinguishers and sprays. The difference is that reagent is not directly on the mob's skin - it might just be on their clothing. -/datum/reagent/proc/touch_mob(var/mob/M, var/amount) - return - -/datum/reagent/proc/touch_obj(var/obj/O, var/amount) // Acid melting, cleaner cleaning, etc - return - -/datum/reagent/proc/touch_turf(var/turf/T, var/amount) // Cleaner cleaning, lube lubbing, etc, all go here - return - -/datum/reagent/proc/on_mob_life(var/mob/living/carbon/M, var/alien, var/datum/reagents/metabolism/location) // Currently, on_mob_life is called on carbons. Any interaction with non-carbon mobs (lube) will need to be done in touch_mob. - if(!istype(M)) - return - if(!affects_dead && M.stat == DEAD) - return - if(!affects_robots && M.isSynthetic()) - return - if(!istype(location)) - return - - var/datum/reagents/metabolism/active_metab = location - var/removed = metabolism - - var/ingest_rem_mult = 1 - var/ingest_abs_mult = 1 - - if(!mrate_static == TRUE) - // Modifiers - for(var/datum/modifier/mod in M.modifiers) - if(!isnull(mod.metabolism_percent)) - removed *= mod.metabolism_percent - ingest_rem_mult *= mod.metabolism_percent - // Species - removed *= M.species.metabolic_rate - ingest_rem_mult *= M.species.metabolic_rate - // Metabolism - removed *= active_metab.metabolism_speed - ingest_rem_mult *= active_metab.metabolism_speed - - if(ishuman(M)) - var/mob/living/carbon/human/H = M - if(!H.isSynthetic()) - if(H.species.has_organ[O_HEART] && (active_metab.metabolism_class == CHEM_BLOOD)) - var/obj/item/organ/internal/heart/Pump = H.internal_organs_by_name[O_HEART] - if(!Pump) - removed *= 0.1 - else if(Pump.standard_pulse_level == PULSE_NONE) // No pulse normally means chemicals process a little bit slower than normal. - removed *= 0.8 - else // Otherwise, chemicals process as per percentage of your current pulse, or, if you have no pulse but are alive, by a miniscule amount. - removed *= max(0.1, H.pulse / Pump.standard_pulse_level) - - if(H.species.has_organ[O_STOMACH] && (active_metab.metabolism_class == CHEM_INGEST)) - var/obj/item/organ/internal/stomach/Chamber = H.internal_organs_by_name[O_STOMACH] - if(Chamber) - ingest_rem_mult *= max(0.1, 1 - (Chamber.damage / Chamber.max_damage)) - else - ingest_rem_mult = 0.1 - - if(H.species.has_organ[O_INTESTINE] && (active_metab.metabolism_class == CHEM_INGEST)) - var/obj/item/organ/internal/intestine/Tube = H.internal_organs_by_name[O_INTESTINE] - if(Tube) - ingest_abs_mult *= max(0.1, 1 - (Tube.damage / Tube.max_damage)) - else - ingest_abs_mult = 0.1 - - else - var/obj/item/organ/internal/heart/machine/Pump = H.internal_organs_by_name[O_PUMP] - var/obj/item/organ/internal/stomach/machine/Cycler = H.internal_organs_by_name[O_CYCLER] - - if(active_metab.metabolism_class == CHEM_BLOOD) - if(Pump) - removed *= 1.1 - Pump.damage / Pump.max_damage - else - removed *= 0.1 - - else if(active_metab.metabolism_class == CHEM_INGEST) // If the pump is damaged, we waste chems from the tank. - if(Pump) - ingest_abs_mult *= max(0.25, 1 - Pump.damage / Pump.max_damage) - - else - ingest_abs_mult *= 0.2 - - if(Cycler) // If we're damaged, we empty our tank slower. - ingest_rem_mult = max(0.1, 1 - (Cycler.damage / Cycler.max_damage)) - - else - ingest_rem_mult = 0.1 - - else if(active_metab.metabolism_class == CHEM_TOUCH) // Machines don't exactly absorb chemicals. - removed *= 0.5 - - if(filtered_organs && filtered_organs.len) - for(var/organ_tag in filtered_organs) - var/obj/item/organ/internal/O = H.internal_organs_by_name[organ_tag] - if(O && !O.is_broken() && prob(max(0, O.max_damage - O.damage))) - removed *= 0.8 - if(active_metab.metabolism_class == CHEM_INGEST) - ingest_rem_mult *= 0.8 - - if(ingest_met && (active_metab.metabolism_class == CHEM_INGEST)) - removed = ingest_met * ingest_rem_mult - if(touch_met && (active_metab.metabolism_class == CHEM_TOUCH)) - removed = touch_met - removed = min(removed, volume) - max_dose = max(volume, max_dose) - dose = min(dose + removed, max_dose) - if(removed >= (metabolism * 0.1) || removed >= 0.1) // If there's too little chemical, don't affect the mob, just remove it - switch(active_metab.metabolism_class) - if(CHEM_BLOOD) - affect_blood(M, alien, removed) - if(CHEM_INGEST) - affect_ingest(M, alien, removed * ingest_abs_mult) - if(CHEM_TOUCH) - affect_touch(M, alien, removed) - if(overdose && (volume > overdose * M?.species.chemOD_threshold) && (active_metab.metabolism_class != CHEM_TOUCH && !can_overdose_touch)) - overdose(M, alien, removed) - if(M.species.allergens & allergen_type) //uhoh, we can't handle this! - var/damage_severity = M.species.allergen_damage_severity*allergen_factor - var/disable_severity = M.species.allergen_disable_severity*allergen_factor - if(M.species.allergen_reaction & AG_TOX_DMG) - M.adjustToxLoss(damage_severity) - if(M.species.allergen_reaction & AG_OXY_DMG) - M.adjustOxyLoss(damage_severity) - if(prob(2.5*disable_severity)) - M.emote(pick("cough","gasp","choke")) - if(M.species.allergen_reaction & AG_EMOTE) - if(prob(2.5*disable_severity)) //this has a higher base chance, but not *too* high - M.emote(pick("pale","shiver","twitch")) - if(M.species.allergen_reaction & AG_PAIN) - M.adjustHalLoss(disable_severity) - if(M.species.allergen_reaction & AG_WEAKEN) - M.Weaken(disable_severity) - if(M.species.allergen_reaction & AG_BLURRY) - M.eye_blurry = max(M.eye_blurry, disable_severity) - if(M.species.allergen_reaction & AG_SLEEPY) - M.drowsyness = max(M.drowsyness, disable_severity) - remove_self(removed) - return - -/datum/reagent/proc/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) - return - -/datum/reagent/proc/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed) - M.bloodstr.add_reagent(id, removed) - return - -/datum/reagent/proc/affect_touch(var/mob/living/carbon/M, var/alien, var/removed) - return - -/datum/reagent/proc/overdose(var/mob/living/carbon/M, var/alien, var/removed) // Overdose effect. - if(alien == IS_DIONA) - return - if(ishuman(M)) - var/mob/living/carbon/human/H = M - overdose_mod *= H.species.chemOD_mod - // 6 damage per unit at minimum, scales with excessive reagents. Rounding should help keep damage consistent between ingest / inject, but isn't perfect. - // Hardcapped at 3.6 damage per tick, or 18 damage per unit at 0.2 metabolic rate so that you can't instakill people with overdoses by feeding them infinite periadaxon. - // Overall, max damage is slightly less effective than hydrophoron, and 1/5 as effective as cyanide. - M.adjustToxLoss(min(removed * overdose_mod * round(3 + 3 * volume / overdose), 3.6)) - -/datum/reagent/proc/initialize_data(var/newdata) // Called when the reagent is created. - if(!isnull(newdata)) - data = newdata - return - -/datum/reagent/proc/mix_data(var/newdata, var/newamount) // You have a reagent with data, and new reagent with its own data get added, how do you deal with that? - return - -/datum/reagent/proc/get_data() // Just in case you have a reagent that handles data differently. - if(data && istype(data, /list)) - return data.Copy() - else if(data) - return data - return null - -/datum/reagent/Destroy() // This should only be called by the holder, so it's already handled clearing its references - holder = null - . = ..() - -/* DEPRECATED - TODO: REMOVE EVERYWHERE */ - -/datum/reagent/proc/reaction_turf(var/turf/target) - touch_turf(target) - -/datum/reagent/proc/reaction_obj(var/obj/target) - touch_obj(target) - -/datum/reagent/proc/reaction_mob(var/mob/target) - touch_mob(target) + + + +/datum/reagent + var/name = "Reagent" + var/id = "reagent" + var/description = "A non-descript chemical." + var/taste_description = "bitterness" + var/taste_mult = 1 //how this taste compares to others. Higher values means it is more noticable + var/datum/reagents/holder = null + var/reagent_state = SOLID + var/list/data = null + var/volume = 0 + var/metabolism = REM // This would be 0.2 normally + var/list/filtered_organs = list() // Organs that will slow the processing of this chemical. + var/mrate_static = FALSE //If the reagent should always process at the same speed, regardless of species, make this TRUE + var/ingest_met = 0 + var/touch_met = 0 + var/dose = 0 + var/max_dose = 0 + var/overdose = 0 //Amount at which overdose starts + var/overdose_mod = 1 //Modifier to overdose damage + var/can_overdose_touch = FALSE // Can the chemical OD when processing on touch? + var/scannable = 0 // Shows up on health analyzers. + + var/affects_dead = 0 // Does this chem process inside a corpse? + var/affects_robots = 0 // Does this chem process inside a Synth? + + var/allergen_type = GENERIC // What potential allergens does this contain? + var/allergen_factor = 1 // If the potential allergens are mixed and low-volume, they're a bit less dangerous. Needed for drinks because they're a single reagent compared to food which contains multiple seperate reagents. + + var/cup_icon_state = null + var/cup_name = null + var/cup_desc = null + var/cup_center_of_mass = null + + var/color = "#000000" + var/color_weight = 1 + + var/glass_icon = DRINK_ICON_DEFAULT + var/glass_name = "something" + var/glass_desc = "It's a glass of... what, exactly?" + var/list/glass_special = null // null equivalent to list() + +/datum/reagent/proc/remove_self(var/amount) // Shortcut + if(holder) + holder.remove_reagent(id, amount) + +// This doesn't apply to skin contact - this is for, e.g. extinguishers and sprays. The difference is that reagent is not directly on the mob's skin - it might just be on their clothing. +/datum/reagent/proc/touch_mob(var/mob/M, var/amount) + return + +/datum/reagent/proc/touch_obj(var/obj/O, var/amount) // Acid melting, cleaner cleaning, etc + return + +/datum/reagent/proc/touch_turf(var/turf/T, var/amount) // Cleaner cleaning, lube lubbing, etc, all go here + return + +/datum/reagent/proc/on_mob_life(var/mob/living/carbon/M, var/alien, var/datum/reagents/metabolism/location) // Currently, on_mob_life is called on carbons. Any interaction with non-carbon mobs (lube) will need to be done in touch_mob. + if(!istype(M)) + return + if(!affects_dead && M.stat == DEAD) + return + if(!affects_robots && M.isSynthetic()) + return + if(!istype(location)) + return + + var/datum/reagents/metabolism/active_metab = location + var/removed = metabolism + + var/ingest_rem_mult = 1 + var/ingest_abs_mult = 1 + + if(!mrate_static == TRUE) + // Modifiers + for(var/datum/modifier/mod in M.modifiers) + if(!isnull(mod.metabolism_percent)) + removed *= mod.metabolism_percent + ingest_rem_mult *= mod.metabolism_percent + // Species + removed *= M.species.metabolic_rate + ingest_rem_mult *= M.species.metabolic_rate + // Metabolism + removed *= active_metab.metabolism_speed + ingest_rem_mult *= active_metab.metabolism_speed + + if(ishuman(M)) + var/mob/living/carbon/human/H = M + if(!H.isSynthetic()) + if(H.species.has_organ[O_HEART] && (active_metab.metabolism_class == CHEM_BLOOD)) + var/obj/item/organ/internal/heart/Pump = H.internal_organs_by_name[O_HEART] + if(!Pump) + removed *= 0.1 + else if(Pump.standard_pulse_level == PULSE_NONE) // No pulse normally means chemicals process a little bit slower than normal. + removed *= 0.8 + else // Otherwise, chemicals process as per percentage of your current pulse, or, if you have no pulse but are alive, by a miniscule amount. + removed *= max(0.1, H.pulse / Pump.standard_pulse_level) + + if(H.species.has_organ[O_STOMACH] && (active_metab.metabolism_class == CHEM_INGEST)) + var/obj/item/organ/internal/stomach/Chamber = H.internal_organs_by_name[O_STOMACH] + if(Chamber) + ingest_rem_mult *= max(0.1, 1 - (Chamber.damage / Chamber.max_damage)) + else + ingest_rem_mult = 0.1 + + if(H.species.has_organ[O_INTESTINE] && (active_metab.metabolism_class == CHEM_INGEST)) + var/obj/item/organ/internal/intestine/Tube = H.internal_organs_by_name[O_INTESTINE] + if(Tube) + ingest_abs_mult *= max(0.1, 1 - (Tube.damage / Tube.max_damage)) + else + ingest_abs_mult = 0.1 + + else + var/obj/item/organ/internal/heart/machine/Pump = H.internal_organs_by_name[O_PUMP] + var/obj/item/organ/internal/stomach/machine/Cycler = H.internal_organs_by_name[O_CYCLER] + + if(active_metab.metabolism_class == CHEM_BLOOD) + if(Pump) + removed *= 1.1 - Pump.damage / Pump.max_damage + else + removed *= 0.1 + + else if(active_metab.metabolism_class == CHEM_INGEST) // If the pump is damaged, we waste chems from the tank. + if(Pump) + ingest_abs_mult *= max(0.25, 1 - Pump.damage / Pump.max_damage) + + else + ingest_abs_mult *= 0.2 + + if(Cycler) // If we're damaged, we empty our tank slower. + ingest_rem_mult = max(0.1, 1 - (Cycler.damage / Cycler.max_damage)) + + else + ingest_rem_mult = 0.1 + + else if(active_metab.metabolism_class == CHEM_TOUCH) // Machines don't exactly absorb chemicals. + removed *= 0.5 + + if(filtered_organs && filtered_organs.len) + for(var/organ_tag in filtered_organs) + var/obj/item/organ/internal/O = H.internal_organs_by_name[organ_tag] + if(O && !O.is_broken() && prob(max(0, O.max_damage - O.damage))) + removed *= 0.8 + if(active_metab.metabolism_class == CHEM_INGEST) + ingest_rem_mult *= 0.8 + + if(ingest_met && (active_metab.metabolism_class == CHEM_INGEST)) + removed = ingest_met * ingest_rem_mult + if(touch_met && (active_metab.metabolism_class == CHEM_TOUCH)) + removed = touch_met + removed = min(removed, volume) + max_dose = max(volume, max_dose) + dose = min(dose + removed, max_dose) + if(removed >= (metabolism * 0.1) || removed >= 0.1) // If there's too little chemical, don't affect the mob, just remove it + switch(active_metab.metabolism_class) + if(CHEM_BLOOD) + affect_blood(M, alien, removed) + if(CHEM_INGEST) + affect_ingest(M, alien, removed * ingest_abs_mult) + if(CHEM_TOUCH) + affect_touch(M, alien, removed) + if(overdose && (volume > overdose * M?.species.chemOD_threshold) && (active_metab.metabolism_class != CHEM_TOUCH && !can_overdose_touch)) + overdose(M, alien, removed) + if(M.species.allergens & allergen_type) //uhoh, we can't handle this! + var/damage_severity = M.species.allergen_damage_severity*allergen_factor + var/disable_severity = M.species.allergen_disable_severity*allergen_factor + if(M.species.allergen_reaction & AG_TOX_DMG) + M.adjustToxLoss(damage_severity) + if(M.species.allergen_reaction & AG_OXY_DMG) + M.adjustOxyLoss(damage_severity) + if(prob(2.5*disable_severity)) + M.emote(pick("cough","gasp","choke")) + if(M.species.allergen_reaction & AG_EMOTE) + if(prob(2.5*disable_severity)) //this has a higher base chance, but not *too* high + M.emote(pick("pale","shiver","twitch")) + if(M.species.allergen_reaction & AG_PAIN) + M.adjustHalLoss(disable_severity) + if(M.species.allergen_reaction & AG_WEAKEN) + M.Weaken(disable_severity) + if(M.species.allergen_reaction & AG_BLURRY) + M.eye_blurry = max(M.eye_blurry, disable_severity) + if(M.species.allergen_reaction & AG_SLEEPY) + M.drowsyness = max(M.drowsyness, disable_severity) + remove_self(removed) + return + +/datum/reagent/proc/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) + return + +/datum/reagent/proc/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed) + M.bloodstr.add_reagent(id, removed) + return + +/datum/reagent/proc/affect_touch(var/mob/living/carbon/M, var/alien, var/removed) + return + +/datum/reagent/proc/overdose(var/mob/living/carbon/M, var/alien, var/removed) // Overdose effect. + if(alien == IS_DIONA) + return + if(ishuman(M)) + var/mob/living/carbon/human/H = M + overdose_mod *= H.species.chemOD_mod + // 6 damage per unit at minimum, scales with excessive reagents. Rounding should help keep damage consistent between ingest / inject, but isn't perfect. + // Hardcapped at 3.6 damage per tick, or 18 damage per unit at 0.2 metabolic rate so that you can't instakill people with overdoses by feeding them infinite periadaxon. + // Overall, max damage is slightly less effective than hydrophoron, and 1/5 as effective as cyanide. + M.adjustToxLoss(min(removed * overdose_mod * round(3 + 3 * volume / overdose), 3.6)) + +/datum/reagent/proc/initialize_data(var/newdata) // Called when the reagent is created. + if(!isnull(newdata)) + data = newdata + return + +/datum/reagent/proc/mix_data(var/newdata, var/newamount) // You have a reagent with data, and new reagent with its own data get added, how do you deal with that? + return + +/datum/reagent/proc/get_data() // Just in case you have a reagent that handles data differently. + if(data && istype(data, /list)) + return data.Copy() + else if(data) + return data + return null + +/datum/reagent/Destroy() // This should only be called by the holder, so it's already handled clearing its references + holder = null + . = ..() + +/* DEPRECATED - TODO: REMOVE EVERYWHERE */ + +/datum/reagent/proc/reaction_turf(var/turf/target) + touch_turf(target) + +/datum/reagent/proc/reaction_obj(var/obj/target) + touch_obj(target) + +/datum/reagent/proc/reaction_mob(var/mob/target) + touch_mob(target) + +/// Called by [/datum/reagents/proc/conditional_update] +/datum/reagent/proc/on_update(atom/A) + return diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm b/code/modules/reagents/reagents/core.dm similarity index 100% rename from code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm rename to code/modules/reagents/reagents/core.dm diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm b/code/modules/reagents/reagents/dispenser.dm similarity index 100% rename from code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm rename to code/modules/reagents/reagents/dispenser.dm diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm b/code/modules/reagents/reagents/food_drinks.dm similarity index 100% rename from code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm rename to code/modules/reagents/reagents/food_drinks.dm diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks_vr.dm b/code/modules/reagents/reagents/food_drinks_vr.dm similarity index 91% rename from code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks_vr.dm rename to code/modules/reagents/reagents/food_drinks_vr.dm index 246bb05b2c8..55436f295c5 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks_vr.dm +++ b/code/modules/reagents/reagents/food_drinks_vr.dm @@ -458,4 +458,62 @@ M.adjustToxLoss(removed) //Equivalent to half as much protein, since it's half protein. if(M.species.organic_food_coeff) if(alien == IS_SLIME || alien == IS_CHIMERA) //slimes and chimera can get nutrition from injected nutriment and protein - M.nutrition += (alt_nutriment_factor * removed) \ No newline at end of file + M.nutrition += (alt_nutriment_factor * removed) + +//////////////////////Bepis Drinks (04/29/2021)////////////////////// + +/datum/reagent/drink/soda/bepis_cola + name = "Bepis" + id = "bepis" + description = "A weird cola-like beverage." + taste_description = "bepsi" + reagent_state = LIQUID + color = "#100800" + adj_drowsy = -3 + adj_temp = -5 + + glass_name = "Bepis Cola" + glass_desc = "A glass of weird cola beverage." + glass_special = list(DRINK_FIZZ) + +/datum/reagent/drink/soda/buzz_fuzz + name = "Buzz Fuzz" + id = "buzz_fuzz" + description = "A delicious frontier beverage that's simply a Hive of Flavour!" + taste_description = "carbonated honey and pollen" + reagent_state = LIQUID + color = "#8CFF00" + adj_drowsy = -3 + adj_temp = -5 + + glass_name = "Buzz Fuzz" + glass_desc = "A glass that's stinging with flavour." + glass_special = list(DRINK_FIZZ) + +/datum/reagent/drink/soda/sprited_cranberry + name = "Sprited Cranberry" + id = "sprited_cranberry" + description = "A winter spiced cranberry drink. Perfect for year-round consumption." + taste_description = "sweet spiced cranberry" + reagent_state = LIQUID + color = "#fffafa" + adj_drowsy = -3 + adj_temp = -5 + + glass_name = "Sprited Cranberry" + glass_desc = "A glass of sprited cranberry" + glass_special = list(DRINK_FIZZ) + +/datum/reagent/drink/soda/shamblers + name = "Shambler's Juice" + id = "shamblers" + description = "A strange off-brand beverage that's bursting with flavor." + taste_description = "carbonated metallic soda" + reagent_state = LIQUID + color = "#f00060" + adj_drowsy = -3 + adj_temp = -5 + + glass_name = "Shambler's Juice" + glass_desc = "A glass of something shambly" + glass_special = list(DRINK_FIZZ) \ No newline at end of file diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm b/code/modules/reagents/reagents/medicine.dm similarity index 100% rename from code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm rename to code/modules/reagents/reagents/medicine.dm diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine_vr.dm b/code/modules/reagents/reagents/medicine_vr.dm similarity index 100% rename from code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine_vr.dm rename to code/modules/reagents/reagents/medicine_vr.dm diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Modifiers.dm b/code/modules/reagents/reagents/modifiers.dm similarity index 100% rename from code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Modifiers.dm rename to code/modules/reagents/reagents/modifiers.dm diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Other.dm b/code/modules/reagents/reagents/other.dm similarity index 90% rename from code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Other.dm rename to code/modules/reagents/reagents/other.dm index 5c1c9cf4274..9e83c720bc2 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Other.dm +++ b/code/modules/reagents/reagents/other.dm @@ -238,14 +238,6 @@ reagent_state = SOLID color = "#D0D0D0" -/datum/reagent/uranium - name ="Uranium" - id = "uranium" - description = "A silvery-white metallic chemical element in the actinide series, weakly radioactive." - taste_description = "metal" - reagent_state = SOLID - color = "#B8B8C0" - /datum/reagent/platinum name = "Platinum" id = "platinum" @@ -254,6 +246,14 @@ reagent_state = SOLID color = "#777777" +/datum/reagent/uranium + name ="Uranium" + id = "uranium" + description = "A silvery-white metallic chemical element in the actinide series, weakly radioactive." + taste_description = "metal" + reagent_state = SOLID + color = "#B8B8C0" + /datum/reagent/uranium/affect_touch(var/mob/living/carbon/M, var/alien, var/removed) affect_ingest(M, alien, removed) @@ -268,6 +268,55 @@ new /obj/effect/decal/cleanable/greenglow(T) return +/datum/reagent/hydrogen/deuterium + name = "Deuterium" + id = "deuterium" + description = "A isotope of hydrogen. It has one extra neutron, and shares all chemical characteristics with hydrogen." + +/datum/reagent/hydrogen/tritium + name = "Tritium" + id = "tritium" + description = "A radioactive isotope of hydrogen. It has two extra neutrons, and shares all other chemical characteristics with hydrogen." + +/datum/reagent/lithium/lithium6 + name = "Lithium-6" + id = "lithium6" + description = "An isotope of lithium. It has 3 neutrons, but shares all chemical characteristics with regular lithium." + +/datum/reagent/helium/helium3 + name = "Helium-3" + id = "helium3" + description = "An isotope of helium. It only has one neutron, but shares all chemical characteristics with regular helium." + taste_mult = 0 + reagent_state = GAS + color = "#808080" + +/datum/reagent/boron/boron11 + name = "Boron-11" + id = "boron11" + description = "An isotope of boron. It has 6 neutrons." + taste_description = "metallic" // Apparently noone on the internet knows what boron tastes like. Or at least they won't share + +/datum/reagent/supermatter + name = "Supermatter" + id = "supermatter" + description = "The immense power of a supermatter crystal, in liquid form. You're not entirely sure how that's possible, but it's probably best handled with care." + taste_description = "taffy" // 0. The supermatter is tasty, tasty taffy. + +// Same as if you boop it wrong. It touches you, you die +/datum/reagent/supermatter/affect_touch(mob/living/carbon/M, alien, removed) + . = ..() + M.ash() + +/datum/reagent/supermatter/affect_ingest(mob/living/carbon/M, alien, removed) + . = ..() + M.ash() + +/datum/reagent/supermatter/affect_blood(mob/living/carbon/M, alien, removed) + . = ..() + M.ash() + + /datum/reagent/adrenaline name = "Adrenaline" id = "adrenaline" diff --git a/code/modules/reagents/Chemistry-Reagents_vr.dm b/code/modules/reagents/reagents/other_vr.dm similarity index 95% rename from code/modules/reagents/Chemistry-Reagents_vr.dm rename to code/modules/reagents/reagents/other_vr.dm index f6cd245dee7..b1146960ed9 100644 --- a/code/modules/reagents/Chemistry-Reagents_vr.dm +++ b/code/modules/reagents/reagents/other_vr.dm @@ -28,14 +28,6 @@ BI.forceMove(torso) torso.implants += BI -/datum/chemical_reaction/slime/sapphire_mutation - name = "Slime Mutation Toxins" - id = "slime_mutation_tox" - result = "mutationtoxin" - required_reagents = list("blood" = 5) - result_amount = 30 - required = /obj/item/slime_extract/sapphire - /datum/reagent/nif_repair_nanites name = "Programmed Nanomachines" id = "nifrepairnanites" diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm b/code/modules/reagents/reagents/toxins.dm similarity index 100% rename from code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm rename to code/modules/reagents/reagents/toxins.dm diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Vore_vr.dm b/code/modules/reagents/reagents/vore_vr.dm similarity index 100% rename from code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Vore_vr.dm rename to code/modules/reagents/reagents/vore_vr.dm diff --git a/code/modules/research/rdconsole.dm b/code/modules/research/rdconsole.dm index 370a460bc73..3d58a40b16b 100755 --- a/code/modules/research/rdconsole.dm +++ b/code/modules/research/rdconsole.dm @@ -70,10 +70,12 @@ won't update every console in existence) but it's more of a hassle to do. Also, return return_name /obj/machinery/computer/rdconsole/proc/CallReagentName(var/ID) - var/datum/reagent/R = SSchemistry.chemical_reagents["[ID]"] - if(!R) - return ID - return R.name + var/return_name = ID + for(var/datum/reagent/R in SSchemistry.chemical_reagents) + if(R.id == ID) + return_name = R.name + break + return return_name /obj/machinery/computer/rdconsole/proc/SyncRDevices() //Makes sure it is properly sync'ed up with the devices attached to it (if any). for(var/obj/machinery/r_n_d/D in range(3, src)) diff --git a/code/modules/spells/spell_code.dm b/code/modules/spells/spell_code.dm index 6c57fa60376..f2a85f7bbe6 100644 --- a/code/modules/spells/spell_code.dm +++ b/code/modules/spells/spell_code.dm @@ -267,7 +267,7 @@ var/list/spells = typesof(/spell) //needed for the badmin verb for now else user.whisper(replacetext(invocation," ","`")) if(SpI_EMOTE) - user.emote("me", 1, invocation) //the 1 means it's for everyone in view, the me makes it an emote, and the invocation is written accordingly. + user.custom_emote(VISIBLE_MESSAGE, invocation) ///////////////////// ///UPGRADING PROCS/// diff --git a/code/modules/tgui/modules/appearance_changer.dm b/code/modules/tgui/modules/appearance_changer.dm index e9478c3c31d..d063d6b41a3 100644 --- a/code/modules/tgui/modules/appearance_changer.dm +++ b/code/modules/tgui/modules/appearance_changer.dm @@ -542,7 +542,7 @@ // VOREStation Add - Ears/Tails/Wings /datum/tgui_module/appearance_changer/proc/can_use_sprite(datum/sprite_accessory/X, mob/living/carbon/human/target, mob/user) - if(X.apply_restrictions && !(target.species.name in X.species_allowed)) + if(!isnull(X.species_allowed) && !(target.species.name in X.species_allowed)) return FALSE if(LAZYLEN(X.ckeys_allowed) && !(user?.ckey in X.ckeys_allowed) && !(target.ckey in X.ckeys_allowed)) diff --git a/code/modules/vore/eating/belly_obj_vr.dm b/code/modules/vore/eating/belly_obj_vr.dm index 7f7f33e0e45..ab82f4c6d15 100644 --- a/code/modules/vore/eating/belly_obj_vr.dm +++ b/code/modules/vore/eating/belly_obj_vr.dm @@ -21,6 +21,7 @@ var/nutrition_percent = 100 // Nutritional percentage per tick in digestion mode var/digest_brute = 0.5 // Brute damage per tick in digestion mode var/digest_burn = 0.5 // Burn damage per tick in digestion mode + var/digest_oxy = 0 // Oxy damage per tick in digestion mode var/immutable = FALSE // Prevents this belly from being deleted var/escapable = FALSE // Belly can be resisted out of at any time var/escapetime = 20 SECONDS // Deciseconds, how long to escape this belly @@ -49,7 +50,7 @@ //Actual full digest modes var/tmp/static/list/digest_modes = list(DM_HOLD,DM_DIGEST,DM_ABSORB,DM_DRAIN,DM_UNABSORB,DM_HEAL,DM_SHRINK,DM_GROW,DM_SIZE_STEAL,DM_EGG) //Digest mode addon flags - var/tmp/static/list/mode_flag_list = list("Numbing" = DM_FLAG_NUMBING, "Stripping" = DM_FLAG_STRIPPING, "Leave Remains" = DM_FLAG_LEAVEREMAINS, "Muffles" = DM_FLAG_THICKBELLY, "Affect Worn Items" = DM_FLAG_AFFECTWORN) + var/tmp/static/list/mode_flag_list = list("Numbing" = DM_FLAG_NUMBING, "Stripping" = DM_FLAG_STRIPPING, "Leave Remains" = DM_FLAG_LEAVEREMAINS, "Muffles" = DM_FLAG_THICKBELLY, "Affect Worn Items" = DM_FLAG_AFFECTWORN, "Jams Sensors" = DM_FLAG_JAMSENSORS) //Item related modes var/tmp/static/list/item_digest_modes = list(IM_HOLD,IM_DIGEST_FOOD,IM_DIGEST) @@ -132,6 +133,7 @@ "nutrition_percent", "digest_brute", "digest_burn", + "digest_oxy", "immutable", "can_taste", "escapable", @@ -760,6 +762,7 @@ dupe.nutrition_percent = nutrition_percent dupe.digest_brute = digest_brute dupe.digest_burn = digest_burn + dupe.digest_oxy = digest_oxy dupe.immutable = immutable dupe.can_taste = can_taste dupe.escapable = escapable diff --git a/code/modules/vore/eating/bellymodes_datum_vr.dm b/code/modules/vore/eating/bellymodes_datum_vr.dm index 4d9199b7270..ea6f9b67b2b 100644 --- a/code/modules/vore/eating/bellymodes_datum_vr.dm +++ b/code/modules/vore/eating/bellymodes_datum_vr.dm @@ -41,11 +41,14 @@ GLOBAL_LIST_INIT(digest_modes, list()) // Deal digestion damage (and feed the pred) var/old_brute = L.getBruteLoss() var/old_burn = L.getFireLoss() + var/old_oxy = L.getOxyLoss() L.adjustBruteLoss(B.digest_brute) L.adjustFireLoss(B.digest_burn) + L.adjustOxyLoss(B.digest_oxy) var/actual_brute = L.getBruteLoss() - old_brute var/actual_burn = L.getFireLoss() - old_burn - var/damage_gain = (actual_brute + actual_burn)*(B.nutrition_percent / 100) + var/actual_oxy = L.getOxyLoss() - old_oxy + var/damage_gain = (actual_brute + actual_burn + actual_oxy/2)*(B.nutrition_percent / 100) var/offset = (1 + ((L.weight - 137) / 137)) // 130 pounds = .95 140 pounds = 1.02 var/difference = B.owner.size_multiplier / L.size_multiplier diff --git a/code/modules/vore/eating/bellymodes_vr.dm b/code/modules/vore/eating/bellymodes_vr.dm index 428871edf97..eca51127c2e 100644 --- a/code/modules/vore/eating/bellymodes_vr.dm +++ b/code/modules/vore/eating/bellymodes_vr.dm @@ -76,6 +76,8 @@ if(!digestion_noise_chance) digestion_noise_chance = DM.noise_chance + +///////////////////// Time to actually process mobs ///////////////////// for(var/target in touchable_mobs) var/mob/living/L = target if(!istype(L)) diff --git a/code/modules/vore/eating/contaminate_vr.dm b/code/modules/vore/eating/contaminate_vr.dm index 998c7b53c53..2a9f9ac05ff 100644 --- a/code/modules/vore/eating/contaminate_vr.dm +++ b/code/modules/vore/eating/contaminate_vr.dm @@ -96,7 +96,7 @@ var/list/gurgled_overlays = list( // Special handling of gurgle_contaminate ////////////// /obj/item/weapon/card/id/gurgle_contaminate(var/atom/movable/item_storage = null) - digest_act(item_storage) //Digesting these anyway + digest_act(item_storage) //Contamination and digestion does same thing to these return TRUE /obj/item/device/pda/gurgle_contaminate(var/atom/movable/item_storage = null) diff --git a/code/modules/vore/eating/digest_act_vr.dm b/code/modules/vore/eating/digest_act_vr.dm index b2958d0ddfd..3e3ed7f737f 100644 --- a/code/modules/vore/eating/digest_act_vr.dm +++ b/code/modules/vore/eating/digest_act_vr.dm @@ -26,7 +26,7 @@ if(isbelly(item_storage)) var/obj/belly/B = item_storage - g_damage = 0.25 * (B.digest_brute + B.digest_burn) + g_damage = 0.25 * (B.digest_brute + B.digest_burn + (B.digest_oxy)/2) if(digest_stage > 0) if(g_damage > digest_stage) @@ -55,8 +55,6 @@ ///////////// /obj/item/weapon/hand_tele/digest_act(var/atom/movable/item_storage = null) return FALSE -/obj/item/weapon/card/id/gold/captain/spare/digest_act(var/atom/movable/item_storage = null) - return FALSE /obj/item/device/aicard/digest_act(var/atom/movable/item_storage = null) return FALSE /obj/item/device/paicard/digest_act(var/atom/movable/item_storage = null) @@ -78,20 +76,14 @@ // Some special treatment ///////////// -/obj/item/weapon/card/id - var/lost_access = list() - /obj/item/weapon/card/id/digest_act(atom/movable/item_storage = null) - desc = "A partially digested card that has seen better days. The damage appears to be only cosmetic, but the access codes need to be reprogrammed at the HoP office or ID restoration terminal." + desc = "A partially digested card that has seen better days. The damage appears to be only cosmetic." if(!sprite_stack || !istype(sprite_stack) || !(sprite_stack.len)) icon = 'icons/obj/card_vr.dmi' icon_state = "[initial(icon_state)]_digested" else sprite_stack += "digested" update_icon() - if(!(LAZYLEN(lost_access)) && LAZYLEN(access)) - lost_access = access //Do not forget what access we lose - access = list() // Then lose it return FALSE /obj/item/weapon/reagent_containers/food/digest_act(atom/movable/item_storage = null) @@ -119,7 +111,7 @@ if((. = ..())) if(isbelly(item_storage)) var/obj/belly/B = item_storage - . += 2 * (B.digest_brute + B.digest_burn) + . += 2 * (B.digest_brute + B.digest_burn + (B.digest_oxy)/2) else . += 30 //Organs give a little more diff --git a/code/modules/vore/eating/vorepanel_vr.dm b/code/modules/vore/eating/vorepanel_vr.dm index b5b29fa7dfe..5a47029b139 100644 --- a/code/modules/vore/eating/vorepanel_vr.dm +++ b/code/modules/vore/eating/vorepanel_vr.dm @@ -154,6 +154,7 @@ "nutrition_percent" = selected.nutrition_percent, "digest_brute" = selected.digest_brute, "digest_burn" = selected.digest_burn, + "digest_oxy" = selected.digest_oxy, "bulge_size" = selected.bulge_size, "shrink_grow_size" = selected.shrink_grow_size, "emote_time" = selected.emote_time, @@ -843,6 +844,12 @@ var/new_new_damage = CLAMP(new_damage, 0, 6) host.vore_selected.digest_brute = new_new_damage . = TRUE + if("b_oxy_dmg") + var/new_damage = input(user, "Choose the amount of suffocation damage prey will take per tick. Ranges from 0 to 12.", "Set Belly Suffocation Damage.", host.vore_selected.digest_oxy) as num|null + if(new_damage == null) + return FALSE + var/new_new_damage = CLAMP(new_damage, 0, 12) + host.vore_selected.digest_oxy = new_new_damage if("b_emoteactive") host.vore_selected.emote_active = !host.vore_selected.emote_active . = TRUE diff --git a/code/modules/vore/fluffstuff/custom_clothes_vr.dm b/code/modules/vore/fluffstuff/custom_clothes_vr.dm index 14d75133bb2..74dae36ba4f 100644 --- a/code/modules/vore/fluffstuff/custom_clothes_vr.dm +++ b/code/modules/vore/fluffstuff/custom_clothes_vr.dm @@ -2288,7 +2288,7 @@ Departamental Swimsuits, for general use body_parts_covered = UPPER_TORSO|LOWER_TORSO|FEET|ARMS|HANDS //PastelPrinceDan: Kiyoshi Maki -/obj/item/clothing/accessory/poncho/fluff/cloakglowing +/obj/item/clothing/accessory/poncho/roles/cloak/fluff/cloakglowing name = "glowing cloak" desc = "A fancy cloak with a RGB LED color strip along the trim, cycling through the colors of the rainbow." icon = 'icons/vore/custom_clothes_vr.dmi' @@ -2298,17 +2298,17 @@ Departamental Swimsuits, for general use icon_override = 'icons/vore/custom_onmob_vr.dmi' var/is_dark = FALSE -/obj/item/clothing/accessory/poncho/fluff/cloakglowing/equipped() +/obj/item/clothing/accessory/poncho/roles/cloak/fluff/cloakglowing/equipped() ..() var/mob/living/carbon/human/H = loc if(istype(H) && H.wear_suit == src) icon_override = 'icons/vore/custom_onmob_vr.dmi' update_clothing_icon() -/obj/item/clothing/accessory/poncho/fluff/cloakglowing/dropped() +/obj/item/clothing/accessory/poncho/roles/cloak/fluff/cloakglowing/dropped() icon_override = 'icons/vore/custom_onmob_vr.dmi' -/obj/item/clothing/accessory/poncho/fluff/cloakglowing/proc/colorswap(mob/user) +/obj/item/clothing/accessory/poncho/roles/cloak/fluff/cloakglowing/proc/colorswap(mob/user) if(user.canmove && !user.stat) src.is_dark = !src.is_dark if (src.is_dark) @@ -2323,7 +2323,7 @@ Departamental Swimsuits, for general use to_chat(user, "The polychromic plates in your cloak activate, turning it white.") has_suit.update_clothing_icon() -/obj/item/clothing/accessory/poncho/fluff/cloakglowing/verb/color_verb() +/obj/item/clothing/accessory/poncho/roles/cloak/fluff/cloakglowing/verb/color_verb() set name = "Swap color" set category = "Object" set src in usr diff --git a/code/modules/vore/fluffstuff/custom_items_vr.dm b/code/modules/vore/fluffstuff/custom_items_vr.dm index d1f0a3e6f92..5811130768a 100644 --- a/code/modules/vore/fluffstuff/custom_items_vr.dm +++ b/code/modules/vore/fluffstuff/custom_items_vr.dm @@ -1360,3 +1360,16 @@ desc = "A well kept strange ritual knife, There is a small tag with the name 'Astra Ether' on it. They are probably looking for this." icon = 'icons/obj/wizard.dmi' icon_state = "render" + +//AlFalah - Charlotte Graves +/obj/item/weapon/storage/fancy/fluff/charlotte + name = "inconspicuous cigarette case" + desc = "A SkyTron 3000 cigarette case with no additional functions. The buttons and CRT monitor are completely for show and have no functions. Seriously. " + icon_state = "charlotte" + icon = 'icons/vore/custom_items_vr.dmi' + storage_slots = 7 + can_hold = list(/obj/item/clothing/mask/smokable/cigarette, /obj/item/weapon/flame/lighter, /obj/item/trash/cigbutt) + icon_type = "charlotte" + //brand = "\improper Professional 120" + w_class = ITEMSIZE_TINY + starts_with = list(/obj/item/clothing/mask/smokable/cigarette = 7) \ No newline at end of file diff --git a/code/modules/vore/smoleworld/smoleworld_vr.dm b/code/modules/vore/smoleworld/smoleworld_vr.dm index 5e84d7cbd1f..50dbacfe1f3 100644 --- a/code/modules/vore/smoleworld/smoleworld_vr.dm +++ b/code/modules/vore/smoleworld/smoleworld_vr.dm @@ -60,7 +60,7 @@ recipes += new/datum/stack_recipe("smole houses", /obj/structure/smolebuilding/houses, 2, time = 10) recipes += new/datum/stack_recipe("smole business", /obj/structure/smolebuilding/business, 2, time = 10) recipes += new/datum/stack_recipe("smole warehouses", /obj/structure/smolebuilding/warehouses, 2, time = 10) - recipes += new/datum/stack_recipe("smole musem", /obj/structure/smolebuilding/musem, 2, time = 10) + recipes += new/datum/stack_recipe("smole museum", /obj/structure/smolebuilding/museum, 2, time = 10) /datum/material/smolebricks name = "smolebricks" @@ -86,7 +86,7 @@ //smolebrick case to make for easy bricks. /obj/item/weapon/storage/smolebrickcase name = "smolebrick case" - desc = "you feel the power of imagination." + desc = "You feel the power of imagination." icon = 'icons/vore/smoleworld_vr.dmi' icon_state = "smolestorage" throw_speed = 1 @@ -152,10 +152,10 @@ anchored = 1 /obj/structure/smoletrack/roadF - name = "road fourway piece" + name = "road four-way piece" icon = 'icons/vore/smoleworld_vr.dmi' icon_state = "carfourway" - desc = "A fourway road piece." + desc = "A four-way road piece." anchored = 1 //buildings code @@ -279,10 +279,10 @@ icon = 'icons/vore/smoleworld_vr.dmi' icon_state = "smolewarehouses" -/obj/structure/smolebuilding/musem - name = "smole musem" +/obj/structure/smolebuilding/museum + name = "smole museum" icon = 'icons/vore/smoleworld_vr.dmi' - icon_state = "smolemusem" + icon_state = "smolemuseum" // //CAR STUFF < WILL BE MESSED WITH IN A LATER UPDATE COMMENTED OUT FOR NOW ///obj/item/smolecar @@ -357,8 +357,8 @@ drop_sound = 'sound/items/drop/basketball.ogg' /obj/item/weapon/reagent_containers/food/snacks/snackplanet/virgo3b - name = "virgo3bB" - desc = "A sticky jelly jaw breaker in the shape of Virgo3B, it even has a tiny tether!" + name = "Virgo 3B" + desc = "A sticky jelly jaw breaker in the shape of Virgo-3B, it even has a tiny tether!" icon = 'icons/vore/smoleworld_vr.dmi' icon_state = "sp_Virgo3B" bitesize = 3 @@ -379,8 +379,8 @@ drop_sound = 'sound/items/drop/basketball.ogg' /obj/item/weapon/reagent_containers/food/snacks/snackplanet/virgoprime - name = "virgo prime" - desc = "Its a orange jaw breaker in the shape Virgo Prime!" + name = "Virgo Prime" + desc = "It's a orange jaw breaker in the shape of Virgo Prime!" icon = 'icons/vore/smoleworld_vr.dmi' icon_state = "sp_virgoprime" bitesize = 3 @@ -391,7 +391,7 @@ /obj/item/weapon/storage/bagoplanets name = "bag o' planets" - desc = "A cosmic bag of fist sized candy planets." + desc = "A cosmic bag of fist-sized candy planets." icon = 'icons/vore/smoleworld_vr.dmi' icon_state = "sp_storage" w_class = ITEMSIZE_LARGE diff --git a/code/modules/xenobio/items/extracts.dm b/code/modules/xenobio/items/extracts.dm index 159bb0f1516..f810b9f68b8 100644 --- a/code/modules/xenobio/items/extracts.dm +++ b/code/modules/xenobio/items/extracts.dm @@ -39,17 +39,17 @@ else . += "This extract is inert." -/datum/chemical_reaction/slime +/decl/chemical_reaction/instant/slime var/required = null -/datum/chemical_reaction/slime/can_happen(var/datum/reagents/holder) +/decl/chemical_reaction/instant/slime/can_happen(var/datum/reagents/holder) if(holder.my_atom && istype(holder.my_atom, required)) var/obj/item/slime_extract/T = holder.my_atom if(T.uses > 0) return ..() return FALSE -/datum/chemical_reaction/slime/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/slime/on_reaction(var/datum/reagents/holder) var/obj/item/slime_extract/T = holder.my_atom T.uses-- if(T.uses <= 0) @@ -67,7 +67,7 @@ icon_state = "grey slime extract" description_info = "This extract will create a new grey baby slime if injected with phoron, or some new monkey cubes if injected with blood." -/datum/chemical_reaction/slime/grey_new_slime +/decl/chemical_reaction/instant/slime/grey_new_slime name = "Slime Spawn" id = "m_spawn" result = null @@ -75,12 +75,12 @@ result_amount = 1 required = /obj/item/slime_extract/grey -/datum/chemical_reaction/slime/grey_new_slime/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/slime/grey_new_slime/on_reaction(var/datum/reagents/holder) holder.my_atom.visible_message("Infused with phoron, the core begins to quiver and grow, and soon a new baby slime emerges from it!") new /mob/living/simple_mob/slime/xenobio(get_turf(holder.my_atom)) ..() -/datum/chemical_reaction/slime/grey_monkey +/decl/chemical_reaction/instant/slime/grey_monkey name = "Slime Monkey" id = "m_monkey" result = null @@ -88,12 +88,12 @@ result_amount = 1 required = /obj/item/slime_extract/grey -/datum/chemical_reaction/slime/grey_monkey/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/slime/grey_monkey/on_reaction(var/datum/reagents/holder) for(var/i = 1 to 4) new /obj/item/weapon/reagent_containers/food/snacks/monkeycube(get_turf(holder.my_atom)) ..() -/datum/chemical_reaction/slime/grey_slimejelly +/decl/chemical_reaction/instant/slime/grey_slimejelly name = "Slime Jelly" id = "m_jelly" result = "slimejelly" @@ -123,7 +123,7 @@ color = "#666666" strength = 20 -/datum/chemical_reaction/slime/metal_metamorphic +/decl/chemical_reaction/instant/slime/metal_metamorphic name = "Slime Metal" id = "m_metal" required_reagents = list("phoron" = 5) @@ -132,7 +132,7 @@ required = /obj/item/slime_extract/metal -/datum/chemical_reaction/metamorphic +/decl/chemical_reaction/instant/metamorphic result_amount = REAGENTS_PER_SHEET * 2 @@ -145,42 +145,42 @@ // This is kind of a waste since iron is in the chem dispenser but it would be inconsistent if this wasn't here. -/datum/chemical_reaction/metamorphic/iron +/decl/chemical_reaction/instant/metamorphic/iron name = "Morph into Iron" id = "morph_iron" required_reagents = list("metamorphic" = REAGENTS_PER_SHEET, "iron" = REAGENTS_PER_SHEET) result = "iron" -/datum/chemical_reaction/metamorphic/silver +/decl/chemical_reaction/instant/metamorphic/silver name = "Morph into Silver" id = "morph_silver" required_reagents = list("metamorphic" = REAGENTS_PER_SHEET, "silver" = REAGENTS_PER_SHEET) result = "silver" -/datum/chemical_reaction/metamorphic/gold +/decl/chemical_reaction/instant/metamorphic/gold name = "Morph into Gold" id = "morph_gold" required_reagents = list("metamorphic" = REAGENTS_PER_SHEET, "gold" = REAGENTS_PER_SHEET) result = "gold" -/datum/chemical_reaction/metamorphic/platinum +/decl/chemical_reaction/instant/metamorphic/platinum name = "Morph into Platinum" id = "morph_platinum" required_reagents = list("metamorphic" = REAGENTS_PER_SHEET, "platinum" = REAGENTS_PER_SHEET) result = "platinum" -/datum/chemical_reaction/metamorphic/uranium +/decl/chemical_reaction/instant/metamorphic/uranium name = "Morph into Uranium" id = "morph_uranium" required_reagents = list("metamorphic" = REAGENTS_PER_SHEET, "uranium" = REAGENTS_PER_SHEET) result = "uranium" -/datum/chemical_reaction/metamorphic/phoron +/decl/chemical_reaction/instant/metamorphic/phoron name = "Morph into Phoron" id = "morph_phoron" required_reagents = list("metamorphic" = REAGENTS_PER_SHEET, "phoron" = REAGENTS_PER_SHEET) @@ -188,7 +188,7 @@ // Creates 'alloys' which can be finalized with frost oil. -/datum/chemical_reaction/slime/metal_binding +/decl/chemical_reaction/instant/slime/metal_binding name = "Slime Binding" id = "m_binding" required_reagents = list("water" = 5) @@ -215,7 +215,7 @@ prefill = list("binding" = 60) -/datum/chemical_reaction/binding +/decl/chemical_reaction/instant/binding name = "Bind into Steel" id = "bind_steel" result = "steel" @@ -231,7 +231,7 @@ color = "#888888" -/datum/chemical_reaction/binding/plasteel // Two parts 'steel', one part platnium matches the smelter alloy recipe. +/decl/chemical_reaction/instant/binding/plasteel // Two parts 'steel', one part platnium matches the smelter alloy recipe. name = "Bind into Plasteel" id = "bind_plasteel" required_reagents = list("binding" = REAGENTS_PER_SHEET, "steel" = REAGENTS_PER_SHEET * 2, "platinum" = REAGENTS_PER_SHEET) @@ -258,7 +258,7 @@ The extract can also create a slime stability agent when injected with blood, which reduces the odds of newly created slimes mutating into \ a different color when a slime reproduces." -/datum/chemical_reaction/slime/blue_frostoil +/decl/chemical_reaction/instant/slime/blue_frostoil name = "Slime Frost Oil" id = "m_frostoil" result = "frostoil" @@ -267,14 +267,14 @@ required = /obj/item/slime_extract/blue -/datum/chemical_reaction/slime/blue_stability +/decl/chemical_reaction/instant/slime/blue_stability name = "Slime Stability" id = "m_stability" required_reagents = list("blood" = 5) result_amount = 1 required = /obj/item/slime_extract/blue -/datum/chemical_reaction/slime/blue_stability/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/slime/blue_stability/on_reaction(var/datum/reagents/holder) new /obj/item/slimepotion/stabilizer(get_turf(holder.my_atom)) ..() @@ -291,14 +291,14 @@ can extract from a slime specimen." -/datum/chemical_reaction/slime/purple_steroid +/decl/chemical_reaction/instant/slime/purple_steroid name = "Slime Steroid" id = "m_steroid" required_reagents = list("phoron" = 5) result_amount = 1 required = /obj/item/slime_extract/purple -/datum/chemical_reaction/slime/purple_steroid/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/slime/purple_steroid/on_reaction(var/datum/reagents/holder) new /obj/item/slimepotion/steroid(get_turf(holder.my_atom)) ..() @@ -313,14 +313,14 @@ icon_state = "orange slime extract" description_info = "This extract creates a fire when injected with phoron, after a five second delay." -/datum/chemical_reaction/slime/orange_fire +/decl/chemical_reaction/instant/slime/orange_fire name = "Slime Fire" id = "m_fire" required_reagents = list("phoron" = 5) result_amount = 1 required = /obj/item/slime_extract/orange -/datum/chemical_reaction/slime/orange_fire/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/slime/orange_fire/on_reaction(var/datum/reagents/holder) log_and_message_admins("Orange extract reaction (fire) has been activated in [get_area(holder.my_atom)]. Last fingerprints: [holder.my_atom.fingerprintslast]") holder.my_atom.visible_message("\The [src] begins to vibrate violently!") playsound(holder.my_atom, 'sound/effects/phasein.ogg', 75, 1) @@ -350,14 +350,14 @@ description_info = "This extract will create a special 10k capacity power cell that self recharges slowly over time, when injected with phoron. \ When injected with blood, it will create a glob of slime which glows brightly. If injected with water, it will emit a strong EMP, after a five second delay." -/datum/chemical_reaction/slime/yellow_emp +/decl/chemical_reaction/instant/slime/yellow_emp name = "Slime EMP" id = "m_emp" required_reagents = list("water" = 5) result_amount = 1 required = /obj/item/slime_extract/yellow -/datum/chemical_reaction/slime/yellow_emp/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/slime/yellow_emp/on_reaction(var/datum/reagents/holder) log_and_message_admins("Yellow extract reaction (emp) has been activated in [get_area(holder.my_atom)]. Last fingerprints: [holder.my_atom.fingerprintslast]") holder.my_atom.visible_message("\The [src] begins to vibrate violently!") playsound(holder.my_atom, 'sound/effects/phasein.ogg', 75, 1) @@ -368,26 +368,26 @@ ..() -/datum/chemical_reaction/slime/yellow_battery +/decl/chemical_reaction/instant/slime/yellow_battery name = "Slime Cell" id = "m_cell" required_reagents = list("phoron" = 5) result_amount = 1 required = /obj/item/slime_extract/yellow -/datum/chemical_reaction/slime/yellow_battery/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/slime/yellow_battery/on_reaction(var/datum/reagents/holder) new /obj/item/weapon/cell/slime(get_turf(holder.my_atom)) ..() -/datum/chemical_reaction/slime/yellow_flashlight +/decl/chemical_reaction/instant/slime/yellow_flashlight name = "Slime Flashlight" id = "m_flashlight" required_reagents = list("blood" = 5) result_amount = 1 required = /obj/item/slime_extract/yellow -/datum/chemical_reaction/slime/yellow_flashlight/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/slime/yellow_flashlight/on_reaction(var/datum/reagents/holder) new /obj/item/device/flashlight/slime(get_turf(holder.my_atom)) ..() @@ -401,7 +401,7 @@ description_info = "This extract will create 5u liquid gold when injected with phoron." -/datum/chemical_reaction/slime/gold_gold +/decl/chemical_reaction/instant/slime/gold_gold name = "Slime Gold" id = "m_gold" result = "gold" @@ -420,7 +420,7 @@ description_info = "This extract will create 5u liquid silver when injected with phoron." -/datum/chemical_reaction/slime/silver_silver +/decl/chemical_reaction/instant/slime/silver_silver name = "Slime Silver" id = "m_silver" result = "silver" @@ -440,7 +440,7 @@ description_info = "This extract will create 40u liquid phoron when injected with water." -/datum/chemical_reaction/slime/dark_purple_phoron +/decl/chemical_reaction/instant/slime/dark_purple_phoron name = "Slime Phoron" id = "m_phoron_harvest" result = "phoron" @@ -462,7 +462,7 @@ cold-resistant armor like winter coats can protect from this. Note that the user is not immune to the extract's effects." -/datum/chemical_reaction/slime/dark_blue_cold_snap +/decl/chemical_reaction/instant/slime/dark_blue_cold_snap name = "Slime Cold Snap" id = "m_cold_snap" required_reagents = list("phoron" = 5) @@ -470,7 +470,7 @@ required = /obj/item/slime_extract/dark_blue // This iterates over a ZAS zone's contents, so that things seperated in other zones aren't subjected to the temperature drop. -/datum/chemical_reaction/slime/dark_blue_cold_snap/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/slime/dark_blue_cold_snap/on_reaction(var/datum/reagents/holder) var/turf/simulated/T = get_turf(holder.my_atom) if(!T) // Nullspace lacks zones. return @@ -544,14 +544,14 @@ out of control." -/datum/chemical_reaction/slime/red_enrage +/decl/chemical_reaction/instant/slime/red_enrage name = "Slime Enrage" id = "m_enrage" required_reagents = list("blood" = 5) result_amount = 1 required = /obj/item/slime_extract/red -/datum/chemical_reaction/slime/red_enrage/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/slime/red_enrage/on_reaction(var/datum/reagents/holder) for(var/mob/living/simple_mob/slime/S in view(get_turf(holder.my_atom))) if(S.stat) continue @@ -580,14 +580,14 @@ -/datum/chemical_reaction/slime/red_mutation +/decl/chemical_reaction/instant/slime/red_mutation name = "Slime Mutation" id = "m_mutation" required_reagents = list("phoron" = 5) result_amount = 1 required = /obj/item/slime_extract/red -/datum/chemical_reaction/slime/red_mutation/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/slime/red_mutation/on_reaction(var/datum/reagents/holder) new /obj/item/slimepotion/mutator(get_turf(holder.my_atom)) ..() @@ -600,7 +600,7 @@ icon_state = "green slime extract" description_info = "This extract will create 5u of liquid uranium when injected with phoron." -/datum/chemical_reaction/slime/green_uranium +/decl/chemical_reaction/instant/slime/green_uranium name = "Slime Uranium" id = "m_uranium" result = "uranium" @@ -620,7 +620,7 @@ with phoron. When injected with water, it will create an organ-mending agent. The slime medications have a very low threshold for overdosage, however." -/datum/chemical_reaction/slime/pink_clotting +/decl/chemical_reaction/instant/slime/pink_clotting name = "Slime Clotting Med" id = "m_clotting" result = "slime_bleed_fixer" @@ -629,7 +629,7 @@ required = /obj/item/slime_extract/pink -/datum/chemical_reaction/slime/pink_bone_fix +/decl/chemical_reaction/instant/slime/pink_bone_fix name = "Slime Bone Med" id = "m_bone_fixer" result = "slime_bone_fixer" @@ -638,7 +638,7 @@ required = /obj/item/slime_extract/pink -/datum/chemical_reaction/slime/pink_organ_fix +/decl/chemical_reaction/instant/slime/pink_organ_fix name = "Slime Organ Med" id = "m_organ_fixer" result = "slime_organ_fixer" @@ -680,7 +680,7 @@ increase the power of the explosion instead of allowing for multiple explosions." -/datum/chemical_reaction/slime/oil_griff +/decl/chemical_reaction/instant/slime/oil_griff name = "Slime Explosion" id = "m_boom" required_reagents = list("blood" = 5) @@ -688,7 +688,7 @@ required = /obj/item/slime_extract/oil -/datum/chemical_reaction/slime/oil_griff/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/slime/oil_griff/on_reaction(var/datum/reagents/holder) ..() var/obj/item/slime_extract/E = holder.my_atom var/power = 1 @@ -718,26 +718,26 @@ short ranged, random teleporting. When injected with phoron, it creates one 'greater' slime crystal, which allows for a one time precise teleport to \ a specific area." -/datum/chemical_reaction/slime/bluespace_lesser +/decl/chemical_reaction/instant/slime/bluespace_lesser name = "Slime Lesser Tele" id = "m_tele_lesser" required_reagents = list("water" = 5) result_amount = 1 required = /obj/item/slime_extract/bluespace -/datum/chemical_reaction/slime/bluespace_lesser/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/slime/bluespace_lesser/on_reaction(var/datum/reagents/holder) for(var/i = 1 to 5) new /obj/item/slime_crystal(get_turf(holder.my_atom)) ..() -/datum/chemical_reaction/slime/bluespace_greater +/decl/chemical_reaction/instant/slime/bluespace_greater name = "Slime Greater Tele" id = "m_tele_lesser" required_reagents = list("phoron" = 5) result_amount = 1 required = /obj/item/slime_extract/bluespace -/datum/chemical_reaction/slime/bluespace_greater/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/slime/bluespace_greater/on_reaction(var/datum/reagents/holder) new /obj/item/weapon/disposable_teleporter/slime(get_turf(holder.my_atom)) ..() @@ -752,14 +752,14 @@ 'charges' before it goes inert." -/datum/chemical_reaction/slime/cerulean_enhancer +/decl/chemical_reaction/instant/slime/cerulean_enhancer name = "Slime Enhancer" id = "m_enhancer" required_reagents = list("phoron" = 5) result_amount = 1 required = /obj/item/slime_extract/cerulean -/datum/chemical_reaction/slime/cerulean_enhancer/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/slime/cerulean_enhancer/on_reaction(var/datum/reagents/holder) new /obj/item/slimepotion/enhancer(get_turf(holder.my_atom)) ..() @@ -774,26 +774,26 @@ injected with water, it will create a very delicious and filling product." -/datum/chemical_reaction/slime/amber_slimefood +/decl/chemical_reaction/instant/slime/amber_slimefood name = "Slime Feeding" id = "m_slime_food" required_reagents = list("phoron" = 5) result_amount = 1 required = /obj/item/slime_extract/amber -/datum/chemical_reaction/slime/amber_slimefood/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/slime/amber_slimefood/on_reaction(var/datum/reagents/holder) new /obj/item/slimepotion/feeding(get_turf(holder.my_atom)) ..() -/datum/chemical_reaction/slime/amber_peoplefood +/decl/chemical_reaction/instant/slime/amber_peoplefood name = "Slime Food" id = "m_people_food" required_reagents = list("water" = 5) result_amount = 1 required = /obj/item/slime_extract/amber -/datum/chemical_reaction/slime/amber_peoplefood/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/slime/amber_peoplefood/on_reaction(var/datum/reagents/holder) new /obj/item/weapon/reagent_containers/food/snacks/slime(get_turf(holder.my_atom)) ..() @@ -809,14 +809,14 @@ description_info = "This extract will create one 'slime cube' when injected with phoron. The slime cube is needed to create a Promethean." -/datum/chemical_reaction/slime/sapphire_promethean +/decl/chemical_reaction/instant/slime/sapphire_promethean name = "Slime Promethean" id = "m_promethean" required_reagents = list("phoron" = 5) result_amount = 1 required = /obj/item/slime_extract/sapphire -/datum/chemical_reaction/slime/sapphire_promethean/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/slime/sapphire_promethean/on_reaction(var/datum/reagents/holder) new /obj/item/slime_cube(get_turf(holder.my_atom)) ..() @@ -830,14 +830,14 @@ description_info = "This extract will cause all entities close to the extract to become stronger for ten minutes, when injected with phoron. \ When injected with blood, makes a slime loyalty agent which will make the slime fight other dangerous entities but not station crew." -/datum/chemical_reaction/slime/ruby_swole +/decl/chemical_reaction/instant/slime/ruby_swole name = "Slime Strength" id = "m_strength" required_reagents = list("phoron" = 5) result_amount = 1 required = /obj/item/slime_extract/ruby -/datum/chemical_reaction/slime/ruby_swole/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/slime/ruby_swole/on_reaction(var/datum/reagents/holder) for(var/mob/living/L in range(1, holder.my_atom)) L.add_modifier(/datum/modifier/slime_strength, 10 MINUTES, src) ..() @@ -858,14 +858,14 @@ incoming_damage_percent = 0.75 -/datum/chemical_reaction/slime/ruby_loyalty +/decl/chemical_reaction/instant/slime/ruby_loyalty name = "Slime Loyalty" id = "m_strength" required_reagents = list("blood" = 5) result_amount = 1 required = /obj/item/slime_extract/ruby -/datum/chemical_reaction/slime/ruby_loyalty/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/slime/ruby_loyalty/on_reaction(var/datum/reagents/holder) new /obj/item/slimepotion/loyalty(get_turf(holder.my_atom)) ..() @@ -879,14 +879,14 @@ icon_state = "emerald slime extract" description_info = "This extract will cause all entities close to the extract to become more agile for ten minutes, when injected with phoron." -/datum/chemical_reaction/slime/emerald_fast +/decl/chemical_reaction/instant/slime/emerald_fast name = "Slime Agility" id = "m_agility" required_reagents = list("phoron" = 5) result_amount = 1 required = /obj/item/slime_extract/emerald -/datum/chemical_reaction/slime/emerald_fast/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/slime/emerald_fast/on_reaction(var/datum/reagents/holder) for(var/mob/living/L in range(1, holder.my_atom)) L.add_modifier(/datum/modifier/slime_agility, 10 MINUTES, src) ..() @@ -916,26 +916,26 @@ When injected with phoron, it instead creates a slime friendship agent, which makes the slime consider the user their ally. The agent \ might be useful on other specimens as well." -/datum/chemical_reaction/slime/light_pink_docility +/decl/chemical_reaction/instant/slime/light_pink_docility name = "Slime Docility" id = "m_docile" required_reagents = list("water" = 5) result_amount = 1 required = /obj/item/slime_extract/light_pink -/datum/chemical_reaction/slime/light_pink_docility/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/slime/light_pink_docility/on_reaction(var/datum/reagents/holder) new /obj/item/slimepotion/docility(get_turf(holder.my_atom)) ..() -/datum/chemical_reaction/slime/light_pink_friendship +/decl/chemical_reaction/instant/slime/light_pink_friendship name = "Slime Friendship" id = "m_friendship" required_reagents = list("phoron" = 5) result_amount = 1 required = /obj/item/slime_extract/light_pink -/datum/chemical_reaction/slime/light_pink_friendship/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/slime/light_pink_friendship/on_reaction(var/datum/reagents/holder) new /obj/item/slimepotion/friendship(get_turf(holder.my_atom)) ..() @@ -952,7 +952,7 @@ which makes slimes stop attacking other slime colors." -/datum/chemical_reaction/slime/rainbow_random_slime +/decl/chemical_reaction/instant/slime/rainbow_random_slime name = "Slime Random Slime" id = "m_rng_slime" required_reagents = list("phoron" = 5) @@ -960,7 +960,7 @@ required = /obj/item/slime_extract/rainbow -/datum/chemical_reaction/slime/rainbow_random_slime/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/slime/rainbow_random_slime/on_reaction(var/datum/reagents/holder) var/mob/living/simple_mob/slime/xenobio/S var/list/slime_types = typesof(/mob/living/simple_mob/slime/xenobio) @@ -976,14 +976,14 @@ new S(get_turf(holder.my_atom)) ..() -/datum/chemical_reaction/slime/rainbow_unity +/decl/chemical_reaction/instant/slime/rainbow_unity name = "Slime Unity" id = "m_unity" required_reagents = list("water" = 5) result_amount = 1 required = /obj/item/slime_extract/rainbow -/datum/chemical_reaction/slime/rainbow_unity/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/slime/rainbow_unity/on_reaction(var/datum/reagents/holder) new /obj/item/slimepotion/unity(get_turf(holder.my_atom)) ..() diff --git a/config/alienwhitelist.txt b/config/alienwhitelist.txt index ccee935d168..8444ddc1f86 100644 --- a/config/alienwhitelist.txt +++ b/config/alienwhitelist.txt @@ -19,6 +19,7 @@ chargae - Protean chillyfang - Black-Eyed Shadekin crossexonar - Protean detectivegoogle - Protean +digitalsquirrel95 - Protean draycu - Vox flaktual - Vox flurriee - Protean @@ -46,6 +47,7 @@ mrsebbi - Xenochimera natje - Xenochimera nerdass - Protean newyorks - Protean +oneofmanynames385 - Protean ontejbjoav - Diona oreganovulgaris - Xenochimera owwy - Black-Eyed Shadekin @@ -67,6 +69,7 @@ ryumi - Xenochimera scoutisafolflol - Xenochimera seiga - Vox sepulchre - Vox +stobarico - Protean sharplight - Protean silvertalismen - Diona silvertalismen - Vox diff --git a/config/docker/README.md b/config/docker/README.md new file mode 100644 index 00000000000..3c1b9b34820 --- /dev/null +++ b/config/docker/README.md @@ -0,0 +1,43 @@ +## How to set-up the Docker database + + +First, open `config/docker/mysql.env.example`, open in notepad or N++, change all the values to something else ~~or don't if you are lazy~~ for security sake. + +Then proceed to save the changed version to `mysql.env` and save it in the same directory as the `mysql.env.example` file. + +In order to get docker to use the database, it's suggested to change the `config/dbconfig.txt` to include the values in `mysql.env` file, to do this, use the hostname `db` as host! + +### Example for `config/dbconfig.txt`: + +The default database name is `tgstation` by default. Unless you change the SQL schemas, this cannot be changed. + +Keep note of the values, `*LOGIN` and `*PASSWORD` + +``` +# MySQL Connection Configuration + +# Server the MySQL database can be found at +# Examples: localhost, 200.135.5.43, www.mysqldb.com, etc. +ADDRESS db + +# MySQL server port (default is 3306) +PORT 3306 + +# Database the population, death, karma, etc. tables may be found in +DATABASE tgstation + +# Username/Login used to access the database +LOGIN sillyusername + +# Password used to access the database +PASSWORD somekindofpassword + +# The following information is for feedback tracking via the blackbox server +FEEDBACK_DATABASE tgstation +FEEDBACK_LOGIN sillyusernane +FEEDBACK_PASSWORD somekindofpassword + +# Track population and death statistics +# Comment this out to disable +#ENABLE_STAT_TRACKING +``` diff --git a/config/docker/mysql.env.example b/config/docker/mysql.env.example new file mode 100644 index 00000000000..73b37b08fd0 --- /dev/null +++ b/config/docker/mysql.env.example @@ -0,0 +1,6 @@ +# MySQL database root password +MYSQL_ROOT_PASSWORD=SUPERSEKRETOMYGOD +# MySQL login username +MYSQL_USERNAME=sillyusername +# MySQL login password +MYSQL_PASSWORD=somekindofpassword diff --git a/config/example/config.txt b/config/example/config.txt index dd07f7b73d5..735fe805e9e 100644 --- a/config/example/config.txt +++ b/config/example/config.txt @@ -555,3 +555,7 @@ ALLOW_URL_LINKS # Control which submaps are loaded for the Dynamic Engine system ENGINE_MAP Supermatter Engine,Edison's Bane + +# Controls how strictly the species whitelists on loadout entries are enforced +# Possible values: 0 (Off), 1 (Lax, user must be whitelisted for the species), 2 (Strict, user must be the species) +LOADOUT_WHITELIST 1 \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 00000000000..b22b1c4ac0c --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,45 @@ +version: '3' + +services: + # Virgo DM server + dreammaker: + image: vorestation:latest + restart: unless-stopped + build: + context: . + dockerfile: Dockerfile + ports: + - "2303:2303" + depends_on: + - db + volumes: + - ./config/:/vorestation/config + - gamedata:/vorestation/data + # MariaDB/MySQL database: game + # (if you don't really need this, feel free to remove this section.) + db: + image: mariadb + restart: unless-stopped + env_file: + - ./config/docker/mysql.env + volumes: + - ./SQL/tgstation_schema.sql:/docker-entrypoint-initdb.d/tgstation_schema.sql:ro + - ./SQL/feedback_schema.sql:/docker-entrypoint-initdb.d/feedback_schema.sql:ro + - database:/var/lib/mysql + # Adminer, for managing the DB, commented out by default but uncomment if you need it I guess. + #adminer: + # image: wodby/adminer + # depends_on: + # - db + # environment: + # ADMINER_DEFAULT_DB_DRIVER: mysql + # ADMINER_DEFAULT_DB_HOST: db + # ADMINER_DEFAULT_DB_NAME: tgstation + # ADMINER_DESIGN: nette + # ADMINER_PLUGINS: tables-filter tinymce + # ports: + # - 8080:9000 + +volumes: + gamedata: + database: diff --git a/icons/_nanomaps/tether_nanomap_z3.png b/icons/_nanomaps/tether_nanomap_z3.png index 8cc7f4d9f15..cc52e6c7529 100644 Binary files a/icons/_nanomaps/tether_nanomap_z3.png and b/icons/_nanomaps/tether_nanomap_z3.png differ diff --git a/icons/effects/effects_vr.dmi b/icons/effects/effects_vr.dmi index 02569f6157d..f9824436dd3 100644 Binary files a/icons/effects/effects_vr.dmi and b/icons/effects/effects_vr.dmi differ diff --git a/icons/mob/animal.dmi b/icons/mob/animal.dmi index a20911d4355..b0130e58df5 100644 Binary files a/icons/mob/animal.dmi and b/icons/mob/animal.dmi differ diff --git a/icons/mob/corgi_back.dmi b/icons/mob/corgi_back.dmi index 81626df0333..27de68f79c0 100644 Binary files a/icons/mob/corgi_back.dmi and b/icons/mob/corgi_back.dmi differ diff --git a/icons/mob/corgi_head.dmi b/icons/mob/corgi_head.dmi index ca62243e79b..d8be15b3bc5 100644 Binary files a/icons/mob/corgi_head.dmi and b/icons/mob/corgi_head.dmi differ diff --git a/icons/mob/items/lefthand_guns_vr.dmi b/icons/mob/items/lefthand_guns_vr.dmi index 76ad8ebf311..0d8acb4fbba 100644 Binary files a/icons/mob/items/lefthand_guns_vr.dmi and b/icons/mob/items/lefthand_guns_vr.dmi differ diff --git a/icons/mob/items/lefthand_material.dmi b/icons/mob/items/lefthand_material.dmi index 7fbcc1131ff..dec3ab84ea0 100644 Binary files a/icons/mob/items/lefthand_material.dmi and b/icons/mob/items/lefthand_material.dmi differ diff --git a/icons/mob/items/lefthand_melee_vr.dmi b/icons/mob/items/lefthand_melee_vr.dmi index 69ff6b66108..ad144c53b44 100644 Binary files a/icons/mob/items/lefthand_melee_vr.dmi and b/icons/mob/items/lefthand_melee_vr.dmi differ diff --git a/icons/mob/items/righthand_guns_vr.dmi b/icons/mob/items/righthand_guns_vr.dmi index 42d935f7608..73ee95c0a3a 100644 Binary files a/icons/mob/items/righthand_guns_vr.dmi and b/icons/mob/items/righthand_guns_vr.dmi differ diff --git a/icons/mob/items/righthand_material.dmi b/icons/mob/items/righthand_material.dmi index ac51aa86f14..d65181cc6a6 100644 Binary files a/icons/mob/items/righthand_material.dmi and b/icons/mob/items/righthand_material.dmi differ diff --git a/icons/mob/items/righthand_melee_vr.dmi b/icons/mob/items/righthand_melee_vr.dmi index 655dbc371d6..3d5ca587dbd 100644 Binary files a/icons/mob/items/righthand_melee_vr.dmi and b/icons/mob/items/righthand_melee_vr.dmi differ diff --git a/icons/mob/screen/holo.dmi b/icons/mob/screen/holo.dmi index 434da95f7d8..a0fff5d7819 100644 Binary files a/icons/mob/screen/holo.dmi and b/icons/mob/screen/holo.dmi differ diff --git a/icons/mob/screen/midnight.dmi b/icons/mob/screen/midnight.dmi index 842554a84bb..b1f37cb2239 100644 Binary files a/icons/mob/screen/midnight.dmi and b/icons/mob/screen/midnight.dmi differ diff --git a/icons/mob/screen_full_vore.dmi b/icons/mob/screen_full_vore.dmi index 632f413f597..4e5b3a70fdd 100644 Binary files a/icons/mob/screen_full_vore.dmi and b/icons/mob/screen_full_vore.dmi differ diff --git a/icons/mob/species/teshari/head.dmi b/icons/mob/species/teshari/head.dmi index 51eff217bb7..038fb9cc3dd 100644 Binary files a/icons/mob/species/teshari/head.dmi and b/icons/mob/species/teshari/head.dmi differ diff --git a/icons/mob/species/teshari/suit.dmi b/icons/mob/species/teshari/suit.dmi index 9f6a652c4a5..714b0408a53 100644 Binary files a/icons/mob/species/teshari/suit.dmi and b/icons/mob/species/teshari/suit.dmi differ diff --git a/icons/mob/species/teshari/ties.dmi b/icons/mob/species/teshari/ties.dmi index fb49fe444fd..467d0ffa35c 100644 Binary files a/icons/mob/species/teshari/ties.dmi and b/icons/mob/species/teshari/ties.dmi differ diff --git a/icons/mob/ties_vr.dmi b/icons/mob/ties_vr.dmi index 7e06a43e112..2b45005380e 100644 Binary files a/icons/mob/ties_vr.dmi and b/icons/mob/ties_vr.dmi differ diff --git a/icons/mob/vore/taurs_vr.dmi b/icons/mob/vore/taurs_vr.dmi index 87f0b32cc2f..54e865150b9 100644 Binary files a/icons/mob/vore/taurs_vr.dmi and b/icons/mob/vore/taurs_vr.dmi differ diff --git a/icons/mob/vore64x64.dmi b/icons/mob/vore64x64.dmi index e349085e633..41394a32c8f 100644 Binary files a/icons/mob/vore64x64.dmi and b/icons/mob/vore64x64.dmi differ diff --git a/icons/obj/clothing/species/teshari/hats.dmi b/icons/obj/clothing/species/teshari/hats.dmi index c069f66f136..2d7877c0c3e 100644 Binary files a/icons/obj/clothing/species/teshari/hats.dmi and b/icons/obj/clothing/species/teshari/hats.dmi differ diff --git a/icons/obj/clothing/species/teshari/suits.dmi b/icons/obj/clothing/species/teshari/suits.dmi index 6679ceb22c8..820649befa7 100644 Binary files a/icons/obj/clothing/species/teshari/suits.dmi and b/icons/obj/clothing/species/teshari/suits.dmi differ diff --git a/icons/obj/clothing/ties_vr.dmi b/icons/obj/clothing/ties_vr.dmi index 9df871aedc4..537da3aa5fe 100644 Binary files a/icons/obj/clothing/ties_vr.dmi and b/icons/obj/clothing/ties_vr.dmi differ diff --git a/icons/obj/device_vr.dmi b/icons/obj/device_vr.dmi index 1fa6835a94a..200443e0463 100644 Binary files a/icons/obj/device_vr.dmi and b/icons/obj/device_vr.dmi differ diff --git a/icons/obj/drinks.dmi b/icons/obj/drinks.dmi index 250c191c730..6a05cf1443c 100644 Binary files a/icons/obj/drinks.dmi and b/icons/obj/drinks.dmi differ diff --git a/icons/obj/drinks_vr.dmi b/icons/obj/drinks_vr.dmi index 280bf84cbd1..f1a34845330 100644 Binary files a/icons/obj/drinks_vr.dmi and b/icons/obj/drinks_vr.dmi differ diff --git a/icons/obj/gun_vr.dmi b/icons/obj/gun_vr.dmi index 34c2a2dc6d5..a794ff88a35 100644 Binary files a/icons/obj/gun_vr.dmi and b/icons/obj/gun_vr.dmi differ diff --git a/icons/obj/storage_vr.dmi b/icons/obj/storage_vr.dmi index 674f7e0d9ce..07d87323ad8 100644 Binary files a/icons/obj/storage_vr.dmi and b/icons/obj/storage_vr.dmi differ diff --git a/icons/obj/toy_vr.dmi b/icons/obj/toy_vr.dmi index 2e6c3af857c..3ad106945b6 100644 Binary files a/icons/obj/toy_vr.dmi and b/icons/obj/toy_vr.dmi differ diff --git a/icons/obj/vending_vr.dmi b/icons/obj/vending_vr.dmi index 64c2ad0f5cb..94e2ba1fb67 100644 Binary files a/icons/obj/vending_vr.dmi and b/icons/obj/vending_vr.dmi differ diff --git a/icons/obj/weapons_vr.dmi b/icons/obj/weapons_vr.dmi index aa67af73261..26cb3ecd2f6 100644 Binary files a/icons/obj/weapons_vr.dmi and b/icons/obj/weapons_vr.dmi differ diff --git a/icons/vore/custom_items_vr.dmi b/icons/vore/custom_items_vr.dmi index 10580ec71f0..b8fe78c7591 100644 Binary files a/icons/vore/custom_items_vr.dmi and b/icons/vore/custom_items_vr.dmi differ diff --git a/icons/vore/smoleworld_vr.dmi b/icons/vore/smoleworld_vr.dmi index 206c0cef32c..035a6d6ce57 100644 Binary files a/icons/vore/smoleworld_vr.dmi and b/icons/vore/smoleworld_vr.dmi differ diff --git a/interface/skin.dmf b/interface/skin.dmf index 595a980bf15..4887895627f 100644 --- a/interface/skin.dmf +++ b/interface/skin.dmf @@ -603,6 +603,9 @@ macro "hotkeymode" elem name = "U" command = "Rest" + elem + name = "B" + command = "Resist" elem name = "NUMPAD1" command = "body-r-leg" diff --git a/maps/expedition_vr/beach/beach.dmm b/maps/expedition_vr/beach/beach.dmm index 3efcfc0c104..c60de785482 100644 --- a/maps/expedition_vr/beach/beach.dmm +++ b/maps/expedition_vr/beach/beach.dmm @@ -1973,7 +1973,7 @@ /turf/simulated/floor/tiled/asteroid_steel, /area/tether_away/beach/resort/lockermed) "Tg" = ( -/mob/living/simple_mob/animal/passive/fish/solarfish, +/mob/living/simple_mob/animal/passive/fish/icebass, /turf/simulated/floor/water/ocean, /area/tether_away/beach/cavebase) "Tp" = ( diff --git a/maps/offmap_vr/om_ships/aro2.dmm b/maps/offmap_vr/om_ships/aro2.dmm index 81eccda8c1f..b6a955a65c9 100644 --- a/maps/offmap_vr/om_ships/aro2.dmm +++ b/maps/offmap_vr/om_ships/aro2.dmm @@ -130,7 +130,7 @@ /area/aro2/room1) "aI" = ( /obj/effect/floor_decal/industrial/warning/full, -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "aroship" }, /obj/structure/cable/cyan{ @@ -235,7 +235,7 @@ /area/aro2/room1) "bd" = ( /obj/effect/floor_decal/industrial/warning/full, -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "aroship" }, /obj/structure/cable/cyan{ @@ -703,7 +703,7 @@ /area/aro2/boatdeck) "el" = ( /obj/effect/floor_decal/industrial/warning/full, -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "aroship" }, /obj/structure/cable/cyan, @@ -3040,7 +3040,7 @@ /area/aro2/starboardbay) "Ed" = ( /obj/effect/floor_decal/industrial/warning/full, -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "aroship" }, /obj/structure/cable/cyan{ @@ -3392,7 +3392,7 @@ /area/shuttle/aroboat2) "HF" = ( /obj/effect/floor_decal/industrial/warning/full, -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "aroship" }, /obj/structure/cable/cyan{ @@ -3546,7 +3546,7 @@ /area/aro2/portbay) "Jg" = ( /obj/effect/floor_decal/industrial/warning/full, -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "aroship" }, /obj/structure/cable/cyan{ @@ -3955,7 +3955,7 @@ /area/aro2/boatdeck) "MR" = ( /obj/effect/floor_decal/industrial/warning/full, -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "aroship" }, /obj/structure/cable/cyan{ @@ -4072,7 +4072,7 @@ /area/aro2/cockpit) "OK" = ( /obj/effect/floor_decal/industrial/warning/full, -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "aroship" }, /obj/structure/cable/cyan, @@ -4186,7 +4186,7 @@ /area/aro2/portbay) "PF" = ( /obj/effect/floor_decal/industrial/warning/full, -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "aroship" }, /obj/structure/cable/cyan{ @@ -4795,7 +4795,7 @@ /area/aro2/boatdeck) "Wg" = ( /obj/effect/floor_decal/industrial/warning/full, -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "aroship" }, /obj/structure/cable/cyan{ diff --git a/maps/offmap_vr/om_ships/bearcat.dmm b/maps/offmap_vr/om_ships/bearcat.dmm index 9aa7bdee334..744da6a92bf 100644 --- a/maps/offmap_vr/om_ships/bearcat.dmm +++ b/maps/offmap_vr/om_ships/bearcat.dmm @@ -3572,7 +3572,7 @@ /turf/simulated/floor/plating, /area/shuttle/bearcat/maintenance_engine_pod_starboard) "sg" = ( -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "bearcat_pd" }, /turf/simulated/floor/airless, @@ -3632,7 +3632,7 @@ /turf/simulated/shuttle/plating/airless/carry, /area/shuttle/bearcat/maintenance_engine_pod_starboard) "Di" = ( -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "bearcat_pd" }, /turf/simulated/floor/airless, diff --git a/maps/offmap_vr/om_ships/cruiser.dmm b/maps/offmap_vr/om_ships/cruiser.dmm index e22624e8344..63d53696698 100644 --- a/maps/offmap_vr/om_ships/cruiser.dmm +++ b/maps/offmap_vr/om_ships/cruiser.dmm @@ -9355,7 +9355,7 @@ /turf/simulated/floor/wood, /area/mothership/breakroom) "uh" = ( -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "warship_pd" }, /turf/simulated/floor/reinforced/airless{ diff --git a/maps/offmap_vr/om_ships/itglight.dmm b/maps/offmap_vr/om_ships/itglight.dmm index b64bf5745d4..4444727be29 100644 --- a/maps/offmap_vr/om_ships/itglight.dmm +++ b/maps/offmap_vr/om_ships/itglight.dmm @@ -48,7 +48,7 @@ d2 = 4; icon_state = "0-4" }, -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "dauntless_pd" }, /turf/simulated/floor/airless, @@ -328,7 +328,7 @@ /turf/simulated/floor/airless, /area/itglight/captain) "bq" = ( -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "dauntless_pd" }, /obj/structure/cable/pink{ @@ -2093,7 +2093,7 @@ /turf/simulated/floor/tiled/eris/steel/gray_platform, /area/itglight/starboardhighsec) "mo" = ( -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "dauntless_pd" }, /obj/structure/cable/pink{ @@ -6009,7 +6009,7 @@ /turf/simulated/floor/tiled/eris/steel/brown_platform, /area/itglight/shuttlebay) "Kv" = ( -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "dauntless_pd" }, /obj/structure/cable/pink{ @@ -7824,7 +7824,7 @@ /turf/space, /area/itglight/starboardengi) "We" = ( -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "dauntless_pd" }, /obj/structure/cable/pink{ @@ -8115,7 +8115,7 @@ /turf/simulated/floor/carpet/turcarpet, /area/itglight/crew1) "XO" = ( -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "dauntless_pd" }, /obj/structure/cable/pink{ diff --git a/maps/offmap_vr/om_ships/mercship.dmm b/maps/offmap_vr/om_ships/mercship.dmm index 320159cc1a7..81864bde356 100644 --- a/maps/offmap_vr/om_ships/mercship.dmm +++ b/maps/offmap_vr/om_ships/mercship.dmm @@ -2268,7 +2268,7 @@ /turf/simulated/floor/tiled/dark, /area/ship/mercenary/hall1) "dY" = ( -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "merc_pd" }, /obj/effect/decal/warning_stripes, @@ -2902,7 +2902,7 @@ /turf/simulated/floor/plating, /area/ship/mercenary/engine) "fj" = ( -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "merc_pd" }, /obj/effect/decal/warning_stripes, @@ -3530,28 +3530,28 @@ /turf/simulated/floor/tiled/dark, /area/ship/mercenary/engineering) "gk" = ( -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "merc_pd" }, /obj/effect/decal/warning_stripes, /turf/simulated/floor/plating/external, /area/ship/mercenary/bridge) "gl" = ( -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "merc_pd" }, /obj/effect/decal/warning_stripes, /turf/simulated/floor/plating/external, /area/ship/mercenary/engineeringcntrl) "gm" = ( -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "merc_pd" }, /obj/effect/decal/warning_stripes, /turf/simulated/floor/plating/external, /area/ship/mercenary/armoury) "gn" = ( -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "merc_pd" }, /obj/effect/decal/warning_stripes, diff --git a/maps/offmap_vr/om_ships/salamander.dmm b/maps/offmap_vr/om_ships/salamander.dmm index 6fb59647e80..933058d6c67 100644 --- a/maps/offmap_vr/om_ships/salamander.dmm +++ b/maps/offmap_vr/om_ships/salamander.dmm @@ -36,7 +36,7 @@ /turf/simulated/floor/tiled/techmaint, /area/shuttle/salamander) "bk" = ( -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "salamander_pd" }, /turf/simulated/floor/plating, @@ -1256,7 +1256,7 @@ /turf/simulated/floor/tiled/techmaint, /area/shuttle/salamander_engineering) "tA" = ( -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "salamander_pd" }, /turf/simulated/floor/plating, diff --git a/maps/offmap_vr/om_ships/salamander_wreck.dmm b/maps/offmap_vr/om_ships/salamander_wreck.dmm index a1960322ac1..d1b9c38c848 100644 --- a/maps/offmap_vr/om_ships/salamander_wreck.dmm +++ b/maps/offmap_vr/om_ships/salamander_wreck.dmm @@ -35,7 +35,7 @@ /turf/simulated/floor/tiled/techmaint, /area/shuttle/salamander_wreck) "bk" = ( -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "salamander_wreck_pd" }, /turf/simulated/floor/airless, @@ -1275,7 +1275,7 @@ /turf/simulated/floor/tiled/techmaint/airless, /area/shuttle/salamander_wreck_engineering) "tA" = ( -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "salamander_wreck_pd" }, /turf/simulated/floor/airless, diff --git a/maps/offmap_vr/om_ships/shelter_6.dm b/maps/offmap_vr/om_ships/shelter_6.dm index f65d2491dd0..d6f5f780635 100644 --- a/maps/offmap_vr/om_ships/shelter_6.dm +++ b/maps/offmap_vr/om_ships/shelter_6.dm @@ -48,6 +48,6 @@ [i]Transponder[/i]: Transmitting (MIL), NanoTrasen [b]Notice[/b]: Experimental vessel"} color = "#8800ff" //Indigo - vessel_mass = 5000 + vessel_mass = 3000 vessel_size = SHIP_SIZE_SMALL shuttle = "NDV Tabiranth" diff --git a/maps/offmap_vr/om_ships/shelter_6.dmm b/maps/offmap_vr/om_ships/shelter_6.dmm index e424a56984b..5918d23ad43 100644 --- a/maps/offmap_vr/om_ships/shelter_6.dmm +++ b/maps/offmap_vr/om_ships/shelter_6.dmm @@ -6,7 +6,7 @@ }, /area/shuttle/tabiranth) "ab" = ( -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "tabiranth_pd" }, /turf/simulated/floor/reinforced/airless{ @@ -347,12 +347,18 @@ /turf/simulated/floor/reinforced, /area/shuttle/tabiranth) "ah" = ( -/obj/structure/fans/hardlight, +/obj/structure/fans/hardlight{ + explosion_resistance = 100 + }, /obj/machinery/door/blast/regular{ destroy_hits = 1000; + explosion_resistance = 200; id = "tabi-hangar1" }, -/turf/simulated/floor/tiled/steel_ridged, +/obj/effect/floor_decal/industrial/danger/full, +/turf/simulated/floor/reinforced{ + explosion_resistance = 200 + }, /area/shuttle/tabiranth) "ai" = ( /obj/effect/floor_decal/industrial/hatch/yellow, @@ -502,189 +508,28 @@ /turf/simulated/floor/reinforced, /area/shuttle/tabiranth) "ay" = ( -/obj/machinery/smartfridge/survival_pod, -/obj/item/clothing/under/ert, -/obj/item/clothing/under/ert, -/obj/item/clothing/under/ert, -/obj/item/clothing/under/ert, -/obj/item/clothing/under/ert, -/obj/item/clothing/under/ert, -/obj/item/weapon/storage/box/survival/comp{ - starts_with = list(/obj/item/weapon/tool/prybar/red,/obj/item/clothing/glasses/goggles,/obj/item/weapon/reagent_containers/hypospray/autoinjector,/obj/item/stack/medical/bruise_pack,/obj/item/device/flashlight/glowstick,/obj/item/weapon/reagent_containers/food/snacks/candy/proteinbar,/obj/item/clothing/mask/breath,/obj/item/weapon/tank/emergency/oxygen/engi) +/obj/structure/fans/hardlight{ + explosion_resistance = 100 }, -/obj/item/weapon/storage/box/survival/comp{ - starts_with = list(/obj/item/weapon/tool/prybar/red,/obj/item/clothing/glasses/goggles,/obj/item/weapon/reagent_containers/hypospray/autoinjector,/obj/item/stack/medical/bruise_pack,/obj/item/device/flashlight/glowstick,/obj/item/weapon/reagent_containers/food/snacks/candy/proteinbar,/obj/item/clothing/mask/breath,/obj/item/weapon/tank/emergency/oxygen/engi) +/obj/machinery/door/blast/regular{ + destroy_hits = 1000; + explosion_resistance = 200; + id = "tabi-hangar2" }, -/obj/item/weapon/storage/box/survival/comp{ - starts_with = list(/obj/item/weapon/tool/prybar/red,/obj/item/clothing/glasses/goggles,/obj/item/weapon/reagent_containers/hypospray/autoinjector,/obj/item/stack/medical/bruise_pack,/obj/item/device/flashlight/glowstick,/obj/item/weapon/reagent_containers/food/snacks/candy/proteinbar,/obj/item/clothing/mask/breath,/obj/item/weapon/tank/emergency/oxygen/engi) +/obj/effect/floor_decal/industrial/danger/full, +/turf/simulated/floor/reinforced{ + explosion_resistance = 200 }, -/obj/item/weapon/storage/box/survival/comp{ - starts_with = list(/obj/item/weapon/tool/prybar/red,/obj/item/clothing/glasses/goggles,/obj/item/weapon/reagent_containers/hypospray/autoinjector,/obj/item/stack/medical/bruise_pack,/obj/item/device/flashlight/glowstick,/obj/item/weapon/reagent_containers/food/snacks/candy/proteinbar,/obj/item/clothing/mask/breath,/obj/item/weapon/tank/emergency/oxygen/engi) - }, -/obj/item/weapon/storage/box/survival/comp{ - starts_with = list(/obj/item/weapon/tool/prybar/red,/obj/item/clothing/glasses/goggles,/obj/item/weapon/reagent_containers/hypospray/autoinjector,/obj/item/stack/medical/bruise_pack,/obj/item/device/flashlight/glowstick,/obj/item/weapon/reagent_containers/food/snacks/candy/proteinbar,/obj/item/clothing/mask/breath,/obj/item/weapon/tank/emergency/oxygen/engi) - }, -/obj/item/weapon/storage/box/survival/comp{ - starts_with = list(/obj/item/weapon/tool/prybar/red,/obj/item/clothing/glasses/goggles,/obj/item/weapon/reagent_containers/hypospray/autoinjector,/obj/item/stack/medical/bruise_pack,/obj/item/device/flashlight/glowstick,/obj/item/weapon/reagent_containers/food/snacks/candy/proteinbar,/obj/item/clothing/mask/breath,/obj/item/weapon/tank/emergency/oxygen/engi) - }, -/obj/item/device/perfect_tele, -/obj/item/weapon/storage/belt/utility/chief/full, -/obj/item/weapon/storage/belt/utility/chief/full, -/obj/item/weapon/storage/belt/utility/chief/full, -/obj/item/weapon/storage/belt/utility/chief/full, -/obj/item/weapon/storage/belt/security/tactical, -/obj/item/weapon/storage/belt/security/tactical, -/obj/item/weapon/storage/belt/security/tactical, -/obj/item/weapon/storage/belt/security/tactical, -/obj/item/weapon/storage/belt/medical/emt, -/obj/item/weapon/storage/belt/medical/emt, -/obj/item/weapon/storage/belt/medical/emt, -/obj/item/weapon/storage/belt/medical/emt, -/obj/item/weapon/storage/backpack/ert/commander, -/obj/item/weapon/storage/backpack/ert/engineer, -/obj/item/weapon/storage/backpack/ert/engineer, -/obj/item/weapon/storage/backpack/ert/medical, -/obj/item/weapon/storage/backpack/ert/medical, -/obj/item/weapon/storage/backpack/ert/security, -/obj/item/weapon/storage/backpack/ert/security, -/obj/item/weapon/storage/backpack/ert/security, -/obj/item/weapon/storage/backpack/ert/security, -/obj/item/weapon/cell/hyper, -/obj/item/weapon/cell/hyper, -/obj/item/weapon/cell/hyper, -/obj/item/weapon/cell/hyper, -/obj/item/weapon/cell/hyper, -/obj/item/weapon/cell/hyper, -/obj/item/weapon/cell/hyper, -/obj/item/weapon/cell/hyper, -/obj/item/weapon/cell/hyper, -/obj/item/weapon/cell/hyper, -/obj/item/weapon/gun/energy/locked/frontier/holdout/unlocked, -/obj/item/weapon/gun/energy/locked/frontier/holdout/unlocked, -/obj/item/weapon/gun/energy/locked/frontier/holdout/unlocked, -/obj/item/weapon/gun/energy/locked/frontier/holdout/unlocked, -/obj/item/weapon/gun/energy/locked/frontier/holdout/unlocked, -/obj/item/weapon/gun/energy/locked/frontier/holdout/unlocked, -/obj/item/weapon/gun/energy/locked/frontier/holdout/unlocked, -/obj/item/weapon/gun/projectile/pistol, -/obj/item/weapon/gun/projectile/pistol, -/obj/item/weapon/gun/projectile/pistol, -/obj/item/ammo_magazine/m9mm/compact, -/obj/item/ammo_magazine/m9mm/compact, -/obj/item/ammo_magazine/m9mm/compact, -/obj/item/ammo_magazine/m9mm/compact, -/obj/item/ammo_magazine/m9mm/compact, -/obj/item/ammo_magazine/m9mm/compact, -/obj/item/ammo_magazine/m9mm/compact/flash, -/obj/item/ammo_magazine/m9mm/compact/flash, -/obj/item/ammo_magazine/m9mm/compact/flash, -/obj/item/ammo_magazine/m9mm/compact/rubber, -/obj/item/ammo_magazine/m9mm/compact/rubber, -/obj/item/ammo_magazine/m9mm/compact/rubber, -/obj/item/ammo_magazine/m9mm/compact/practice, -/obj/item/ammo_magazine/m9mm/compact/practice, -/obj/item/ammo_magazine/m9mm/compact/practice, -/obj/item/clothing/glasses/thermal, -/obj/item/clothing/glasses/thermal, -/obj/item/clothing/glasses/graviton, -/obj/item/clothing/glasses/graviton, -/obj/item/clothing/glasses/graviton, -/obj/item/clothing/glasses/graviton, -/obj/item/clothing/glasses/graviton, -/obj/item/clothing/glasses/graviton, -/obj/item/clothing/glasses/night, -/obj/item/clothing/glasses/night, -/obj/item/clothing/glasses/night, -/obj/item/clothing/glasses/night, -/obj/item/device/binoculars, -/obj/item/device/binoculars, -/obj/item/device/binoculars, -/obj/item/device/binoculars, -/obj/item/clothing/mask/gas/half, -/obj/item/clothing/mask/gas/half, -/obj/item/clothing/mask/gas/half, -/obj/item/clothing/mask/gas/half, -/obj/item/clothing/mask/gas/half, -/obj/item/clothing/mask/gas/half, -/obj/item/clothing/mask/gas/half, -/obj/item/clothing/mask/gas/half, -/obj/item/modular_computer/laptop/preset/custom_loadout/elite, -/obj/item/modular_computer/laptop/preset/custom_loadout/elite, -/obj/item/modular_computer/laptop/preset/custom_loadout/elite, -/obj/item/modular_computer/laptop/preset/custom_loadout/elite, -/obj/item/modular_computer/laptop/preset/custom_loadout/elite, -/obj/item/modular_computer/laptop/preset/custom_loadout/elite, -/obj/item/modular_computer/tablet/preset/custom_loadout/elite, -/obj/item/modular_computer/tablet/preset/custom_loadout/elite, -/obj/item/modular_computer/tablet/preset/custom_loadout/elite, -/obj/item/modular_computer/tablet/preset/custom_loadout/elite, -/obj/item/modular_computer/tablet/preset/custom_loadout/elite, -/obj/item/modular_computer/tablet/preset/custom_loadout/elite, -/obj/item/device/survivalcapsule, -/obj/item/device/survivalcapsule, -/obj/item/device/survivalcapsule, -/obj/item/device/survivalcapsule, -/obj/item/device/survivalcapsule, -/obj/item/device/survivalcapsule, -/obj/item/device/survivalcapsule, -/obj/item/device/survivalcapsule, -/obj/item/device/survivalcapsule, -/obj/item/device/survivalcapsule, -/obj/item/device/survivalcapsule, -/obj/item/device/survivalcapsule, -/obj/item/device/survivalcapsule, -/obj/item/device/survivalcapsule, -/obj/item/device/survivalcapsule, -/obj/item/device/survivalcapsule, -/obj/item/device/survivalcapsule, -/obj/item/device/survivalcapsule, -/obj/item/device/survivalcapsule, -/obj/item/device/survivalcapsule, -/obj/item/device/survivalcapsule/luxury, -/obj/item/device/survivalcapsule/luxury, -/obj/item/device/survivalcapsule/luxury, -/obj/item/device/survivalcapsule/luxury, -/obj/item/device/survivalcapsule/luxury, -/obj/item/device/survivalcapsule/luxury, -/obj/item/device/survivalcapsule/luxury, -/obj/item/device/survivalcapsule/luxury, -/obj/item/device/survivalcapsule/luxurybar, -/obj/item/device/survivalcapsule/luxurybar, -/obj/item/weapon/tank/emergency/oxygen/double, -/obj/item/weapon/tank/emergency/oxygen/double, -/obj/item/weapon/tank/emergency/oxygen/double, -/obj/item/weapon/tank/emergency/oxygen/double, -/obj/item/weapon/tank/emergency/oxygen/double, -/obj/item/weapon/tank/emergency/oxygen/double, -/obj/item/weapon/tank/emergency/oxygen/double, -/obj/item/weapon/tank/emergency/oxygen/double, -/obj/item/weapon/tank/emergency/oxygen/double, -/obj/item/weapon/tank/emergency/oxygen/double, -/obj/item/clothing/suit/space/void/refurb/officer, -/obj/item/modular_computer/laptop/preset/custom_loadout/hybrid, -/obj/item/weapon/gun/magnetic/railgun/automatic, -/obj/item/weapon/gun/magnetic/railgun/automatic, -/turf/simulated/floor/tiled/white, -/area/shuttle/tabiranth) -"aA" = ( -/obj/machinery/atmospherics/portables_connector, -/obj/machinery/portable_atmospherics/canister/air{ - start_pressure = 8559.63 - }, -/obj/machinery/light{ - dir = 8; - icon_state = "tube1" - }, -/turf/simulated/floor/reinforced, /area/shuttle/tabiranth) "aB" = ( -/obj/machinery/atmospherics/portables_connector, -/obj/machinery/portable_atmospherics/canister/air{ - start_pressure = 8559.63 +/obj/machinery/portable_atmospherics/canister/oxygen{ + start_pressure = 15000 }, -/obj/machinery/light{ - dir = 4 +/obj/machinery/mech_recharger, +/obj/effect/floor_decal/techfloor{ + dir = 1 }, +/obj/effect/floor_decal/techfloor, /turf/simulated/floor/reinforced, /area/shuttle/tabiranth) "aC" = ( @@ -702,46 +547,25 @@ /turf/simulated/floor/bluegrid, /area/shuttle/tabiranth) "aD" = ( -/obj/structure/fans/hardlight, -/obj/machinery/door/airlock/alien/blue/locked{ - req_one_access = list(101) +/obj/machinery/atmospherics/portables_connector, +/obj/machinery/portable_atmospherics/canister/air{ + start_pressure = 15000 }, -/obj/machinery/access_button{ - command = "cycle_exterior"; - frequency = 1380; - master_tag = "tabiranth_airlock"; - name = "exterior access button"; - pixel_x = -5; - pixel_y = -26 +/obj/machinery/light{ + dir = 8; + icon_state = "tube1" }, -/obj/effect/map_helper/airlock/door/ext_door, -/turf/simulated/floor/tiled/techfloor/grid, +/turf/simulated/floor/reinforced, /area/shuttle/tabiranth) "aE" = ( -/obj/machinery/atmospherics/unary/vent_pump/high_volume{ - dir = 4; - frequency = 1380 +/obj/machinery/atmospherics/portables_connector, +/obj/machinery/portable_atmospherics/canister/air{ + start_pressure = 15000 }, -/obj/machinery/embedded_controller/radio/airlock/docking_port{ - frequency = 1380; - id_tag = "tabiranth_airlock"; - pixel_y = -32; - req_one_access = list(101) +/obj/machinery/light{ + dir = 4 }, -/obj/machinery/airlock_sensor{ - frequency = 1380; - pixel_y = 25 - }, -/obj/effect/map_helper/airlock/atmos/chamber_pump, -/obj/effect/map_helper/airlock/sensor/chamber_sensor, -/obj/machinery/light/small{ - icon_state = "bulb1"; - dir = 1 - }, -/obj/structure/handrail{ - dir = 1 - }, -/turf/simulated/floor/tiled/techfloor/grid, +/turf/simulated/floor/reinforced, /area/shuttle/tabiranth) "aF" = ( /obj/machinery/atmospherics/pipe/manifold/hidden, @@ -782,12 +606,23 @@ /turf/simulated/floor/reinforced, /area/shuttle/tabiranth) "aH" = ( -/obj/machinery/portable_atmospherics/canister/oxygen, -/obj/machinery/mech_recharger, -/obj/effect/floor_decal/techfloor{ - dir = 1 +/obj/structure/fans/hardlight{ + explosion_resistance = 100 }, -/obj/effect/floor_decal/techfloor, +/obj/machinery/door/airlock/alien/blue/locked{ + explosion_resistance = 200; + req_one_access = list(101) + }, +/obj/machinery/access_button{ + command = "cycle_exterior"; + frequency = 1380; + master_tag = "tabiranth_airlock"; + name = "exterior access button"; + pixel_x = -5; + pixel_y = -26 + }, +/obj/effect/map_helper/airlock/door/ext_door, +/obj/effect/floor_decal/industrial/danger/full, /turf/simulated/floor/reinforced, /area/shuttle/tabiranth) "aI" = ( @@ -840,11 +675,40 @@ /turf/simulated/floor/reinforced, /area/shuttle/tabiranth) "aK" = ( +/obj/machinery/atmospherics/unary/vent_pump/high_volume{ + dir = 4; + frequency = 1380 + }, +/obj/machinery/embedded_controller/radio/airlock/docking_port{ + frequency = 1380; + id_tag = "tabiranth_airlock"; + pixel_y = -32; + req_one_access = list(101) + }, +/obj/machinery/airlock_sensor{ + frequency = 1380; + pixel_y = 25 + }, +/obj/effect/map_helper/airlock/atmos/chamber_pump, +/obj/effect/map_helper/airlock/sensor/chamber_sensor, +/obj/machinery/light/small{ + icon_state = "bulb1"; + dir = 1 + }, +/obj/structure/handrail{ + dir = 1 + }, +/turf/simulated/floor/reinforced, +/area/shuttle/tabiranth) +"aL" = ( /obj/machinery/atmospherics/pipe/simple/hidden{ dir = 4 }, -/obj/structure/fans/hardlight, +/obj/structure/fans/hardlight{ + explosion_resistance = 100 + }, /obj/machinery/door/airlock/alien/blue/locked{ + explosion_resistance = 200; req_one_access = list(101) }, /obj/machinery/access_button{ @@ -855,14 +719,18 @@ pixel_y = 26 }, /obj/effect/map_helper/airlock/door/int_door, -/turf/simulated/floor/tiled/techfloor/grid, +/obj/effect/floor_decal/industrial/danger/full, +/turf/simulated/floor/reinforced, /area/shuttle/tabiranth) -"aL" = ( +"aM" = ( /obj/machinery/atmospherics/pipe/simple/hidden{ dir = 4 }, -/obj/structure/fans/hardlight, +/obj/structure/fans/hardlight{ + explosion_resistance = 100 + }, /obj/machinery/door/airlock/alien/blue/locked{ + explosion_resistance = 200; req_one_access = list(101) }, /obj/machinery/access_button{ @@ -873,17 +741,41 @@ pixel_y = 26 }, /obj/effect/map_helper/airlock/door/int_door, -/turf/simulated/floor/tiled/techfloor/grid, -/area/shuttle/tabiranth) -"aM" = ( -/turf/simulated/floor/reinforced/airless{ - name = "outer hull" - }, +/obj/effect/floor_decal/industrial/danger/full, +/turf/simulated/floor/reinforced, /area/shuttle/tabiranth) "aN" = ( /obj/machinery/sleeper/survival_pod, /turf/simulated/floor/tiled/white, /area/shuttle/tabiranth) +"aO" = ( +/obj/machinery/atmospherics/unary/vent_pump/high_volume{ + dir = 8; + frequency = 1380 + }, +/obj/machinery/light/small{ + icon_state = "bulb1"; + dir = 1 + }, +/obj/machinery/airlock_sensor{ + frequency = 1380; + pixel_y = 25 + }, +/obj/machinery/embedded_controller/radio/airlock/docking_port{ + frequency = 1380; + id_tag = "tabiranth_docker"; + pixel_y = -32; + req_one_access = list(101) + }, +/obj/effect/shuttle_landmark/shuttle_initializer/tabiranth, +/obj/effect/overmap/visitable/ship/landable/tabiranth, +/obj/effect/map_helper/airlock/sensor/chamber_sensor, +/obj/effect/map_helper/airlock/atmos/chamber_pump, +/obj/structure/handrail{ + dir = 1 + }, +/turf/simulated/floor/reinforced, +/area/shuttle/tabiranth) "aP" = ( /obj/machinery/telecomms/allinone, /turf/simulated/floor/bluegrid, @@ -1037,16 +929,24 @@ /turf/simulated/floor/tiled/white, /area/shuttle/tabiranth) "aT" = ( -/obj/machinery/shipsensors{ - dir = 1; - health = 1000; - heat_reduction = 4.5; - max_health = 1000; - name = "military sensors suite" +/obj/structure/fans/hardlight{ + explosion_resistance = 100 }, -/turf/simulated/floor/reinforced/airless{ - name = "outer hull" +/obj/machinery/door/airlock/alien/blue/locked{ + explosion_resistance = 200; + req_one_access = list(101) }, +/obj/effect/map_helper/airlock/door/ext_door, +/obj/machinery/access_button{ + command = "cycle_exterior"; + frequency = 1380; + master_tag = "tabiranth_docker"; + name = "exterior access button"; + pixel_x = 5; + pixel_y = -26 + }, +/obj/effect/floor_decal/industrial/danger/full, +/turf/simulated/floor/reinforced, /area/shuttle/tabiranth) "aU" = ( /obj/machinery/chemical_dispenser/ert/specialops, @@ -1167,6 +1067,510 @@ /turf/simulated/floor/tiled/techfloor/grid, /area/shuttle/tabiranth) "bj" = ( +/obj/structure/handrail{ + dir = 8 + }, +/turf/simulated/shuttle/wall/voidcraft/blue{ + name = "small craft wall"; + stripe_color = "#45b3d8" + }, +/area/shuttle/tabiranth) +"bk" = ( +/obj/effect/floor_decal/techfloor{ + dir = 5 + }, +/obj/structure/closet/secure_closet/wall{ + anchored = 1; + density = 0; + pixel_x = 32; + req_access = list(101) + }, +/turf/simulated/floor/tiled/techfloor/grid, +/area/shuttle/tabiranth) +"bl" = ( +/obj/machinery/power/smes/buildable/hybrid{ + input_level = 200000; + output_level = 200000 + }, +/obj/structure/cable/cyan{ + icon_state = "0-4" + }, +/turf/simulated/floor/tiled/techmaint, +/area/shuttle/tabiranth) +"bm" = ( +/obj/structure/cable/cyan{ + d1 = 1; + d2 = 8; + icon_state = "1-8" + }, +/obj/machinery/power/terminal{ + dir = 8 + }, +/turf/simulated/floor/tiled/techmaint, +/area/shuttle/tabiranth) +"bn" = ( +/obj/machinery/pointdefense_control{ + id_tag = "tabiranth_pd" + }, +/turf/simulated/floor/tiled/techmaint, +/area/shuttle/tabiranth) +"bo" = ( +/obj/structure/closet/medical_wall{ + pixel_x = -32 + }, +/obj/item/weapon/reagent_containers/blood/prelabeled/OMinus, +/obj/item/weapon/reagent_containers/blood/prelabeled/OMinus, +/obj/item/weapon/reagent_containers/blood/prelabeled/OMinus, +/obj/item/weapon/reagent_containers/blood/prelabeled/OMinus, +/obj/item/weapon/reagent_containers/blood/prelabeled/OMinus, +/obj/item/weapon/reagent_containers/blood/prelabeled/OMinus, +/obj/item/weapon/reagent_containers/blood/prelabeled/OMinus, +/obj/item/weapon/reagent_containers/blood/prelabeled/OMinus, +/obj/item/weapon/storage/box/gloves, +/obj/item/weapon/storage/firstaid/surgery, +/obj/item/weapon/reagent_containers/spray/cleaner{ + desc = "Someone has crossed out the Space from Space Cleaner and written in Surgery. 'Do not remove under punishment of death!!!' is scrawled on the back."; + name = "Surgery Cleaner"; + pixel_x = 2; + pixel_y = 2 + }, +/obj/item/weapon/reagent_containers/spray/cleaner{ + desc = "Someone has crossed out the Space from Space Cleaner and written in Surgery. 'Do not remove under punishment of death!!!' is scrawled on the back."; + name = "Surgery Cleaner"; + pixel_x = 2; + pixel_y = 2 + }, +/obj/item/device/mmi/digital/posibrain, +/obj/item/device/mmi, +/obj/item/weapon/book/manual/robotics_cyborgs, +/obj/item/device/robotanalyzer, +/obj/item/weapon/tank/anesthetic, +/obj/item/weapon/tank/anesthetic, +/obj/item/weapon/tank/anesthetic, +/obj/item/clothing/mask/breath/medical, +/obj/item/clothing/mask/breath/medical, +/obj/item/clothing/mask/breath/medical, +/obj/item/weapon/storage/belt/utility/chief/full, +/obj/item/stack/cable_coil/alien, +/obj/item/stack/nanopaste, +/obj/item/stack/nanopaste, +/obj/item/stack/nanopaste, +/obj/item/device/defib_kit/jumper_kit/loaded, +/obj/item/device/defib_kit/compact/loaded, +/turf/simulated/floor/tiled/white, +/area/shuttle/tabiranth) +"bp" = ( +/obj/machinery/computer/operating{ + dir = 8 + }, +/turf/simulated/floor/tiled/white, +/area/shuttle/tabiranth) +"bq" = ( +/obj/machinery/mineral/equipment_vendor, +/obj/effect/floor_decal/techfloor{ + dir = 8 + }, +/turf/simulated/floor/tiled/techfloor/grid, +/area/shuttle/tabiranth) +"br" = ( +/obj/effect/floor_decal/techfloor{ + dir = 4 + }, +/obj/machinery/light/small{ + dir = 4; + pixel_y = 0 + }, +/obj/machinery/atm, +/turf/simulated/floor/tiled/techfloor/grid, +/area/shuttle/tabiranth) +"bs" = ( +/obj/structure/table/survival_pod, +/obj/machinery/turretid{ + control_area = /area/shuttle/tabiranth; + pixel_x = -32; + req_access = list(101) + }, +/obj/machinery/light/small{ + dir = 8; + pixel_x = 0 + }, +/obj/machinery/recharger, +/obj/item/modular_computer/laptop/preset/custom_loadout/elite, +/turf/simulated/floor/tiled/techmaint, +/area/shuttle/tabiranth) +"bt" = ( +/obj/structure/handrail{ + dir = 8 + }, +/turf/simulated/floor/reinforced/airless{ + name = "outer hull" + }, +/area/shuttle/tabiranth) +"bu" = ( +/obj/machinery/computer/ship/engines{ + dir = 8; + icon_state = "computer" + }, +/obj/machinery/light/small{ + dir = 4; + pixel_y = 0 + }, +/turf/simulated/floor/tiled/techmaint, +/area/shuttle/tabiranth) +"bv" = ( +/obj/structure/medical_stand, +/obj/machinery/light{ + dir = 8; + icon_state = "tube1" + }, +/turf/simulated/floor/tiled/white, +/area/shuttle/tabiranth) +"bw" = ( +/obj/machinery/optable, +/obj/machinery/oxygen_pump/anesthetic{ + pixel_x = 32 + }, +/turf/simulated/floor/tiled/white, +/area/shuttle/tabiranth) +"bx" = ( +/obj/machinery/mineral/equipment_vendor/survey, +/obj/effect/floor_decal/techfloor{ + dir = 10 + }, +/turf/simulated/floor/tiled/techfloor/grid, +/area/shuttle/tabiranth) +"by" = ( +/obj/machinery/syndicate_beacon/virgo{ + charges = 10; + density = 0 + }, +/obj/effect/floor_decal/techfloor{ + icon_state = "techfloor_edges"; + dir = 6 + }, +/obj/machinery/vending/nifsoft_shop{ + categories = 111; + emagged = 1; + name = "Hacked NIFSoft Shop"; + prices = list() + }, +/turf/simulated/floor/tiled/techfloor/grid, +/area/shuttle/tabiranth) +"bz" = ( +/obj/machinery/computer/ship/sensors{ + dir = 4 + }, +/turf/simulated/floor/tiled/techmaint, +/area/shuttle/tabiranth) +"bA" = ( +/obj/structure/cable/cyan{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/obj/machinery/door/airlock/alien/blue{ + req_one_access = list(108) + }, +/turf/simulated/floor/tiled/steel_ridged, +/area/shuttle/tabiranth) +"bB" = ( +/obj/machinery/computer/shuttle_control/explore/tabiranth{ + dir = 8 + }, +/turf/simulated/floor/tiled/techmaint, +/area/shuttle/tabiranth) +"bC" = ( +/obj/machinery/organ_printer/flesh/full, +/obj/structure/sink/kitchen{ + icon_state = "sink_alt"; + dir = 4; + pixel_x = -13 + }, +/turf/simulated/floor/tiled/white, +/area/shuttle/tabiranth) +"bD" = ( +/obj/item/weapon/storage/firstaid/surgery, +/obj/item/weapon/reagent_containers/spray/cleaner{ + desc = "Someone has crossed out the Space from Space Cleaner and written in Surgery. 'Do not remove under punishment of death!!!' is scrawled on the back."; + name = "Surgery Cleaner"; + pixel_x = 2; + pixel_y = 2 + }, +/obj/structure/table/survival_pod, +/turf/simulated/floor/tiled/white, +/area/shuttle/tabiranth) +"bE" = ( +/obj/structure/shuttle/engine/heater, +/obj/structure/window/phoronreinforced{ + dir = 1 + }, +/turf/simulated/floor/reinforced/airless, +/area/shuttle/tabiranth) +"bF" = ( +/obj/machinery/computer/ship/helm{ + dir = 1 + }, +/turf/simulated/floor/tiled/techmaint, +/area/shuttle/tabiranth) +"bG" = ( +/obj/machinery/ion_engine{ + generated_thrust = 5 + }, +/turf/simulated/floor/reinforced/airless, +/area/shuttle/tabiranth) +"bH" = ( +/obj/structure/closet/hydrant{ + pixel_x = 32 + }, +/obj/item/clothing/suit/fire/firefighter, +/obj/item/clothing/mask/gas, +/obj/item/device/flashlight, +/obj/item/weapon/tank/oxygen/red, +/obj/item/weapon/tank/emergency/oxygen/double, +/obj/item/weapon/tank/emergency/oxygen/double, +/obj/item/weapon/extinguisher, +/obj/item/weapon/extinguisher, +/obj/item/weapon/extinguisher, +/obj/item/weapon/extinguisher, +/obj/item/clothing/head/hardhat/red, +/obj/item/weapon/storage/toolbox/emergency, +/turf/simulated/floor/tiled/white, +/area/shuttle/tabiranth) +"bI" = ( +/obj/structure/bed/chair/bay/shuttle, +/obj/machinery/button/remote/blast_door{ + id = "tabi-vault"; + name = "Vault Blast Door Controls"; + pixel_x = 26; + pixel_y = -26; + req_one_access = list(108) + }, +/turf/simulated/floor/tiled/techmaint, +/area/shuttle/tabiranth) +"bJ" = ( +/obj/machinery/smartfridge/survival_pod, +/obj/item/clothing/under/ert, +/obj/item/clothing/under/ert, +/obj/item/clothing/under/ert, +/obj/item/clothing/under/ert, +/obj/item/clothing/under/ert, +/obj/item/clothing/under/ert, +/obj/item/weapon/storage/box/survival/comp{ + starts_with = list(/obj/item/weapon/tool/prybar/red,/obj/item/clothing/glasses/goggles,/obj/item/weapon/reagent_containers/hypospray/autoinjector,/obj/item/stack/medical/bruise_pack,/obj/item/device/flashlight/glowstick,/obj/item/weapon/reagent_containers/food/snacks/candy/proteinbar,/obj/item/clothing/mask/breath,/obj/item/weapon/tank/emergency/oxygen/engi) + }, +/obj/item/weapon/storage/box/survival/comp{ + starts_with = list(/obj/item/weapon/tool/prybar/red,/obj/item/clothing/glasses/goggles,/obj/item/weapon/reagent_containers/hypospray/autoinjector,/obj/item/stack/medical/bruise_pack,/obj/item/device/flashlight/glowstick,/obj/item/weapon/reagent_containers/food/snacks/candy/proteinbar,/obj/item/clothing/mask/breath,/obj/item/weapon/tank/emergency/oxygen/engi) + }, +/obj/item/weapon/storage/box/survival/comp{ + starts_with = list(/obj/item/weapon/tool/prybar/red,/obj/item/clothing/glasses/goggles,/obj/item/weapon/reagent_containers/hypospray/autoinjector,/obj/item/stack/medical/bruise_pack,/obj/item/device/flashlight/glowstick,/obj/item/weapon/reagent_containers/food/snacks/candy/proteinbar,/obj/item/clothing/mask/breath,/obj/item/weapon/tank/emergency/oxygen/engi) + }, +/obj/item/weapon/storage/box/survival/comp{ + starts_with = list(/obj/item/weapon/tool/prybar/red,/obj/item/clothing/glasses/goggles,/obj/item/weapon/reagent_containers/hypospray/autoinjector,/obj/item/stack/medical/bruise_pack,/obj/item/device/flashlight/glowstick,/obj/item/weapon/reagent_containers/food/snacks/candy/proteinbar,/obj/item/clothing/mask/breath,/obj/item/weapon/tank/emergency/oxygen/engi) + }, +/obj/item/weapon/storage/box/survival/comp{ + starts_with = list(/obj/item/weapon/tool/prybar/red,/obj/item/clothing/glasses/goggles,/obj/item/weapon/reagent_containers/hypospray/autoinjector,/obj/item/stack/medical/bruise_pack,/obj/item/device/flashlight/glowstick,/obj/item/weapon/reagent_containers/food/snacks/candy/proteinbar,/obj/item/clothing/mask/breath,/obj/item/weapon/tank/emergency/oxygen/engi) + }, +/obj/item/weapon/storage/box/survival/comp{ + starts_with = list(/obj/item/weapon/tool/prybar/red,/obj/item/clothing/glasses/goggles,/obj/item/weapon/reagent_containers/hypospray/autoinjector,/obj/item/stack/medical/bruise_pack,/obj/item/device/flashlight/glowstick,/obj/item/weapon/reagent_containers/food/snacks/candy/proteinbar,/obj/item/clothing/mask/breath,/obj/item/weapon/tank/emergency/oxygen/engi) + }, +/obj/item/device/perfect_tele, +/obj/item/weapon/storage/belt/utility/chief/full, +/obj/item/weapon/storage/belt/utility/chief/full, +/obj/item/weapon/storage/belt/utility/chief/full, +/obj/item/weapon/storage/belt/utility/chief/full, +/obj/item/weapon/storage/belt/security/tactical, +/obj/item/weapon/storage/belt/security/tactical, +/obj/item/weapon/storage/belt/security/tactical, +/obj/item/weapon/storage/belt/security/tactical, +/obj/item/weapon/storage/belt/medical/emt, +/obj/item/weapon/storage/belt/medical/emt, +/obj/item/weapon/storage/belt/medical/emt, +/obj/item/weapon/storage/belt/medical/emt, +/obj/item/weapon/storage/backpack/ert/commander, +/obj/item/weapon/storage/backpack/ert/engineer, +/obj/item/weapon/storage/backpack/ert/engineer, +/obj/item/weapon/storage/backpack/ert/medical, +/obj/item/weapon/storage/backpack/ert/medical, +/obj/item/weapon/storage/backpack/ert/security, +/obj/item/weapon/storage/backpack/ert/security, +/obj/item/weapon/storage/backpack/ert/security, +/obj/item/weapon/storage/backpack/ert/security, +/obj/item/weapon/cell/hyper, +/obj/item/weapon/cell/hyper, +/obj/item/weapon/cell/hyper, +/obj/item/weapon/cell/hyper, +/obj/item/weapon/cell/hyper, +/obj/item/weapon/cell/hyper, +/obj/item/weapon/cell/hyper, +/obj/item/weapon/cell/hyper, +/obj/item/weapon/cell/hyper, +/obj/item/weapon/cell/hyper, +/obj/item/weapon/gun/energy/locked/frontier/holdout/unlocked, +/obj/item/weapon/gun/energy/locked/frontier/holdout/unlocked, +/obj/item/weapon/gun/energy/locked/frontier/holdout/unlocked, +/obj/item/weapon/gun/energy/locked/frontier/holdout/unlocked, +/obj/item/weapon/gun/energy/locked/frontier/holdout/unlocked, +/obj/item/weapon/gun/energy/locked/frontier/holdout/unlocked, +/obj/item/weapon/gun/projectile/pistol, +/obj/item/weapon/gun/projectile/pistol, +/obj/item/weapon/gun/projectile/pistol, +/obj/item/ammo_magazine/m9mm/compact, +/obj/item/ammo_magazine/m9mm/compact, +/obj/item/ammo_magazine/m9mm/compact, +/obj/item/ammo_magazine/m9mm/compact, +/obj/item/ammo_magazine/m9mm/compact, +/obj/item/ammo_magazine/m9mm/compact, +/obj/item/ammo_magazine/m9mm/compact/flash, +/obj/item/ammo_magazine/m9mm/compact/flash, +/obj/item/ammo_magazine/m9mm/compact/flash, +/obj/item/ammo_magazine/m9mm/compact/rubber, +/obj/item/ammo_magazine/m9mm/compact/rubber, +/obj/item/ammo_magazine/m9mm/compact/rubber, +/obj/item/ammo_magazine/m9mm/compact/practice, +/obj/item/ammo_magazine/m9mm/compact/practice, +/obj/item/ammo_magazine/m9mm/compact/practice, +/obj/item/clothing/glasses/thermal, +/obj/item/clothing/glasses/thermal, +/obj/item/clothing/glasses/graviton, +/obj/item/clothing/glasses/graviton, +/obj/item/clothing/glasses/graviton, +/obj/item/clothing/glasses/graviton, +/obj/item/clothing/glasses/graviton, +/obj/item/clothing/glasses/graviton, +/obj/item/clothing/glasses/night, +/obj/item/clothing/glasses/night, +/obj/item/clothing/glasses/night, +/obj/item/clothing/glasses/night, +/obj/item/device/binoculars, +/obj/item/device/binoculars, +/obj/item/device/binoculars, +/obj/item/device/binoculars, +/obj/item/clothing/mask/gas/half, +/obj/item/clothing/mask/gas/half, +/obj/item/clothing/mask/gas/half, +/obj/item/clothing/mask/gas/half, +/obj/item/clothing/mask/gas/half, +/obj/item/clothing/mask/gas/half, +/obj/item/clothing/mask/gas/half, +/obj/item/clothing/mask/gas/half, +/obj/item/modular_computer/laptop/preset/custom_loadout/elite, +/obj/item/modular_computer/laptop/preset/custom_loadout/elite, +/obj/item/modular_computer/laptop/preset/custom_loadout/elite, +/obj/item/modular_computer/laptop/preset/custom_loadout/elite, +/obj/item/modular_computer/laptop/preset/custom_loadout/elite, +/obj/item/modular_computer/laptop/preset/custom_loadout/elite, +/obj/item/modular_computer/tablet/preset/custom_loadout/elite, +/obj/item/modular_computer/tablet/preset/custom_loadout/elite, +/obj/item/modular_computer/tablet/preset/custom_loadout/elite, +/obj/item/modular_computer/tablet/preset/custom_loadout/elite, +/obj/item/modular_computer/tablet/preset/custom_loadout/elite, +/obj/item/modular_computer/tablet/preset/custom_loadout/elite, +/obj/item/device/survivalcapsule, +/obj/item/device/survivalcapsule, +/obj/item/device/survivalcapsule, +/obj/item/device/survivalcapsule, +/obj/item/device/survivalcapsule, +/obj/item/device/survivalcapsule, +/obj/item/device/survivalcapsule, +/obj/item/device/survivalcapsule, +/obj/item/device/survivalcapsule, +/obj/item/device/survivalcapsule, +/obj/item/device/survivalcapsule, +/obj/item/device/survivalcapsule, +/obj/item/device/survivalcapsule, +/obj/item/device/survivalcapsule, +/obj/item/device/survivalcapsule, +/obj/item/device/survivalcapsule, +/obj/item/device/survivalcapsule, +/obj/item/device/survivalcapsule, +/obj/item/device/survivalcapsule, +/obj/item/device/survivalcapsule, +/obj/item/device/survivalcapsule/luxury, +/obj/item/device/survivalcapsule/luxury, +/obj/item/device/survivalcapsule/luxury, +/obj/item/device/survivalcapsule/luxury, +/obj/item/device/survivalcapsule/luxury, +/obj/item/device/survivalcapsule/luxury, +/obj/item/device/survivalcapsule/luxury, +/obj/item/device/survivalcapsule/luxury, +/obj/item/device/survivalcapsule/luxurybar, +/obj/item/device/survivalcapsule/luxurybar, +/obj/item/weapon/tank/emergency/oxygen/double, +/obj/item/weapon/tank/emergency/oxygen/double, +/obj/item/weapon/tank/emergency/oxygen/double, +/obj/item/weapon/tank/emergency/oxygen/double, +/obj/item/weapon/tank/emergency/oxygen/double, +/obj/item/weapon/tank/emergency/oxygen/double, +/obj/item/weapon/tank/emergency/oxygen/double, +/obj/item/weapon/tank/emergency/oxygen/double, +/obj/item/weapon/tank/emergency/oxygen/double, +/obj/item/weapon/tank/emergency/oxygen/double, +/obj/item/clothing/suit/space/void/refurb/officer, +/turf/simulated/floor/tiled/white, +/area/shuttle/tabiranth) +"bK" = ( +/obj/structure/handrail{ + dir = 8 + }, +/obj/machinery/recharge_station{ + density = 0; + layer = 2.45; + plane = -44 + }, +/obj/effect/catwalk_plated/white, +/turf/simulated/floor/tiled/techfloor/grid, +/area/shuttle/tabiranth) +"bL" = ( +/obj/machinery/shipsensors{ + dir = 1; + health = 1000; + heat_reduction = 4.5; + max_health = 1000; + name = "military sensors suite" + }, +/obj/effect/floor_decal/industrial/danger/full, +/turf/simulated/floor/reinforced/airless{ + name = "outer hull" + }, +/area/shuttle/tabiranth) +"bM" = ( +/obj/machinery/door/airlock/alien/blue{ + req_one_access = list(108) + }, +/obj/machinery/door/blast/regular{ + destroy_hits = 100; + dir = 4; + id = "tabi-vault"; + name = "Vault" + }, +/obj/effect/floor_decal/industrial/warning{ + dir = 1 + }, +/turf/simulated/floor/tiled/steel_ridged, +/area/shuttle/tabiranth) +"bN" = ( +/obj/machinery/door/airlock/alien/blue{ + req_one_access = list(101) + }, +/obj/effect/floor_decal/industrial/warning{ + dir = 1 + }, +/turf/simulated/floor/tiled/steel_ridged, +/area/shuttle/tabiranth) +"bO" = ( +/obj/machinery/mech_recharger{ + icon = 'icons/turf/shuttle_alien_blue.dmi' + }, +/obj/mecha/combat/fighter/baron{ + ground_capable = 1; + health = 800; + internal_damage_threshold = 100; + maxhealth = 800; + name = "Panther" + }, +/turf/simulated/floor/reinforced, +/area/shuttle/tabiranth) +"bP" = ( /obj/machinery/smartfridge/survival_pod, /obj/item/clothing/suit/space/void/merc/fire, /obj/item/clothing/head/helmet/space/void/merc/fire, @@ -1305,6 +1709,12 @@ /obj/item/stack/telecrystal{ amount = 240 }, +/obj/item/stack/telecrystal{ + amount = 240 + }, +/obj/item/stack/telecrystal{ + amount = 240 + }, /obj/item/weapon/card/mining_point_card{ mine_points = 50000 }, @@ -1380,7 +1790,6 @@ /obj/item/device/radio/uplink, /obj/item/device/spaceflare, /obj/item/device/spaceflare, -/obj/item/device/perfect_tele/frontier/unknown/six, /obj/item/device/healthanalyzer/phasic, /obj/item/device/bluespaceradio/tether_prelinked, /obj/item/weapon/cat_box, @@ -1429,6 +1838,7 @@ /obj/item/weapon/storage/box/sniperammo, /obj/item/weapon/storage/box/sniperammo, /obj/item/modular_computer/laptop/preset/custom_loadout/hybrid, +/obj/item/modular_computer/laptop/preset/custom_loadout/hybrid, /obj/item/modular_computer/tablet/preset/custom_loadout/hybrid, /obj/item/device/perfect_tele/alien, /obj/item/device/perfect_tele/frontier/staff, @@ -1442,371 +1852,11 @@ /obj/item/weapon/cell/device/weapon/recharge/alien/hybrid, /obj/item/weapon/circuitboard/machine/abductor/core/hybrid, /obj/item/weapon/circuitboard/machine/abductor/core/hybrid, +/obj/item/weapon/gun/magnetic/railgun/automatic, +/obj/item/weapon/gun/magnetic/railgun/automatic, +/obj/effect/floor_decal/industrial/loading, /turf/simulated/floor/tiled/techmaint, /area/shuttle/tabiranth) -"bk" = ( -/obj/effect/floor_decal/techfloor{ - dir = 5 - }, -/obj/structure/closet/secure_closet/wall{ - anchored = 1; - density = 0; - pixel_x = 32; - req_access = list(101) - }, -/turf/simulated/floor/tiled/techfloor/grid, -/area/shuttle/tabiranth) -"bl" = ( -/obj/machinery/power/smes/buildable/hybrid{ - input_level = 200000; - output_level = 200000 - }, -/obj/structure/cable/cyan{ - icon_state = "0-4" - }, -/turf/simulated/floor/tiled/techmaint, -/area/shuttle/tabiranth) -"bm" = ( -/obj/structure/cable/cyan{ - d1 = 1; - d2 = 8; - icon_state = "1-8" - }, -/obj/machinery/power/terminal{ - dir = 8 - }, -/turf/simulated/floor/tiled/techmaint, -/area/shuttle/tabiranth) -"bn" = ( -/obj/machinery/pointdefense_control{ - id_tag = "tabiranth_pd" - }, -/turf/simulated/floor/tiled/techmaint, -/area/shuttle/tabiranth) -"bo" = ( -/obj/structure/closet/medical_wall{ - pixel_x = -32 - }, -/obj/item/weapon/reagent_containers/blood/prelabeled/OMinus, -/obj/item/weapon/reagent_containers/blood/prelabeled/OMinus, -/obj/item/weapon/reagent_containers/blood/prelabeled/OMinus, -/obj/item/weapon/reagent_containers/blood/prelabeled/OMinus, -/obj/item/weapon/reagent_containers/blood/prelabeled/OMinus, -/obj/item/weapon/reagent_containers/blood/prelabeled/OMinus, -/obj/item/weapon/reagent_containers/blood/prelabeled/OMinus, -/obj/item/weapon/reagent_containers/blood/prelabeled/OMinus, -/obj/item/weapon/storage/box/gloves, -/obj/item/weapon/storage/firstaid/surgery, -/obj/item/weapon/reagent_containers/spray/cleaner{ - desc = "Someone has crossed out the Space from Space Cleaner and written in Surgery. 'Do not remove under punishment of death!!!' is scrawled on the back."; - name = "Surgery Cleaner"; - pixel_x = 2; - pixel_y = 2 - }, -/obj/item/weapon/reagent_containers/spray/cleaner{ - desc = "Someone has crossed out the Space from Space Cleaner and written in Surgery. 'Do not remove under punishment of death!!!' is scrawled on the back."; - name = "Surgery Cleaner"; - pixel_x = 2; - pixel_y = 2 - }, -/obj/item/device/mmi/digital/posibrain, -/obj/item/device/mmi, -/obj/item/weapon/book/manual/robotics_cyborgs, -/obj/item/device/robotanalyzer, -/obj/item/weapon/tank/anesthetic, -/obj/item/weapon/tank/anesthetic, -/obj/item/weapon/tank/anesthetic, -/obj/item/clothing/mask/breath/medical, -/obj/item/clothing/mask/breath/medical, -/obj/item/clothing/mask/breath/medical, -/obj/item/weapon/storage/belt/utility/chief/full, -/obj/item/stack/cable_coil/alien, -/obj/item/stack/nanopaste, -/obj/item/stack/nanopaste, -/obj/item/stack/nanopaste, -/obj/item/device/defib_kit/jumper_kit/loaded, -/obj/item/device/defib_kit/compact/loaded, -/turf/simulated/floor/tiled/white, -/area/shuttle/tabiranth) -"bp" = ( -/obj/machinery/computer/operating{ - dir = 8 - }, -/turf/simulated/floor/tiled/white, -/area/shuttle/tabiranth) -"bq" = ( -/obj/machinery/mineral/equipment_vendor, -/obj/effect/floor_decal/techfloor{ - dir = 8 - }, -/turf/simulated/floor/tiled/techfloor/grid, -/area/shuttle/tabiranth) -"br" = ( -/obj/effect/floor_decal/techfloor{ - dir = 4 - }, -/obj/machinery/light/small{ - dir = 4; - pixel_y = 0 - }, -/obj/machinery/atm, -/turf/simulated/floor/tiled/techfloor/grid, -/area/shuttle/tabiranth) -"bs" = ( -/obj/structure/table/survival_pod, -/obj/machinery/turretid{ - control_area = /area/shuttle/tabiranth; - pixel_x = -32; - req_access = list(101) - }, -/obj/machinery/light/small{ - dir = 8; - pixel_x = 0 - }, -/obj/machinery/recharger, -/obj/item/modular_computer/laptop/preset/custom_loadout/elite, -/turf/simulated/floor/tiled/techmaint, -/area/shuttle/tabiranth) -"bt" = ( -/obj/machinery/atmospherics/unary/vent_pump/high_volume{ - dir = 8; - frequency = 1380 - }, -/obj/machinery/light/small{ - icon_state = "bulb1"; - dir = 1 - }, -/obj/machinery/airlock_sensor{ - frequency = 1380; - pixel_y = 25 - }, -/obj/machinery/embedded_controller/radio/airlock/docking_port{ - frequency = 1380; - id_tag = "tabiranth_docker"; - pixel_y = -32; - req_one_access = list(101) - }, -/obj/effect/shuttle_landmark/shuttle_initializer/tabiranth, -/obj/effect/overmap/visitable/ship/landable/tabiranth, -/obj/effect/map_helper/airlock/sensor/chamber_sensor, -/obj/effect/map_helper/airlock/atmos/chamber_pump, -/obj/structure/handrail{ - dir = 1 - }, -/turf/simulated/floor/tiled/techfloor/grid, -/area/shuttle/tabiranth) -"bu" = ( -/obj/machinery/computer/ship/engines{ - dir = 8; - icon_state = "computer" - }, -/obj/machinery/light/small{ - dir = 4; - pixel_y = 0 - }, -/turf/simulated/floor/tiled/techmaint, -/area/shuttle/tabiranth) -"bv" = ( -/obj/structure/medical_stand, -/obj/machinery/light{ - dir = 8; - icon_state = "tube1" - }, -/turf/simulated/floor/tiled/white, -/area/shuttle/tabiranth) -"bw" = ( -/obj/machinery/optable, -/obj/machinery/oxygen_pump/anesthetic{ - pixel_x = 32 - }, -/turf/simulated/floor/tiled/white, -/area/shuttle/tabiranth) -"bx" = ( -/obj/machinery/mineral/equipment_vendor/survey, -/obj/effect/floor_decal/techfloor{ - dir = 10 - }, -/turf/simulated/floor/tiled/techfloor/grid, -/area/shuttle/tabiranth) -"by" = ( -/obj/machinery/syndicate_beacon/virgo{ - charges = 10; - density = 0 - }, -/obj/effect/floor_decal/techfloor{ - icon_state = "techfloor_edges"; - dir = 6 - }, -/obj/machinery/vending/nifsoft_shop{ - categories = 111; - emagged = 1; - name = "Hacked NIFSoft Shop"; - prices = list() - }, -/turf/simulated/floor/tiled/techfloor/grid, -/area/shuttle/tabiranth) -"bz" = ( -/obj/machinery/computer/ship/sensors{ - dir = 4 - }, -/turf/simulated/floor/tiled/techmaint, -/area/shuttle/tabiranth) -"bA" = ( -/obj/structure/cable/cyan{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, -/obj/machinery/door/airlock/alien/blue{ - req_one_access = list(108) - }, -/turf/simulated/floor/tiled/steel_ridged, -/area/shuttle/tabiranth) -"bB" = ( -/obj/machinery/computer/shuttle_control/explore/tabiranth{ - dir = 8 - }, -/turf/simulated/floor/tiled/techmaint, -/area/shuttle/tabiranth) -"bC" = ( -/obj/machinery/organ_printer/flesh/full, -/obj/structure/sink/kitchen{ - icon_state = "sink_alt"; - dir = 4; - pixel_x = -13 - }, -/turf/simulated/floor/tiled/white, -/area/shuttle/tabiranth) -"bD" = ( -/obj/item/weapon/storage/firstaid/surgery, -/obj/item/weapon/reagent_containers/spray/cleaner{ - desc = "Someone has crossed out the Space from Space Cleaner and written in Surgery. 'Do not remove under punishment of death!!!' is scrawled on the back."; - name = "Surgery Cleaner"; - pixel_x = 2; - pixel_y = 2 - }, -/obj/structure/table/survival_pod, -/turf/simulated/floor/tiled/white, -/area/shuttle/tabiranth) -"bE" = ( -/obj/structure/shuttle/engine/heater, -/obj/structure/window/phoronreinforced{ - dir = 1 - }, -/turf/simulated/floor/reinforced/airless, -/area/shuttle/tabiranth) -"bF" = ( -/obj/machinery/computer/ship/helm{ - dir = 1 - }, -/turf/simulated/floor/tiled/techmaint, -/area/shuttle/tabiranth) -"bG" = ( -/obj/machinery/ion_engine, -/turf/simulated/floor/reinforced/airless, -/area/shuttle/tabiranth) -"bH" = ( -/obj/structure/closet/hydrant{ - pixel_x = 32 - }, -/obj/item/clothing/suit/fire/firefighter, -/obj/item/clothing/mask/gas, -/obj/item/device/flashlight, -/obj/item/weapon/tank/oxygen/red, -/obj/item/weapon/tank/emergency/oxygen/double, -/obj/item/weapon/tank/emergency/oxygen/double, -/obj/item/weapon/extinguisher, -/obj/item/weapon/extinguisher, -/obj/item/weapon/extinguisher, -/obj/item/weapon/extinguisher, -/obj/item/clothing/head/hardhat/red, -/obj/item/weapon/storage/toolbox/emergency, -/turf/simulated/floor/tiled/white, -/area/shuttle/tabiranth) -"bI" = ( -/obj/structure/bed/chair/bay/shuttle, -/obj/machinery/button/remote/blast_door{ - id = "tabi-vault"; - name = "Vault Blast Door Controls"; - pixel_x = 26; - pixel_y = -26; - req_one_access = list(108) - }, -/turf/simulated/floor/tiled/techmaint, -/area/shuttle/tabiranth) -"bJ" = ( -/obj/structure/fans/hardlight, -/obj/machinery/door/airlock/alien/blue/locked{ - req_one_access = list(101) - }, -/obj/effect/map_helper/airlock/door/ext_door, -/obj/machinery/access_button{ - command = "cycle_exterior"; - frequency = 1380; - master_tag = "tabiranth_docker"; - name = "exterior access button"; - pixel_x = 5; - pixel_y = -26 - }, -/turf/simulated/floor/tiled/techfloor/grid, -/area/shuttle/tabiranth) -"bK" = ( -/obj/structure/handrail{ - dir = 8 - }, -/obj/machinery/recharge_station{ - density = 0; - layer = 2.45; - plane = -44 - }, -/obj/effect/catwalk_plated/white, -/turf/simulated/floor/tiled/techfloor/grid, -/area/shuttle/tabiranth) -"bM" = ( -/obj/machinery/door/airlock/alien/blue{ - req_one_access = list(108) - }, -/obj/machinery/door/blast/regular{ - destroy_hits = 100; - dir = 4; - id = "tabi-vault"; - name = "Vault" - }, -/obj/effect/floor_decal/industrial/warning{ - dir = 1 - }, -/turf/simulated/floor/tiled/steel_ridged, -/area/shuttle/tabiranth) -"bN" = ( -/obj/machinery/door/airlock/alien/blue{ - req_one_access = list(101) - }, -/obj/effect/floor_decal/industrial/warning{ - dir = 1 - }, -/turf/simulated/floor/tiled/steel_ridged, -/area/shuttle/tabiranth) -"bO" = ( -/obj/machinery/mech_recharger{ - icon = 'icons/turf/shuttle_alien_blue.dmi' - }, -/obj/mecha/combat/fighter/baron{ - ground_capable = 1; - health = 800; - internal_damage_threshold = 100; - maxhealth = 800; - name = "Panther" - }, -/turf/simulated/floor/reinforced, -/area/shuttle/tabiranth) -"wz" = ( -/obj/structure/fans/hardlight, -/obj/machinery/door/blast/regular{ - destroy_hits = 1000; - id = "tabi-hangar2" - }, -/turf/simulated/floor/tiled/steel_ridged, -/area/shuttle/tabiranth) (1,1,1) = {" ba @@ -1815,9 +1865,9 @@ ba ba aa ac -aD +aH ac -aM +bt ab aa ac @@ -1834,13 +1884,13 @@ ah ah ad ad -aE +aK ad ad ad ad ac -bj +bP bq bx ad @@ -1853,7 +1903,7 @@ ai bO au ac -aK +aL ad aN aX @@ -1871,10 +1921,10 @@ ac aj aq av -aA +aD aF ad -ay +bJ aC bb ac @@ -1930,7 +1980,7 @@ at ax ax aI -ad +bj aV bg be @@ -1946,8 +1996,8 @@ ac ac an bO -aH aB +aE aJ ad aS @@ -1967,7 +2017,7 @@ ao aq aP ac -aL +aM ad aN bH @@ -1982,11 +2032,11 @@ ab (10,1,1) = {" aa ac -wz -wz +ay +ay ad ad -bt +aO ad ad ad @@ -2005,9 +2055,9 @@ ba ba aa ac -bJ -ac aT +ac +bL ab aa ac diff --git a/maps/southern_cross/loadout/loadout_head.dm b/maps/southern_cross/loadout/loadout_head.dm index a25e22e2647..cbf7d63c26a 100644 --- a/maps/southern_cross/loadout/loadout_head.dm +++ b/maps/southern_cross/loadout/loadout_head.dm @@ -1,4 +1,4 @@ /datum/gear/head/pilot display_name = "helmet, pilot (Pilot)" - path = /obj/item/clothing/head/pilot/alt + path = /obj/item/clothing/head/ompilot/alt //VOREStation Edit allowed_roles = list("Pilot") diff --git a/maps/submaps/admin_use_vr/ert.dmm b/maps/submaps/admin_use_vr/ert.dmm index d00e0cb85ca..85fa6982413 100644 --- a/maps/submaps/admin_use_vr/ert.dmm +++ b/maps/submaps/admin_use_vr/ert.dmm @@ -4,7 +4,7 @@ /turf/space, /area/space) "ab" = ( -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "vonbraun_pd" }, /turf/simulated/floor/reinforced/airless, @@ -33,7 +33,7 @@ /turf/simulated/floor/reinforced/airless, /area/ship/ert/mech_bay) "ag" = ( -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "vonbraun_pd" }, /turf/simulated/floor/reinforced/airless, @@ -132,7 +132,7 @@ /turf/simulated/floor/reinforced, /area/shuttle/ert_ship_boat) "aC" = ( -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "vonbraun_pd" }, /turf/simulated/floor/reinforced/airless, @@ -191,7 +191,7 @@ /turf/simulated/floor/tiled/white, /area/ship/ert/med_surg) "aV" = ( -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "vonbraun_pd" }, /turf/simulated/floor/reinforced/airless, @@ -660,7 +660,7 @@ /obj/machinery/light/no_nightshift{ dir = 8 }, -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "vonbraun_pd" }, /turf/simulated/floor/reinforced/airless, @@ -1282,7 +1282,7 @@ /obj/effect/floor_decal/industrial/warning/corner{ dir = 1 }, -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "vonbraun_pd" }, /obj/machinery/light/no_nightshift{ @@ -1324,7 +1324,7 @@ /obj/effect/floor_decal/industrial/warning/corner{ dir = 8 }, -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "vonbraun_pd" }, /obj/machinery/light/no_nightshift{ @@ -3154,7 +3154,7 @@ /turf/simulated/floor/tiled/techfloor, /area/ship/ert/bridge) "sB" = ( -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "vonbraun_pd" }, /turf/simulated/floor/reinforced/airless, @@ -6597,7 +6597,7 @@ /turf/simulated/floor/tiled/techmaint, /area/shuttle/ert_ship_boat) "Nk" = ( -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "vonbraun_pd" }, /obj/machinery/light/no_nightshift{ @@ -6811,7 +6811,7 @@ /turf/simulated/floor/tiled/techmaint, /area/ship/ert/hangar) "Om" = ( -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "vonbraun_pd" }, /turf/simulated/floor/reinforced/airless, @@ -8078,7 +8078,7 @@ /turf/simulated/floor/tiled/techmaint, /area/ship/ert/hangar) "WF" = ( -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "vonbraun_pd" }, /turf/simulated/floor/reinforced/airless, @@ -8422,7 +8422,7 @@ /turf/simulated/floor/tiled/techfloor, /area/ship/ert/engineering) "ZL" = ( -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "vonbraun_pd" }, /turf/simulated/floor/reinforced/airless, diff --git a/maps/submaps/admin_use_vr/kk_mercship.dmm b/maps/submaps/admin_use_vr/kk_mercship.dmm index 70a2b26abb3..362023e72c4 100644 --- a/maps/submaps/admin_use_vr/kk_mercship.dmm +++ b/maps/submaps/admin_use_vr/kk_mercship.dmm @@ -563,7 +563,7 @@ /turf/simulated/floor/tiled/techfloor, /area/ship/manta/recreation) "bG" = ( -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "mercenary_pd" }, /turf/simulated/floor/reinforced/airless, @@ -635,7 +635,7 @@ /turf/simulated/floor/tiled/techfloor, /area/ship/manta/armoury_st) "bT" = ( -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "mercenary_pd" }, /turf/simulated/floor/reinforced/airless, @@ -826,7 +826,7 @@ /turf/simulated/floor/plating, /area/ship/manta/engine) "cI" = ( -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "mercenary_pd" }, /turf/simulated/floor/reinforced/airless, @@ -1766,7 +1766,7 @@ /turf/simulated/floor/tiled/techfloor, /area/ship/manta/bridge) "hq" = ( -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "mercenary_pd" }, /turf/simulated/floor/reinforced/airless, @@ -2296,7 +2296,7 @@ /turf/simulated/floor/tiled/techfloor, /area/ship/manta/bridge) "jh" = ( -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "mercenary_pd" }, /turf/simulated/floor/reinforced/airless, @@ -3229,7 +3229,7 @@ /turf/simulated/floor/plating, /area/ship/manta/engine) "nJ" = ( -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "mercenary_pd" }, /turf/simulated/floor/reinforced/airless, @@ -3590,7 +3590,7 @@ /turf/space, /area/space) "pi" = ( -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "mercenary_pd" }, /turf/simulated/floor/reinforced/airless, @@ -3868,7 +3868,7 @@ /turf/simulated/floor/tiled/techfloor, /area/ship/manta/hallways_aft) "qQ" = ( -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "mercenary_pd" }, /turf/simulated/floor/reinforced/airless, @@ -3932,7 +3932,7 @@ /turf/simulated/floor/reinforced/airless, /area/ship/manta/mech_bay) "rp" = ( -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "mercenary_pd" }, /turf/simulated/floor/reinforced/airless, @@ -4031,7 +4031,7 @@ /turf/simulated/floor/tiled/techfloor, /area/ship/manta/engineering) "rR" = ( -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "mercenary_pd" }, /turf/simulated/floor/reinforced/airless, @@ -4304,7 +4304,7 @@ /turf/simulated/floor/wood, /area/ship/manta/barracks) "ts" = ( -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "mercenary_pd" }, /turf/simulated/floor/reinforced/airless, @@ -7166,7 +7166,7 @@ /turf/simulated/floor/tiled/techmaint, /area/ship/manta/bridge) "FZ" = ( -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "mercenary_pd" }, /turf/simulated/floor/reinforced/airless, diff --git a/maps/submaps/depreciated_vr/talon.dm b/maps/submaps/depreciated_vr/talon.dm index 74281e86b8a..cd7d227f912 100644 --- a/maps/submaps/depreciated_vr/talon.dm +++ b/maps/submaps/depreciated_vr/talon.dm @@ -345,7 +345,7 @@ Once in open space, consider disabling nonessential power-consuming electronics starts_with = list( /obj/item/weapon/material/knife/tacknife/survival, - /obj/item/clothing/head/pilot, + /obj/item/clothing/head/ompilot, /obj/item/clothing/under/rank/pilot1, /obj/item/clothing/suit/storage/toggle/bomber/pilot, /obj/item/clothing/gloves/fingerless, diff --git a/maps/submaps/depreciated_vr/talon1.dmm b/maps/submaps/depreciated_vr/talon1.dmm index 63e1a10ff7d..b1112cb2a20 100644 --- a/maps/submaps/depreciated_vr/talon1.dmm +++ b/maps/submaps/depreciated_vr/talon1.dmm @@ -12,7 +12,7 @@ /obj/structure/cable/green{ icon_state = "0-4" }, -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "talon_pd" }, /turf/simulated/floor/hull/airless, @@ -2426,7 +2426,7 @@ /turf/simulated/floor/tiled/eris/dark/orangecorner, /area/space) "qo" = ( -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "talon_pd" }, /obj/effect/floor_decal/techfloor{ @@ -2673,7 +2673,7 @@ /turf/simulated/floor/tiled/eris/dark/cyancorner, /area/space) "uo" = ( -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "talon_pd" }, /obj/effect/floor_decal/techfloor{ @@ -3174,7 +3174,7 @@ /turf/space, /area/space) "AN" = ( -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "talon_pd" }, /obj/effect/floor_decal/techfloor{ @@ -4912,7 +4912,7 @@ /turf/simulated/floor/tiled/eris/techmaint_panels, /area/space) "UU" = ( -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "talon_pd" }, /obj/effect/floor_decal/techfloor{ diff --git a/maps/submaps/depreciated_vr/talon2.dmm b/maps/submaps/depreciated_vr/talon2.dmm index 45ff1dc5b48..837c88e29d1 100644 --- a/maps/submaps/depreciated_vr/talon2.dmm +++ b/maps/submaps/depreciated_vr/talon2.dmm @@ -2095,7 +2095,7 @@ /obj/structure/cable/green{ icon_state = "0-2" }, -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "talon_pd" }, /obj/effect/floor_decal/techfloor{ @@ -2704,7 +2704,7 @@ /turf/simulated/floor/tiled/eris/steel, /area/space) "CB" = ( -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "talon_pd" }, /obj/structure/cable/green{ @@ -3613,7 +3613,7 @@ /turf/simulated/floor/hull/airless, /area/space) "RA" = ( -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "talon_pd" }, /obj/effect/floor_decal/techfloor{ @@ -3655,7 +3655,7 @@ /turf/simulated/floor/tiled/eris/techmaint_panels, /area/space) "Sb" = ( -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ id_tag = "talon_pd" }, /obj/structure/cable/green{ diff --git a/maps/submaps/pois_vr/debris_field/debris8.dmm b/maps/submaps/pois_vr/debris_field/debris8.dmm index f574d2e8b69..7e21a82345a 100644 --- a/maps/submaps/pois_vr/debris_field/debris8.dmm +++ b/maps/submaps/pois_vr/debris_field/debris8.dmm @@ -9,7 +9,7 @@ /turf/simulated/floor/hull/airless, /area/tether_away/debrisfield/shuttle_buffer) "d" = ( -/obj/machinery/pointdefense{ +/obj/machinery/power/pointdefense{ dir = 4 }, /turf/simulated/floor/hull/airless, diff --git a/maps/submaps/surface_submaps/mountains/mountains.dm b/maps/submaps/surface_submaps/mountains/mountains.dm index a7ac3cc3bb4..2fffd44a723 100644 --- a/maps/submaps/surface_submaps/mountains/mountains.dm +++ b/maps/submaps/surface_submaps/mountains/mountains.dm @@ -41,6 +41,7 @@ #include "Cliff1.dmm" #include "excavation1.dmm" #include "spatial_anomaly.dmm" +#include "speakeasy_vr.dmm" #endif // The 'mountains' is the mining z-level, and has a lot of caves. @@ -235,7 +236,7 @@ cost = 5 allow_duplicates = TRUE template_group = "Underground Cliffs" - + /datum/map_template/surface/mountains/normal/deadly_rabbit // VOREStation Edit name = "The Killer Rabbit" desc = "A cave where the Knights of the Round have fallen to a murderous Rabbit." @@ -363,3 +364,11 @@ mappath = 'maps/submaps/surface_submaps/mountains/spatial_anomaly.dmm' cost = 20 fixed_orientation = TRUE + +/datum/map_template/surface/mountains/normal/Speakeasy //VOREStation add + name = "Speakeasy" + desc = "A hidden underground bar to serve drinks in secret and in style." + mappath = 'maps/submaps/surface_submaps/mountains/speakeasy_vr.dmm' + cost = 10 + allow_duplicates = FALSE + diff --git a/maps/submaps/surface_submaps/mountains/mountains_areas.dm b/maps/submaps/surface_submaps/mountains/mountains_areas.dm index d39e38823b4..4078c4b988c 100644 --- a/maps/submaps/surface_submaps/mountains/mountains_areas.dm +++ b/maps/submaps/surface_submaps/mountains/mountains_areas.dm @@ -163,3 +163,7 @@ /area/submap/spatial_anomaly name = "POI - Spatial Anomaly" ambience = AMBIENCE_FOREBODING + +/area/submap/Speakeasy //VOREStation add + name = "POI - Speakeasy" + requires_power = FALSE \ No newline at end of file diff --git a/maps/submaps/surface_submaps/mountains/speakeasy_vr.dmm b/maps/submaps/surface_submaps/mountains/speakeasy_vr.dmm new file mode 100644 index 00000000000..6d6cc6cdbb1 --- /dev/null +++ b/maps/submaps/surface_submaps/mountains/speakeasy_vr.dmm @@ -0,0 +1,54 @@ +"a" = (/turf/template_noop,/area/submap/Speakeasy) +"c" = (/turf/simulated/floor/carpet/turcarpet,/area/submap/Speakeasy) +"f" = (/obj/structure/table/gamblingtable,/turf/simulated/floor/wood,/area/submap/Speakeasy) +"g" = (/obj/structure/bed/chair/wood{dir = 1},/turf/simulated/floor/wood,/area/submap/Speakeasy) +"h" = (/obj/random/handgun,/turf/simulated/floor/wood,/area/submap/Speakeasy) +"i" = (/obj/item/clothing/head/fedora,/turf/simulated/floor/wood,/area/submap/Speakeasy) +"j" = (/obj/structure/bookcase,/turf/simulated/floor/wood,/area/submap/Speakeasy) +"k" = (/obj/item/weapon/stool/padded,/turf/simulated/floor/wood,/area/submap/Speakeasy) +"l" = (/obj/structure/bed/chair/comfy/black,/turf/simulated/floor/carpet/turcarpet,/area/submap/Speakeasy) +"m" = (/obj/structure/table/woodentable,/obj/machinery/light/poi{dir = 4},/turf/simulated/floor/wood,/area/submap/Speakeasy) +"n" = (/obj/structure/reagent_dispensers/beerkeg,/turf/simulated/floor/wood,/area/submap/Speakeasy) +"o" = (/obj/structure/simple_door/wood,/turf/simulated/floor/wood,/area/submap/Speakeasy) +"p" = (/obj/machinery/media/jukebox,/turf/simulated/floor/wood,/area/submap/Speakeasy) +"s" = (/obj/structure/bed/chair/wood{dir = 4},/turf/simulated/floor/wood,/area/submap/Speakeasy) +"u" = (/obj/structure/table/gamblingtable,/obj/machinery/light/poi{dir = 4},/turf/simulated/floor/wood,/area/submap/Speakeasy) +"v" = (/obj/structure/table/fancyblack,/obj/item/clothing/mask/smokable/cigarette/cigar,/turf/simulated/floor/carpet/turcarpet,/area/submap/Speakeasy) +"w" = (/turf/simulated/wall/wood,/area/submap/Speakeasy) +"x" = (/obj/structure/bed/chair/sofa/blue/left{dir = 4},/turf/simulated/floor/wood,/area/submap/Speakeasy) +"B" = (/turf/simulated/floor/wood,/area/submap/Speakeasy) +"C" = (/turf/simulated/mineral/floor/cave,/area/submap/Speakeasy) +"D" = (/obj/structure/bed/chair/sofa/black/corner{dir = 4},/turf/simulated/floor/wood,/area/submap/Speakeasy) +"E" = (/obj/structure/bed/chair/comfy/black{dir = 1},/turf/simulated/floor/carpet/turcarpet,/area/submap/Speakeasy) +"H" = (/obj/machinery/vending/boozeomat,/turf/simulated/floor/wood,/area/submap/Speakeasy) +"I" = (/obj/structure/table/woodentable,/obj/random/drinkbottle,/turf/simulated/floor/wood,/area/submap/Speakeasy) +"K" = (/obj/effect/floor_decal/corner/black/diagonal,/turf/simulated/floor/tiled/neutral,/area/submap/Speakeasy) +"L" = (/obj/structure/bed/chair/wood{dir = 8},/turf/simulated/floor/wood,/area/submap/Speakeasy) +"M" = (/obj/machinery/light/poi{dir = 1},/turf/simulated/floor/carpet/turcarpet,/area/submap/Speakeasy) +"N" = (/obj/structure/table/woodentable,/turf/simulated/floor/wood,/area/submap/Speakeasy) +"O" = (/obj/machinery/light/poi{dir = 1},/turf/simulated/floor/wood,/area/submap/Speakeasy) +"R" = (/obj/structure/bed/chair/sofa/black{dir = 1},/turf/simulated/floor/wood,/area/submap/Speakeasy) +"U" = (/obj/structure/bed/chair/sofa/blue/right{dir = 1},/turf/simulated/floor/wood,/area/submap/Speakeasy) +"V" = (/obj/structure/table/woodentable,/obj/machinery/chemical_dispenser/bar_soft/full{dir = 1},/turf/simulated/floor/wood,/area/submap/Speakeasy) +"W" = (/obj/structure/bed/chair/wood,/turf/simulated/floor/wood,/area/submap/Speakeasy) +"X" = (/obj/structure/table/woodentable,/obj/machinery/chemical_dispenser/bar_alc/full,/turf/simulated/floor/wood,/area/submap/Speakeasy) +"Y" = (/obj/structure/table/fancyblack,/obj/random/cash/big,/turf/simulated/floor/carpet/turcarpet,/area/submap/Speakeasy) + +(1,1,1) = {" +aaaaaaaaaaaaaaaa +awwwwwwwwwwaaaaa +awnnwBMlMBwwwwaa +awiBjBYvYBwfLwwa +awhBjBcEcBwgBBwa +awwwwBBBBBwBWWwa +awXHwwwowwwBNmwa +awBBBOBBBBBBNNwa +awVNININNIBBggwa +awBkkkkkkkBBBBwa +awpBBBBBBBKKKWwa +awwxffBBBBKKKuwa +aawDRUBBBBKKKgwa +aawwwwBBBBsfLwwa +aaaaawwowwwwwwaa +aaaaaaCCCaaaaaaa +"} diff --git a/maps/tether/tether-01-surface1.dmm b/maps/tether/tether-01-surface1.dmm index 467f3c358a5..a92a06dc5aa 100644 --- a/maps/tether/tether-01-surface1.dmm +++ b/maps/tether/tether-01-surface1.dmm @@ -12223,6 +12223,13 @@ /obj/structure/stairs/spawner/west, /turf/simulated/floor/outdoors/grass/sif/virgo3b, /area/tether/surfacebase/outside/outside1) +"auJ" = ( +/obj/machinery/door/airlock{ + name = "Surface Brig Restroom" + }, +/obj/machinery/door/firedoor, +/turf/simulated/floor/tiled/freezer, +/area/tether/surfacebase/security/brig/bathroom) "auK" = ( /turf/simulated/wall, /area/maintenance/lower/solars) @@ -12340,6 +12347,15 @@ }, /turf/simulated/floor/tiled/techmaint, /area/rnd/external) +"auX" = ( +/obj/structure/toilet{ + dir = 1 + }, +/obj/machinery/light/small{ + dir = 4 + }, +/turf/simulated/floor/tiled/freezer, +/area/tether/surfacebase/security/brig/bathroom) "auY" = ( /obj/structure/cable/green{ d1 = 1; @@ -12424,6 +12440,20 @@ }, /turf/simulated/floor/plating, /area/maintenance/lower/solars) +"ave" = ( +/obj/machinery/door/firedoor/glass, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/door/airlock{ + id_tag = "bathroomlock7"; + name = "Room 8 Restroom" + }, +/turf/simulated/floor/wood, +/area/crew_quarters/sleep/Dorm_8) "avf" = ( /obj/machinery/light/small{ dir = 1 @@ -12975,6 +13005,21 @@ /obj/structure/railing, /turf/simulated/floor/plating, /area/maintenance/lower/solars) +"avN" = ( +/obj/machinery/atmospherics/unary/vent_pump/on{ + dir = 1 + }, +/obj/random/soap, +/obj/structure/table/standard, +/obj/machinery/button/remote/airlock{ + id = "bathroomlock7"; + name = "Room 8 Bathroom Lock"; + pixel_x = -20; + pixel_y = 10; + specialfunctions = 4 + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/sleep/Dorm_8) "avO" = ( /obj/machinery/door/airlock/maintenance/common, /obj/machinery/door/firedoor/glass, @@ -13173,6 +13218,20 @@ /obj/structure/disposalpipe/segment, /turf/simulated/floor/tiled, /area/tether/surfacebase/tram) +"awk" = ( +/obj/machinery/door/firedoor/glass, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/door/airlock{ + id_tag = "bathroomlock6"; + name = "Room 6 Restroom" + }, +/turf/simulated/floor/wood, +/area/crew_quarters/sleep/Dorm_6) "awl" = ( /obj/effect/floor_decal/borderfloor{ dir = 8 @@ -15232,6 +15291,21 @@ }, /turf/simulated/floor/tiled/white, /area/medical/virologyisolation) +"ayY" = ( +/obj/machinery/atmospherics/unary/vent_pump/on{ + dir = 1 + }, +/obj/random/soap, +/obj/structure/table/standard, +/obj/machinery/button/remote/airlock{ + id = "bathroomlock6"; + name = "Room 6 Bathroom Lock"; + pixel_x = -20; + pixel_y = 10; + specialfunctions = 4 + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/sleep/Dorm_6) "ayZ" = ( /obj/effect/floor_decal/borderfloorwhite{ dir = 8 @@ -15468,6 +15542,20 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/tram) +"azr" = ( +/obj/machinery/door/firedoor/glass, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/door/airlock{ + id_tag = "bathroomlock5"; + name = "Room 4 Restroom" + }, +/turf/simulated/floor/wood, +/area/crew_quarters/sleep/Dorm_4) "azs" = ( /turf/simulated/wall/r_wall, /area/maintenance/lower/solars) @@ -15637,6 +15725,21 @@ }, /turf/simulated/floor/tiled/white, /area/tether/surfacebase/medical/centralstairwell) +"azF" = ( +/obj/machinery/atmospherics/unary/vent_pump/on{ + dir = 1 + }, +/obj/random/soap, +/obj/structure/table/standard, +/obj/machinery/button/remote/airlock{ + id = "bathroomlock5"; + name = "Room 4 Bathroom Lock"; + pixel_x = -20; + pixel_y = 10; + specialfunctions = 4 + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/sleep/Dorm_4) "azG" = ( /obj/structure/sign/securearea{ desc = "A warning sign which reads 'CRUSH WARNING'."; @@ -17987,6 +18090,20 @@ /obj/effect/floor_decal/steeldecal/steel_decals9, /turf/simulated/floor/tiled/monotile, /area/rnd/hallway) +"aDL" = ( +/obj/machinery/door/firedoor/glass, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/door/airlock{ + id_tag = "bathroomlock4"; + name = "Room 2 Restroom" + }, +/turf/simulated/floor/wood, +/area/crew_quarters/sleep/Dorm_2) "aDM" = ( /obj/structure/ladder/up, /obj/effect/floor_decal/industrial/outline/yellow, @@ -19227,6 +19344,21 @@ /obj/structure/railing, /turf/simulated/floor/tiled/techfloor/grid, /area/tether/surfacebase/tram) +"aFV" = ( +/obj/machinery/atmospherics/unary/vent_pump/on{ + dir = 1 + }, +/obj/random/soap, +/obj/structure/table/standard, +/obj/machinery/button/remote/airlock{ + id = "bathroomlock4"; + name = "Room 2 Bathroom Lock"; + pixel_x = -20; + pixel_y = 10; + specialfunctions = 4 + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/sleep/Dorm_2) "aFW" = ( /obj/structure/bed/chair/wood{ dir = 1 @@ -19596,6 +19728,20 @@ }, /turf/simulated/floor/tiled, /area/crew_quarters/visitor_dining) +"aGz" = ( +/obj/machinery/door/firedoor/glass, +/obj/machinery/door/airlock{ + id_tag = "bathroomlock1"; + name = "Dark Bar Restroom" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/turf/simulated/floor/plating, +/area/vacant/vacant_bar) "aGA" = ( /obj/machinery/firealarm{ dir = 1; @@ -21389,12 +21535,19 @@ /turf/simulated/floor/tiled, /area/tether/surfacebase/lowernorthhall) "aJD" = ( -/obj/machinery/atmospherics/unary/vent_pump/on{ - dir = 1 +/obj/machinery/door/firedoor/glass, +/obj/machinery/door/airlock{ + id_tag = "bathroomlock2"; + name = "Room 3 Restroom" }, -/obj/machinery/light_construct/small, -/turf/simulated/floor/plating, -/area/crew_quarters/sleep/maintDorm1) +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/sleep/maintDorm3) "aJE" = ( /obj/machinery/atmospherics/unary/vent_pump/on, /turf/simulated/floor/wood, @@ -21800,6 +21953,20 @@ }, /turf/simulated/floor/tiled, /area/engineering/atmos) +"aKq" = ( +/obj/machinery/door/firedoor/glass, +/obj/machinery/door/airlock{ + id_tag = "bathroomlock3"; + name = "Room 1 Restroom" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/turf/simulated/floor/plating, +/area/crew_quarters/sleep/maintDorm1) "aKr" = ( /obj/structure/railing, /obj/effect/floor_decal/borderfloor{ @@ -21874,6 +22041,20 @@ /obj/item/weapon/beach_ball/holoball, /turf/simulated/floor/plating, /area/maintenance/lower/research) +"aKA" = ( +/obj/machinery/atmospherics/unary/vent_pump/on{ + dir = 1 + }, +/obj/machinery/light/small, +/obj/machinery/button/remote/airlock{ + id = "bathroomlock1"; + name = "Dark Bar Bathroom Lock"; + pixel_x = -20; + pixel_y = 10; + specialfunctions = 4 + }, +/turf/simulated/floor/tiled/white, +/area/vacant/vacant_bar) "aKB" = ( /obj/structure/railing{ dir = 8 @@ -23032,18 +23213,20 @@ /turf/simulated/floor/wood, /area/crew_quarters/sleep/Dorm_8) "aMG" = ( -/obj/machinery/door/firedoor/glass, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 +/obj/effect/floor_decal/rust, +/obj/machinery/atmospherics/unary/vent_pump/on{ + dir = 1 }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 +/obj/machinery/light_construct/small, +/obj/machinery/button/remote/airlock{ + id = "bathroomlock2"; + name = "Room 3 Bathroom Lock"; + pixel_x = -20; + pixel_y = 10; + specialfunctions = 4 }, -/obj/machinery/door/airlock{ - name = "Restroom" - }, -/turf/simulated/floor/wood, -/area/crew_quarters/sleep/Dorm_8) +/turf/simulated/floor/tiled/white, +/area/crew_quarters/sleep/maintDorm3) "aMH" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 @@ -23470,10 +23653,16 @@ /obj/machinery/atmospherics/unary/vent_pump/on{ dir = 1 }, -/obj/random/soap, -/obj/structure/table/standard, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/sleep/Dorm_8) +/obj/machinery/light_construct/small, +/obj/machinery/button/remote/airlock{ + id = "bathroomlock3"; + name = "Room 1 Bathroom Lock"; + pixel_x = -20; + pixel_y = 10; + specialfunctions = 4 + }, +/turf/simulated/floor/plating, +/area/crew_quarters/sleep/maintDorm1) "aNu" = ( /obj/machinery/shower{ dir = 1 @@ -24175,18 +24364,12 @@ /turf/simulated/floor/wood, /area/crew_quarters/sleep/Dorm_6) "aOO" = ( -/obj/machinery/door/firedoor/glass, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 +/obj/machinery/flasher{ + id = "SurfaceBrigFlash"; + pixel_y = -20 }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/machinery/door/airlock{ - name = "Restroom" - }, -/turf/simulated/floor/wood, -/area/crew_quarters/sleep/Dorm_6) +/turf/simulated/floor/tiled/dark, +/area/tether/surfacebase/security/brig) "aOP" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 @@ -24494,13 +24677,29 @@ /turf/simulated/floor/wood, /area/crew_quarters/sleep/Dorm_6) "aPj" = ( -/obj/machinery/atmospherics/unary/vent_pump/on{ - dir = 1 +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" }, -/obj/random/soap, -/obj/structure/table/standard, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/sleep/Dorm_6) +/obj/structure/cable/green{ + d1 = 2; + d2 = 4; + icon_state = "2-4" + }, +/obj/effect/floor_decal/corner/lightorange{ + dir = 5 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 6 + }, +/obj/machinery/flasher{ + id = "SurfaceBrigFlash" + }, +/obj/effect/floor_decal/industrial/outline/yellow, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/security/brig) "aPk" = ( /obj/machinery/shower{ dir = 1 @@ -25360,18 +25559,20 @@ /turf/simulated/floor/wood, /area/crew_quarters/sleep/Dorm_4) "aQO" = ( -/obj/machinery/door/firedoor/glass, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" }, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, -/obj/machinery/door/airlock{ - name = "Restroom" +/obj/machinery/flasher{ + id = "SurfaceBrigFlash" }, -/turf/simulated/floor/wood, -/area/crew_quarters/sleep/Dorm_4) +/obj/effect/floor_decal/industrial/outline/yellow, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/security/brig) "aQP" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 @@ -25680,13 +25881,19 @@ /turf/simulated/floor/wood, /area/crew_quarters/sleep/Dorm_4) "aRs" = ( -/obj/machinery/atmospherics/unary/vent_pump/on{ - dir = 1 +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" }, -/obj/random/soap, -/obj/structure/table/standard, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/sleep/Dorm_4) +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/flasher{ + id = "SurfaceBrigFlash" + }, +/obj/effect/floor_decal/industrial/outline/yellow, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/security/brig) "aRt" = ( /obj/machinery/shower{ dir = 1 @@ -26407,18 +26614,12 @@ /turf/simulated/floor/wood, /area/crew_quarters/sleep/Dorm_2) "aSZ" = ( -/obj/machinery/door/firedoor/glass, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 +/obj/machinery/flasher{ + id = "SurfaceBrigFlash" }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/machinery/door/airlock{ - name = "Restroom" - }, -/turf/simulated/floor/wood, -/area/crew_quarters/sleep/Dorm_2) +/obj/effect/floor_decal/industrial/outline/yellow, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/security/brig) "aTa" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 @@ -26758,13 +26959,18 @@ /turf/simulated/floor/wood, /area/crew_quarters/sleep/Dorm_2) "aTH" = ( -/obj/machinery/atmospherics/unary/vent_pump/on{ +/obj/effect/floor_decal/steeldecal/steel_decals4{ dir = 1 }, -/obj/random/soap, -/obj/structure/table/standard, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/sleep/Dorm_2) +/obj/effect/floor_decal/steeldecal/steel_decals4{ + dir = 6 + }, +/obj/machinery/button/flasher{ + id = "SurfaceVisitFlash"; + pixel_y = -20 + }, +/turf/simulated/floor/tiled/dark, +/area/tether/surfacebase/security/brig) "aTI" = ( /obj/machinery/shower{ dir = 1 @@ -28263,6 +28469,17 @@ }, /turf/simulated/floor/tiled, /area/crew_quarters/visitor_laundry) +"aWp" = ( +/obj/effect/floor_decal/steeldecal/steel_decals4, +/obj/effect/floor_decal/steeldecal/steel_decals4{ + dir = 10 + }, +/obj/machinery/flasher{ + id = "SurfaceVisitFlash"; + pixel_y = -20 + }, +/turf/simulated/floor/tiled/dark, +/area/tether/surfacebase/security/brig) "aWq" = ( /obj/machinery/atmospherics/pipe/simple/visible/yellow{ dir = 4 @@ -28711,6 +28928,92 @@ /obj/random/junk, /turf/simulated/floor/wood, /area/crew_quarters/sleep/maintDorm2) +"aXo" = ( +/obj/machinery/button/remote/airlock{ + id = "brigouter"; + name = "Outer Brig Doors"; + pixel_x = 24; + pixel_y = -4; + req_access = list(2) + }, +/obj/machinery/button/remote/airlock{ + id = "briginner"; + name = "Inner Brig Doors"; + pixel_x = 34; + pixel_y = -4; + req_access = list(2) + }, +/obj/effect/floor_decal/borderfloor{ + dir = 4 + }, +/obj/effect/floor_decal/borderfloor/corner2{ + dir = 6 + }, +/obj/effect/floor_decal/borderfloor/corner2{ + dir = 5 + }, +/obj/effect/floor_decal/corner/lightorange/bordercorner2{ + dir = 5 + }, +/obj/effect/floor_decal/corner/lightorange/bordercorner2{ + dir = 6 + }, +/obj/machinery/button/flasher{ + id = "SurfaceBrigFlash"; + pixel_x = 30; + pixel_y = 5 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/security/lowerhall) +"aXp" = ( +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/green{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/effect/floor_decal/steeldecal/steel_decals6{ + dir = 9 + }, +/obj/machinery/flasher{ + id = "SurfaceBrigFlash" + }, +/obj/effect/floor_decal/industrial/outline/yellow, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/security/brig) +"aXq" = ( +/obj/structure/cable/green{ + icon_state = "1-8" + }, +/obj/structure/cable/green{ + d1 = 2; + d2 = 8; + icon_state = "2-8" + }, +/obj/effect/floor_decal/corner/lightorange{ + dir = 6 + }, +/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/manifold/hidden/supply, +/obj/machinery/flasher{ + id = "SurfaceBrigFlash" + }, +/obj/effect/floor_decal/industrial/outline/yellow, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/security/brig) "aXr" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -29194,19 +29497,6 @@ }, /turf/simulated/floor/wood, /area/vacant/vacant_bar) -"aYM" = ( -/obj/machinery/door/firedoor/glass, -/obj/machinery/door/airlock{ - name = "Restroom" - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/turf/simulated/floor/plating, -/area/vacant/vacant_bar) "aYN" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 @@ -29226,19 +29516,6 @@ }, /turf/simulated/floor/tiled/white, /area/vacant/vacant_bar) -"aYR" = ( -/obj/machinery/door/firedoor/glass, -/obj/machinery/door/airlock{ - name = "Restroom" - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/sleep/maintDorm3) "aYT" = ( /obj/machinery/atmospherics/unary/vent_scrubber/on{ dir = 8 @@ -29259,19 +29536,6 @@ }, /turf/simulated/floor/tiled/white, /area/crew_quarters/sleep/maintDorm2) -"aZb" = ( -/obj/machinery/door/firedoor/glass, -/obj/machinery/door/airlock{ - name = "Restroom" - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/turf/simulated/floor/plating, -/area/crew_quarters/sleep/maintDorm1) "aZc" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 @@ -29296,13 +29560,6 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/lowernorthhall) -"aZh" = ( -/obj/machinery/atmospherics/unary/vent_pump/on{ - dir = 1 - }, -/obj/machinery/light/small, -/turf/simulated/floor/tiled/white, -/area/vacant/vacant_bar) "aZi" = ( /obj/machinery/shower{ dir = 1 @@ -29331,14 +29588,6 @@ }, /turf/simulated/floor/plating, /area/crew_quarters/sleep/maintDorm3) -"aZl" = ( -/obj/effect/floor_decal/rust, -/obj/machinery/atmospherics/unary/vent_pump/on{ - dir = 1 - }, -/obj/machinery/light_construct/small, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/sleep/maintDorm3) "aZm" = ( /obj/machinery/shower{ dir = 1 @@ -31547,15 +31796,6 @@ "cGJ" = ( /turf/simulated/floor/plating, /area/maintenance/lower/mining_eva) -"cGU" = ( -/obj/effect/floor_decal/steeldecal/steel_decals4{ - dir = 1 - }, -/obj/effect/floor_decal/steeldecal/steel_decals4{ - dir = 6 - }, -/turf/simulated/floor/tiled/dark, -/area/tether/surfacebase/security/brig) "cHW" = ( /obj/effect/floor_decal/steeldecal/steel_decals6{ dir = 10 @@ -32300,13 +32540,6 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/security/brig) -"fvH" = ( -/obj/machinery/door/airlock{ - name = "Brig Restroom" - }, -/obj/machinery/door/firedoor, -/turf/simulated/floor/tiled/freezer, -/area/tether/surfacebase/security/brig/bathroom) "fvL" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, @@ -32940,13 +33173,6 @@ }, /turf/simulated/floor/tiled, /area/crew_quarters/locker/laundry_arrival) -"hzx" = ( -/obj/effect/floor_decal/steeldecal/steel_decals4, -/obj/effect/floor_decal/steeldecal/steel_decals4{ - dir = 10 - }, -/turf/simulated/floor/tiled/dark, -/area/tether/surfacebase/security/brig) "hAe" = ( /turf/simulated/floor/looking_glass{ dir = 5 @@ -34940,29 +35166,6 @@ /obj/structure/closet/crate/bin, /turf/simulated/floor/carpet/bcarpet, /area/tether/surfacebase/funny/mimeoffice) -"nmf" = ( -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/simple/hidden/green{ - dir = 4 - }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/effect/floor_decal/steeldecal/steel_decals6{ - dir = 9 - }, -/turf/simulated/floor/tiled, -/area/tether/surfacebase/security/brig) "nmA" = ( /obj/machinery/door/airlock/silver{ name = "Mime's Office"; @@ -36168,26 +36371,6 @@ }, /turf/simulated/floor/plating, /area/tether/surfacebase/funny/hideyhole) -"rzZ" = ( -/obj/structure/cable/green{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, -/obj/structure/cable/green{ - d1 = 2; - d2 = 4; - icon_state = "2-4" - }, -/obj/effect/floor_decal/corner/lightorange{ - dir = 5 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 6 - }, -/turf/simulated/floor/tiled, -/area/tether/surfacebase/security/brig) "rBG" = ( /obj/structure/closet, /obj/item/weapon/material/minihoe, @@ -37013,15 +37196,6 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/security/brig) -"uAv" = ( -/obj/structure/toilet{ - dir = 1 - }, -/obj/machinery/light/small{ - dir = 4 - }, -/turf/simulated/floor/tiled/freezer, -/area/tether/surfacebase/security/brig/bathroom) "uAA" = ( /obj/effect/floor_decal/borderfloor/corner, /obj/effect/floor_decal/corner/mauve/bordercorner, @@ -37033,38 +37207,6 @@ }, /turf/simulated/floor/tiled, /area/rnd/hallway) -"uDQ" = ( -/obj/machinery/button/remote/airlock{ - id = "brigouter"; - name = "Outer Brig Doors"; - pixel_x = 24; - pixel_y = -4; - req_access = list(2) - }, -/obj/machinery/button/remote/airlock{ - id = "briginner"; - name = "Inner Brig Doors"; - pixel_x = 34; - pixel_y = -4; - req_access = list(2) - }, -/obj/effect/floor_decal/borderfloor{ - dir = 4 - }, -/obj/effect/floor_decal/borderfloor/corner2{ - dir = 6 - }, -/obj/effect/floor_decal/borderfloor/corner2{ - dir = 5 - }, -/obj/effect/floor_decal/corner/lightorange/bordercorner2{ - dir = 5 - }, -/obj/effect/floor_decal/corner/lightorange/bordercorner2{ - dir = 6 - }, -/turf/simulated/floor/tiled, -/area/tether/surfacebase/security/lowerhall) "uEK" = ( /obj/effect/floor_decal/borderfloor, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ @@ -37553,24 +37695,6 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_one_hall) -"wxV" = ( -/obj/structure/cable/green{ - icon_state = "1-8" - }, -/obj/structure/cable/green{ - d1 = 2; - d2 = 8; - icon_state = "2-8" - }, -/obj/effect/floor_decal/corner/lightorange{ - dir = 6 - }, -/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/manifold/hidden/supply, -/turf/simulated/floor/tiled, -/area/tether/surfacebase/security/brig) "wzA" = ( /obj/structure/catwalk, /obj/machinery/alarm{ @@ -45859,7 +45983,7 @@ vRL hFq neZ diq -uDQ +aXo mvM fLB dMu @@ -46142,9 +46266,9 @@ tiJ kmb pCj kUN -cGU +aTH qwV -nmf +aXp hMu abT bbd @@ -46420,13 +46544,13 @@ wwm jio pCj dju -kmb +aOO pCj dju -kmb +aOO pCj jzW -hzx +aWp qwV wtD wQS @@ -46846,15 +46970,15 @@ aad mYf rQe ybc -rzZ -hTw +aPj hTw hTw hTw +aRs hTw uFs ddU -wxV +aXq nID iKy anp @@ -47414,11 +47538,11 @@ aad pCj wjq wjq -pKE +aQO pmV loj plW -tdh +aSZ fqa fOy eAd @@ -47706,8 +47830,8 @@ eBd fqa fOy xtS -fvH -uAv +auJ +auX fqa anp adK @@ -50058,7 +50182,7 @@ aXm aXI aYd aYd -aYM +aGz aYd aYd aLL @@ -50201,7 +50325,7 @@ aXJ aYd aYr aYN -aZh +aKA aYd aZI aWc @@ -50910,7 +51034,7 @@ aXr aXP aYe aYe -aYR +aJD aYe aYe aZL @@ -51053,7 +51177,7 @@ aXJ aYe aYv aIg -aZl +aMG aYe aUE aZz @@ -52614,7 +52738,7 @@ aXP aXP aYi aYi -aZb +aKq aYi aYi aZS @@ -52757,7 +52881,7 @@ aVn aYi aHX aZc -aJD +aNt aYi aZD aZD @@ -53581,19 +53705,19 @@ aCP aDu aLj aLj -aMG +ave aLj aNS aNS -aOO +awk aNS aPK aPK -aQO +azr aPK aPK aSo -aSZ +aDL aSo aSo arD @@ -53724,19 +53848,19 @@ aDu aLj aLW aMH -aNt +avN aNS aOu aOP -aPj +ayY aPK aQm aQP -aRs +azF aPK aSu aTa -aTH +aFV aSo aTB bcm diff --git a/maps/tether/tether-02-surface2.dmm b/maps/tether/tether-02-surface2.dmm index dbddf78a12f..2fcfdb93229 100644 --- a/maps/tether/tether-02-surface2.dmm +++ b/maps/tether/tether-02-surface2.dmm @@ -5531,7 +5531,8 @@ /area/maintenance/lower/public_garden_maintenence/upper) "aiF" = ( /obj/machinery/door/airlock{ - name = "Restroom" + id_tag = "bathroomlock12"; + name = "Surface Recovery Toilet 1" }, /obj/machinery/door/firedoor/glass, /turf/simulated/floor/tiled/white, @@ -5588,6 +5589,13 @@ /obj/machinery/light/small{ dir = 1 }, +/obj/machinery/button/remote/airlock{ + id = "bathroomlock12"; + name = "Surface Recovery Toilet 1 Lock"; + pixel_x = -10; + pixel_y = 22; + specialfunctions = 4 + }, /turf/simulated/floor/tiled/white, /area/tether/surfacebase/medical/recoveryward) "aiJ" = ( @@ -6173,15 +6181,10 @@ /area/tether/surfacebase/medical/recoveryward) "ajC" = ( /obj/machinery/door/airlock{ - name = "Restroom" - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 + id_tag = "bathroomlock13"; + name = "Surface Recovery Toilet 2" }, /obj/machinery/door/firedoor/glass, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, /turf/simulated/floor/tiled/white, /area/tether/surfacebase/medical/recoveryward) "ajD" = ( @@ -6802,12 +6805,21 @@ /turf/simulated/floor/tiled/white, /area/tether/surfacebase/medical/uppersouthstairwell) "akH" = ( -/obj/machinery/door/airlock{ - name = "Restroom" +/obj/structure/toilet{ + dir = 8 + }, +/obj/machinery/light/small{ + dir = 1 + }, +/obj/machinery/button/remote/airlock{ + id = "bathroomlock13"; + name = "Surface Recovery Toilet 2 Lock"; + pixel_x = -10; + pixel_y = 22; + specialfunctions = 4 }, -/obj/machinery/door/firedoor/glass, /turf/simulated/floor/tiled/white, -/area/tether/surfacebase/medical/uppersouthstairwell) +/area/tether/surfacebase/medical/recoveryward) "akI" = ( /obj/effect/floor_decal/steeldecal/steel_decals4{ dir = 6 @@ -7592,7 +7604,8 @@ /area/tether/surfacebase/medical/uppersouthstairwell) "alS" = ( /obj/machinery/door/airlock{ - name = "Restroom" + id_tag = "bathroomlock10"; + name = "Surface Toilet 1" }, /obj/machinery/door/firedoor/glass, /turf/simulated/floor/tiled/white, @@ -7604,6 +7617,13 @@ /obj/machinery/light/small{ dir = 4 }, +/obj/machinery/button/remote/airlock{ + id = "bathroomlock10"; + name = "Surface Medbay Toilet 1 Lock"; + pixel_x = -10; + pixel_y = 22; + specialfunctions = 4 + }, /turf/simulated/floor/tiled/white, /area/tether/surfacebase/medical/bathroom) "alU" = ( @@ -10926,15 +10946,19 @@ /turf/simulated/floor/tiled/white, /area/tether/surfacebase/security/brig/bathroom) "ary" = ( -/obj/structure/toilet, -/obj/effect/landmark/start{ - name = "Security Officer" +/obj/machinery/door/airlock{ + id_tag = "bathroomlock7"; + name = "Restroom" }, -/obj/machinery/light/small{ +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/door/firedoor/glass, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, /turf/simulated/floor/tiled/white, -/area/tether/surfacebase/security/brig/bathroom) +/area/tether/surfacebase/medical/recoveryward) "arz" = ( /obj/machinery/atmospherics/pipe/manifold/hidden/supply{ dir = 4 @@ -24228,6 +24252,14 @@ }, /turf/simulated/floor/tiled/techfloor, /area/maintenance/lower/south) +"aRe" = ( +/obj/machinery/door/airlock{ + id_tag = "bathroomlock7"; + name = "Restroom" + }, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor/tiled/white, +/area/tether/surfacebase/medical/recoveryward) "aRf" = ( /obj/effect/floor_decal/rust, /obj/random/drinkbottle, @@ -24794,6 +24826,14 @@ /obj/machinery/shieldgen, /turf/simulated/floor/plating, /area/engineering/atmos/storage) +"aSg" = ( +/obj/machinery/door/airlock{ + id_tag = "bathroomlock11"; + name = "Surface Medbay Toilet 2" + }, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor/tiled/white, +/area/tether/surfacebase/medical/bathroom) "aSh" = ( /obj/machinery/atmospherics/portables_connector{ dir = 4 @@ -24816,6 +24856,30 @@ }, /turf/simulated/floor/plating, /area/maintenance/engineering/pumpstation) +"aSj" = ( +/obj/structure/toilet{ + dir = 8 + }, +/obj/machinery/light/small{ + dir = 4 + }, +/obj/machinery/button/remote/airlock{ + id = "bathroomlock11"; + name = "Surface Medbay Toilet 2 Lock"; + pixel_x = -10; + pixel_y = 22; + specialfunctions = 4 + }, +/turf/simulated/floor/tiled/white, +/area/tether/surfacebase/medical/bathroom) +"aSk" = ( +/obj/machinery/door/airlock{ + id_tag = "bathroomlock7"; + name = "Restroom" + }, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor/tiled/white, +/area/tether/surfacebase/medical/bathroom) "aSl" = ( /obj/effect/floor_decal/borderfloor{ dir = 8 @@ -24882,6 +24946,28 @@ /obj/random/maintenance/clean, /turf/simulated/floor, /area/maintenance/lower/south) +"aSr" = ( +/obj/machinery/door/airlock{ + id_tag = "bathroomlock7"; + name = "Restroom" + }, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor/tiled/white, +/area/tether/surfacebase/medical/uppersouthstairwell) +"aSs" = ( +/obj/structure/toilet, +/obj/machinery/light/small{ + dir = 4 + }, +/obj/machinery/button/remote/airlock{ + id = "bathroomlock9"; + name = "Surface Security Toilet Lock"; + pixel_x = -20; + pixel_y = -10; + specialfunctions = 4 + }, +/turf/simulated/floor/tiled/white, +/area/tether/surfacebase/security/brig/bathroom) "aSt" = ( /obj/structure/cable/green{ icon_state = "0-4" @@ -24907,6 +24993,29 @@ /obj/machinery/door/airlock/maintenance/common, /turf/simulated/floor/plating, /area/maintenance/asmaint2) +"aSw" = ( +/obj/machinery/door/airlock/security{ + id_tag = "bathroomlock9"; + name = "Surface Security Toilet"; + req_one_access = list(1,38) + }, +/obj/machinery/door/firedoor, +/turf/simulated/floor/tiled/white, +/area/tether/surfacebase/security/brig/bathroom) +"aSx" = ( +/obj/machinery/door/airlock{ + id_tag = "bathroomlock18"; + name = "Bar Toilet 2" + }, +/turf/simulated/floor/tiled/white, +/area/rnd/breakroom/bathroom) +"aSy" = ( +/obj/machinery/door/airlock{ + id_tag = "bathroomlock8"; + name = "Research Toilet" + }, +/turf/simulated/floor/tiled/white, +/area/rnd/breakroom/bathroom) "aSz" = ( /obj/machinery/door/firedoor/glass, /obj/structure/cable/green{ @@ -25130,6 +25239,20 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply, /turf/simulated/floor/plating, /area/engineering/atmos/storage) +"aSU" = ( +/obj/structure/toilet{ + dir = 1 + }, +/obj/machinery/light/small, +/obj/machinery/button/remote/airlock{ + id = "bathroomlock8"; + name = "Research Toilet Lock"; + pixel_x = -20; + pixel_y = 10; + specialfunctions = 4 + }, +/turf/simulated/floor/tiled/white, +/area/rnd/breakroom/bathroom) "aSV" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /turf/simulated/floor/plating, @@ -27458,18 +27581,6 @@ }, /turf/simulated/floor/tiled, /area/janitor) -"aXs" = ( -/obj/machinery/door/airlock{ - name = "Unit 2" - }, -/turf/simulated/floor/tiled/white, -/area/rnd/breakroom/bathroom) -"aXt" = ( -/obj/machinery/door/airlock{ - name = "Unit 1" - }, -/turf/simulated/floor/tiled/white, -/area/rnd/breakroom/bathroom) "aXu" = ( /obj/machinery/alarm{ pixel_y = 22 @@ -27742,13 +27853,6 @@ /obj/machinery/recharge_station, /turf/simulated/floor/tiled/white, /area/rnd/breakroom/bathroom) -"aYa" = ( -/obj/structure/toilet{ - dir = 1 - }, -/obj/machinery/light/small, -/turf/simulated/floor/tiled/white, -/area/rnd/breakroom/bathroom) "aYb" = ( /obj/machinery/light/small{ dir = 8 @@ -41955,8 +42059,8 @@ agr aom apA aqF -ary -asz +aSs +aSw atM auo avk @@ -42713,7 +42817,7 @@ aUm aVc aVH aWD -aXs +aSx aXZ aUm ayZ @@ -42997,8 +43101,8 @@ aPJ aVe aVJ aWD -aXt -aYa +aSy +aSU aUm aZb aAf @@ -49192,9 +49296,9 @@ aiP akq alS akq -alS +aSg akq -alS +aSk akq abp bpC @@ -49334,7 +49438,7 @@ ajz akq alT akq -alT +aSj akq atb akq @@ -49478,7 +49582,7 @@ aar aar aiK aiK -akH +aSr aiK aiK aiK @@ -51178,7 +51282,7 @@ adi adi adi ahN -ajC +ary ahN ahN ahN @@ -51745,9 +51849,9 @@ adt ahN aiF ahN -aiF +ajC ahN -aiF +aRe ahN abh auL @@ -51887,7 +51991,7 @@ adt ahN aiI ahN -aiI +akH ahN aoH ahN diff --git a/maps/tether/tether-03-surface3.dmm b/maps/tether/tether-03-surface3.dmm index d30ec6a4ac6..40b1869e5c4 100644 --- a/maps/tether/tether-03-surface3.dmm +++ b/maps/tether/tether-03-surface3.dmm @@ -2101,23 +2101,9 @@ /turf/simulated/floor/tiled, /area/tether/surfacebase/security/processing) "adh" = ( -/obj/machinery/papershredder, -/obj/machinery/light{ - dir = 8 - }, -/obj/effect/floor_decal/borderfloor{ - dir = 10 - }, -/obj/effect/floor_decal/corner/red/border{ - dir = 10 - }, -/obj/effect/floor_decal/borderfloor/corner2{ - dir = 8 - }, -/obj/effect/floor_decal/corner/red/bordercorner2{ - dir = 8 - }, -/turf/simulated/floor/tiled, +/obj/structure/grille, +/obj/structure/window/reinforced/full, +/turf/simulated/floor/plating, /area/tether/surfacebase/security/iaa/officecommon) "adi" = ( /obj/machinery/door/airlock/glass_security{ @@ -3988,17 +3974,29 @@ /turf/simulated/floor/plating, /area/tether/surfacebase/surface_three_hall) "afO" = ( -/obj/machinery/door/airlock{ - name = "Unit 1" +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 6 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/button/remote/airlock{ + id = "bathroomlock16"; + name = "Bathroom Lock"; + pixel_x = -20; + pixel_y = -20; + specialfunctions = 4 }, /turf/simulated/floor/tiled/white, -/area/crew_quarters/recreation_area_restroom) +/area/crew_quarters/captain) "afP" = ( -/obj/machinery/door/airlock{ - name = "Unit 2" +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/door/firedoor/glass, +/obj/machinery/door/airlock/command{ + id_tag = "bathroomlock16"; + name = "Private Restroom" }, /turf/simulated/floor/tiled/white, -/area/crew_quarters/recreation_area_restroom) +/area/crew_quarters/captain) "afQ" = ( /obj/machinery/door/airlock{ name = "Unit 3" @@ -13547,12 +13545,12 @@ /turf/simulated/floor/tiled/white, /area/crew_quarters/captain) "awk" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 6 +/obj/machinery/door/airlock{ + id_tag = "bathroomlock14"; + name = "Recreation Toilet 1" }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, /turf/simulated/floor/tiled/white, -/area/crew_quarters/captain) +/area/crew_quarters/recreation_area_restroom) "awl" = ( /obj/structure/toilet{ dir = 8 @@ -13913,11 +13911,9 @@ /turf/simulated/floor/tiled/white, /area/crew_quarters/recreation_area_restroom) "awM" = ( -/obj/machinery/light/small{ - dir = 4 - }, -/obj/structure/toilet{ - dir = 1 +/obj/machinery/door/airlock{ + id_tag = "bathroomlock15"; + name = "Recreation Toilet 2" }, /turf/simulated/floor/tiled/white, /area/crew_quarters/recreation_area_restroom) @@ -14161,16 +14157,21 @@ /turf/simulated/floor/tiled, /area/hallway/lower/third_south) "axf" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/door/firedoor/glass, -/obj/machinery/door/airlock/command{ - name = "Private Restroom"; - req_access = newlist(); - req_one_access = newlist() +/obj/machinery/light/small{ + dir = 4 + }, +/obj/structure/toilet{ + dir = 1 + }, +/obj/machinery/button/remote/airlock{ + id = "bathroomlock14"; + name = "Recreation Toilet 1 Lock"; + pixel_x = -20; + pixel_y = 10; + specialfunctions = 4 }, /turf/simulated/floor/tiled/white, -/area/crew_quarters/captain) +/area/crew_quarters/recreation_area_restroom) "axg" = ( /turf/simulated/wall, /area/library) @@ -29221,10 +29222,21 @@ /turf/simulated/floor/plating, /area/rnd/research_storage) "aXI" = ( -/obj/structure/shuttle/engine/propulsion, -/turf/simulated/floor/reinforced, -/turf/simulated/shuttle/plating/carry, -/area/shuttle/tether) +/obj/machinery/light/small{ + dir = 4 + }, +/obj/structure/toilet{ + dir = 1 + }, +/obj/machinery/button/remote/airlock{ + id = "bathroomlock15"; + name = "Recreation Toilet 2 Lock"; + pixel_x = -20; + pixel_y = 10; + specialfunctions = 4 + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/recreation_area_restroom) "aXJ" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -29273,18 +29285,57 @@ /turf/simulated/floor/tiled, /area/hallway/lower/third_south) "aXN" = ( -/obj/machinery/atmospherics/unary/engine{ +/obj/machinery/door/airlock{ + id_tag = "bathroomlock17"; + name = "Bar Toilet 1" + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/barrestroom) +"aXO" = ( +/obj/structure/toilet{ + dir = 8 + }, +/obj/machinery/light/small{ dir = 1 }, -/turf/simulated/floor/reinforced, -/turf/simulated/shuttle/plating/carry, -/area/shuttle/tourbus/general) +/obj/machinery/button/remote/airlock{ + id = "bathroomlock18"; + name = "Bar Toilet 2 Lock"; + pixel_x = -10; + pixel_y = 22; + specialfunctions = 4 + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/barrestroom) "aXP" = ( /obj/structure/disposalpipe/up{ dir = 8 }, /turf/simulated/floor/plating, /area/rnd/research_storage) +"aXQ" = ( +/obj/structure/toilet{ + dir = 8 + }, +/obj/machinery/light/small{ + dir = 1 + }, +/obj/machinery/button/remote/airlock{ + id = "bathroomlock17"; + name = "Bar Toilet 1 Lock"; + pixel_x = -10; + pixel_y = 22; + specialfunctions = 4 + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/barrestroom) +"aXR" = ( +/obj/machinery/door/airlock{ + id_tag = "bathroomlock18"; + name = "Bar Toilet 2" + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/barrestroom) "aXS" = ( /obj/structure/bed/chair/comfy, /obj/machinery/camera/network/civilian, @@ -29476,6 +29527,25 @@ }, /turf/simulated/floor/tiled/dark, /area/bridge) +"aYk" = ( +/obj/machinery/papershredder, +/obj/machinery/light{ + dir = 2 + }, +/obj/effect/floor_decal/borderfloor{ + dir = 10 + }, +/obj/effect/floor_decal/corner/red/border{ + dir = 10 + }, +/obj/effect/floor_decal/borderfloor/corner2{ + dir = 8 + }, +/obj/effect/floor_decal/corner/red/bordercorner2{ + dir = 8 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/security/iaa/officecommon) "aYl" = ( /obj/structure/lattice, /obj/structure/disposalpipe/down, @@ -29910,6 +29980,11 @@ }, /turf/simulated/floor/tiled/white, /area/rnd/outpost/xenobiology/outpost_first_aid) +"aZg" = ( +/obj/structure/shuttle/engine/propulsion, +/turf/simulated/floor/reinforced, +/turf/simulated/shuttle/plating/carry, +/area/shuttle/tether) "aZh" = ( /obj/machinery/door/airlock/glass_command{ name = "Bridge"; @@ -30878,6 +30953,13 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) +"baI" = ( +/obj/machinery/atmospherics/unary/engine{ + dir = 1 + }, +/turf/simulated/floor/reinforced, +/turf/simulated/shuttle/plating/carry, +/area/shuttle/tourbus/general) "baJ" = ( /obj/structure/cable{ icon_state = "1-2" @@ -32603,12 +32685,6 @@ }, /turf/simulated/floor/tiled/techmaint, /area/tether/surfacebase/barbackmaintenance) -"bdL" = ( -/obj/machinery/door/airlock{ - name = "Unit 1" - }, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/barrestroom) "bdM" = ( /obj/structure/cable/green{ d1 = 1; @@ -32739,15 +32815,6 @@ }, /turf/simulated/floor/wood, /area/crew_quarters/bar) -"bef" = ( -/obj/structure/toilet{ - dir = 8 - }, -/obj/machinery/light/small{ - dir = 1 - }, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/barrestroom) "beg" = ( /obj/machinery/light/small{ dir = 4 @@ -32816,12 +32883,6 @@ }, /turf/simulated/floor/tiled/white, /area/crew_quarters/kitchen) -"bel" = ( -/obj/machinery/door/airlock{ - name = "Unit 2" - }, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/barrestroom) "bem" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, @@ -51451,7 +51512,7 @@ aac fzy fzy aTY -fzy +adh jYD vEm waR @@ -51593,7 +51654,7 @@ aac fzy aeq afn -adh +aYk jYD efR vkv @@ -51902,8 +51963,8 @@ aiD afj rAe sla -afP -awM +awk +axf afj arn aEi @@ -52186,8 +52247,8 @@ aiG afj aqD awo -afO awM +aXI afj arn afh @@ -54356,7 +54417,7 @@ jML jHw jpB aVJ -aXN +baI aKU aOI aPb @@ -55014,8 +55075,8 @@ ajR akn alj aqc -awk -axf +afO +afP aZl aZx aZL @@ -55208,7 +55269,7 @@ caw jHw gHh aVJ -aXN +baI aKU aOI aKj @@ -57193,7 +57254,7 @@ aNk uSA aNJ aNP -aXI +aZg aKU abg aOk @@ -57335,7 +57396,7 @@ aNl aNl aNK aNP -aXI +aZg aKU abg aOk @@ -57477,7 +57538,7 @@ aNm aNl aNK aNP -aXI +aZg aKU abg aOk @@ -59737,9 +59798,9 @@ aJt aGx aTE aGK -bdL +aXN aGK -bel +aXR aGK bfM aGK @@ -59879,9 +59940,9 @@ aJt aQf aTE aGK -bef +aXQ aGK -bef +aXO aGK bfN aGK diff --git a/maps/tether/tether-05-station1.dmm b/maps/tether/tether-05-station1.dmm index 8883a9e18e2..a4e98b17b44 100644 --- a/maps/tether/tether-05-station1.dmm +++ b/maps/tether/tether-05-station1.dmm @@ -7860,6 +7860,26 @@ /obj/fiftyspawner/copper, /turf/simulated/floor/tiled, /area/engineering/workshop) +"aoQ" = ( +/obj/structure/toilet{ + dir = 4 + }, +/obj/machinery/light/small{ + dir = 8 + }, +/obj/effect/landmark{ + name = "xeno_spawn"; + pixel_x = -1 + }, +/obj/machinery/button/remote/airlock{ + id = "bathroomlock19"; + name = "Engineering Washroom Toilet 1 Lock"; + pixel_x = 10; + pixel_y = 22; + specialfunctions = 4 + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/sleep/engi_wash) "aoR" = ( /obj/structure/grille, /obj/machinery/door/firedoor/border_only, @@ -7868,6 +7888,14 @@ }, /turf/simulated/floor/plating, /area/maintenance/abandonedlibrary) +"aoS" = ( +/obj/machinery/door/airlock{ + id_tag = "bathroomlock19"; + name = "Engineering Washroom Toilet 1" + }, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/sleep/engi_wash) "aoT" = ( /obj/structure/table/woodentable, /obj/item/weapon/paper, @@ -7902,6 +7930,66 @@ /obj/fiftyspawner/glass, /turf/simulated/floor/tiled, /area/engineering/atmos/backup) +"aoY" = ( +/obj/structure/toilet{ + dir = 4 + }, +/obj/machinery/light/small{ + dir = 8 + }, +/obj/machinery/button/remote/airlock{ + id = "bathroomlock20"; + name = "Engineering Washroom Toilet 2 Lock"; + pixel_x = 10; + pixel_y = 22; + specialfunctions = 4 + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/sleep/engi_wash) +"aoZ" = ( +/obj/machinery/door/airlock{ + id_tag = "bathroomlock20"; + name = "Engineering Washroom Toilet 2" + }, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/sleep/engi_wash) +"apa" = ( +/obj/structure/toilet{ + dir = 4 + }, +/obj/machinery/light/small{ + dir = 8 + }, +/obj/effect/landmark{ + name = "xeno_spawn"; + pixel_x = -1 + }, +/obj/machinery/button/remote/airlock{ + id = "bathroomlock21"; + name = "Engineering Washroom Toilet 3 Lock"; + pixel_x = 10; + pixel_y = 22; + specialfunctions = 4 + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/sleep/engi_wash) +"apb" = ( +/obj/machinery/door/airlock{ + id_tag = "bathroomlock21"; + name = "Engineering Washroom Toilet 3" + }, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/sleep/engi_wash) +"apc" = ( +/obj/machinery/door/airlock{ + id_tag = "bathroomlock7"; + name = "Restroom" + }, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/sleep/engi_wash) "apd" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 @@ -7911,12 +7999,58 @@ }, /turf/simulated/floor/carpet, /area/maintenance/abandonedlibrary) +"ape" = ( +/obj/structure/toilet{ + dir = 4 + }, +/obj/machinery/light/small{ + dir = 1 + }, +/obj/machinery/button/remote/airlock{ + id = "bathroomlock22"; + name = "Unit 1 Lock"; + pixel_x = 10; + pixel_y = 22; + specialfunctions = 4 + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/toilet) +"apf" = ( +/obj/machinery/door/airlock{ + id_tag = "bathroomlock22"; + name = "Unit 1" + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/toilet) "apg" = ( /obj/structure/grille, /obj/structure/window/reinforced/full, /obj/machinery/door/firedoor/glass, /turf/simulated/floor, /area/engineering/break_room) +"aph" = ( +/obj/structure/toilet{ + dir = 4 + }, +/obj/machinery/light/small{ + dir = 1 + }, +/obj/machinery/button/remote/airlock{ + id = "bathroomlock23"; + name = "Unit 2 Lock"; + pixel_x = 10; + pixel_y = 22; + specialfunctions = 4 + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/toilet) +"api" = ( +/obj/machinery/door/airlock{ + id_tag = "bathroomlock23"; + name = "Unit 2" + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/toilet) "apm" = ( /turf/simulated/floor/carpet, /area/maintenance/abandonedlibrary) @@ -14255,21 +14389,6 @@ }, /turf/simulated/floor/tiled, /area/tether/station/visitorhallway/laundry) -"aAO" = ( -/obj/structure/toilet{ - dir = 4 - }, -/obj/machinery/light/small{ - dir = 1 - }, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/toilet) -"aAP" = ( -/obj/machinery/door/airlock{ - name = "Unit 1" - }, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/toilet) "aAQ" = ( /obj/machinery/access_button{ command = "cycle_exterior"; @@ -14618,19 +14737,6 @@ /obj/structure/disposalpipe/segment, /turf/simulated/floor/tiled, /area/engineering/hallway) -"aBC" = ( -/obj/structure/toilet{ - dir = 4 - }, -/obj/machinery/light/small{ - dir = 8 - }, -/obj/effect/landmark{ - name = "xeno_spawn"; - pixel_x = -1 - }, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/sleep/engi_wash) "aBD" = ( /obj/structure/cable/green{ d1 = 1; @@ -14833,12 +14939,6 @@ }, /turf/simulated/floor, /area/bridge/secondary/teleporter) -"aBU" = ( -/obj/machinery/door/airlock{ - name = "Unit 2" - }, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/toilet) "aBV" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /turf/simulated/floor/tiled/white, @@ -14846,13 +14946,6 @@ "aBW" = ( /turf/simulated/floor/carpet/purcarpet, /area/bridge/meeting_room) -"aBX" = ( -/obj/machinery/door/airlock{ - name = "Restroom" - }, -/obj/machinery/door/firedoor/glass, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/sleep/engi_wash) "aCa" = ( /obj/machinery/recharge_station, /obj/machinery/camera/network/engineering{ @@ -16029,15 +16122,6 @@ }, /turf/simulated/floor/wood, /area/bridge/meeting_room) -"aEE" = ( -/obj/structure/toilet{ - dir = 4 - }, -/obj/machinery/light/small{ - dir = 8 - }, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/sleep/engi_wash) "aEF" = ( /obj/structure/grille, /obj/structure/window/reinforced/full, @@ -31530,11 +31614,11 @@ avB atd atY auz -aBC +aoQ aAW -aEE +aoY aAW -aBC +apa aAW aMl aoJ @@ -31672,13 +31756,13 @@ ajF apQ atZ auz -aBX +aoS aAW -aBX +aoZ aAW -aBX +apb aAW -aBX +apc aoJ aCa aRc @@ -37518,9 +37602,9 @@ att acm bpi aAk -aAO +ape aAk -aAO +aph aAk byy amU @@ -37660,9 +37744,9 @@ abV acm bpm aAk -aAP +apf aAk -aBU +api aAk aDh amU diff --git a/maps/tether/tether-06-station2.dmm b/maps/tether/tether-06-station2.dmm index 5b3b9de6584..09d88b445ba 100644 --- a/maps/tether/tether-06-station2.dmm +++ b/maps/tether/tether-06-station2.dmm @@ -144,30 +144,18 @@ /turf/simulated/floor/tiled, /area/security/brig/visitation) "ap" = ( -/obj/effect/floor_decal/borderfloor/shifted{ - dir = 4 +/obj/effect/floor_decal/corner/white/border{ + dir = 8 }, -/obj/effect/floor_decal/corner/red/border/shifted{ - dir = 4 +/obj/item/weapon/paper/crumpled{ + name = "basketball" }, -/obj/effect/floor_decal/corner/red{ - dir = 6 +/obj/effect/floor_decal/industrial/outline/yellow, +/obj/machinery/flasher{ + id = "AsteroidSecFlash" }, -/obj/machinery/atmospherics/unary/vent_pump/on{ - dir = 1 - }, -/obj/machinery/button/remote/airlock{ - id = "visitdoor"; - name = "Visitation Access"; - pixel_y = -24 - }, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/turf/simulated/floor/tiled, -/area/security/brig/visitation) +/turf/simulated/floor/tiled/monotile, +/area/security/brig) "aq" = ( /obj/machinery/light{ dir = 4 @@ -388,13 +376,11 @@ /turf/simulated/floor/tiled/dark, /area/security/brig) "aO" = ( -/obj/effect/floor_decal/corner/white/border{ - dir = 8 +/obj/effect/floor_decal/industrial/outline/yellow, +/obj/machinery/flasher{ + id = "AsteroidSecFlash" }, -/obj/item/weapon/paper/crumpled{ - name = "basketball" - }, -/turf/simulated/floor/tiled/monotile, +/turf/simulated/floor/tiled, /area/security/brig) "aP" = ( /turf/simulated/mineral/floor/vacuum, @@ -1833,16 +1819,35 @@ /turf/simulated/floor/tiled/steel_dirty, /area/security/brig) "cO" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 5 +/obj/effect/floor_decal/borderfloor/shifted{ + dir = 4 + }, +/obj/effect/floor_decal/corner/red/border/shifted{ + dir = 4 + }, +/obj/effect/floor_decal/corner/red{ + dir = 6 + }, +/obj/machinery/atmospherics/unary/vent_pump/on{ + dir = 1 + }, +/obj/machinery/button/remote/airlock{ + id = "visitdoor"; + name = "Visitation Access"; + pixel_y = -24 }, /obj/structure/cable/green{ d1 = 4; d2 = 8; icon_state = "4-8" }, -/turf/simulated/floor/tiled/dark, -/area/security/brig) +/obj/machinery/button/flasher{ + id = "AsteroidVisitingFlash"; + pixel_x = -10; + pixel_y = -20 + }, +/turf/simulated/floor/tiled, +/area/security/brig/visitation) "cP" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/structure/cable/green{ @@ -1948,12 +1953,24 @@ /turf/simulated/floor/tiled/dark, /area/security/recstorage) "cW" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/green, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ +/obj/effect/floor_decal/borderfloor/shifted{ + dir = 8 + }, +/obj/effect/floor_decal/corner/red/border/shifted{ + dir = 8 + }, +/obj/effect/floor_decal/corner/red{ dir = 9 }, +/obj/machinery/atmospherics/unary/vent_pump/on{ + dir = 1 + }, +/obj/machinery/flasher{ + id = "AsteroidVisitingFlash"; + pixel_y = -20 + }, /turf/simulated/floor/tiled, -/area/security/brig) +/area/security/brig/visitation) "cX" = ( /obj/machinery/door/firedoor/glass, /obj/structure/cable/green{ @@ -2260,20 +2277,20 @@ /turf/simulated/floor/tiled, /area/security/security_cell_hallway) "dt" = ( -/obj/effect/floor_decal/borderfloor/shifted{ - dir = 8 +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 5 }, -/obj/effect/floor_decal/corner/red/border/shifted{ - dir = 8 +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" }, -/obj/effect/floor_decal/corner/red{ - dir = 9 +/obj/machinery/flasher{ + id = "AsteroidSecFlash"; + pixel_y = -20 }, -/obj/machinery/atmospherics/unary/vent_pump/on{ - dir = 1 - }, -/turf/simulated/floor/tiled, -/area/security/brig/visitation) +/turf/simulated/floor/tiled/dark, +/area/security/brig) "du" = ( /obj/effect/floor_decal/borderfloorblack{ dir = 8 @@ -2513,12 +2530,14 @@ /turf/simulated/floor/tiled/steel_dirty, /area/security/brig) "dQ" = ( -/obj/effect/floor_decal/industrial/warning, /obj/machinery/atmospherics/pipe/simple/hidden/green, -/obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 9 }, +/obj/effect/floor_decal/industrial/outline/yellow, +/obj/machinery/flasher{ + id = "AsteroidSecFlash" + }, /turf/simulated/floor/tiled, /area/security/brig) "dR" = ( @@ -7774,6 +7793,39 @@ }, /turf/simulated/floor/tiled, /area/hallway/station/starboard) +"lU" = ( +/obj/effect/floor_decal/industrial/warning, +/obj/machinery/atmospherics/pipe/simple/hidden/green, +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 9 + }, +/obj/effect/floor_decal/industrial/outline/yellow, +/obj/machinery/flasher{ + id = "AsteroidSecFlash" + }, +/turf/simulated/floor/tiled, +/area/security/brig) +"lV" = ( +/obj/effect/floor_decal/borderfloor{ + dir = 1 + }, +/obj/effect/floor_decal/corner/red/border{ + dir = 1 + }, +/obj/effect/floor_decal/borderfloor/corner2{ + dir = 4 + }, +/obj/effect/floor_decal/corner/red/bordercorner2{ + dir = 4 + }, +/obj/machinery/button/flasher{ + id = "AsteroidSecFlash"; + pixel_x = 20; + pixel_y = 20 + }, +/turf/simulated/floor/tiled, +/area/security/security_cell_hallway) "lW" = ( /obj/structure/cable/green{ d1 = 4; @@ -9541,6 +9593,31 @@ }, /turf/simulated/floor/tiled, /area/hallway/station/starboard) +"oB" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/green{ + dir = 5 + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 1; + icon_state = "pipe-c" + }, +/obj/effect/floor_decal/industrial/outline/yellow, +/obj/machinery/flasher{ + id = "AsteroidSecFlash" + }, +/turf/simulated/floor/tiled, +/area/security/brig) "oC" = ( /obj/effect/floor_decal/borderfloor{ dir = 1 @@ -9571,13 +9648,37 @@ /turf/simulated/shuttle/plating/airless/carry, /area/shuttle/large_escape_pod1) "oE" = ( +/obj/structure/toilet{ + pixel_y = 6 + }, +/obj/machinery/light/small{ + dir = 1 + }, +/obj/machinery/button/remote/airlock{ + id = "bathroomlock24"; + name = "Bathroom Lock"; + pixel_x = -20; + pixel_y = -10; + specialfunctions = 4 + }, +/turf/simulated/floor/tiled/white, +/area/medical/recoveryrestroom) +"oF" = ( +/obj/machinery/door/airlock/medical{ + id_tag = "bathroomlock24"; + name = "Rest Room"; + req_one_access = list() + }, +/turf/simulated/floor/tiled/white, +/area/medical/recoveryrestroom) +"oG" = ( /obj/structure/shuttle/engine/propulsion{ dir = 8 }, /turf/space, /turf/simulated/shuttle/plating/airless/carry, /area/shuttle/large_escape_pod1) -"oF" = ( +"oH" = ( /obj/structure/shuttle/engine/propulsion{ dir = 8; icon_state = "propulsion_r" @@ -9585,7 +9686,7 @@ /turf/space, /turf/simulated/shuttle/plating/airless/carry, /area/shuttle/large_escape_pod1) -"oG" = ( +"oI" = ( /obj/structure/stairs/spawner/west, /turf/simulated/sky/virgo3b/west, /turf/simulated/floor/tiled/white, @@ -10261,7 +10362,6 @@ /area/ai_monitored/storage/eva) "qj" = ( /obj/structure/table/woodentable, -/obj/item/device/binoculars, /obj/item/weapon/folder/blue, /obj/structure/cable/green{ d1 = 1; @@ -15925,15 +16025,6 @@ "Ce" = ( /turf/simulated/floor/tiled/white, /area/medical/recoveryrestroom) -"Cf" = ( -/obj/structure/toilet{ - pixel_y = 6 - }, -/obj/machinery/light/small{ - dir = 1 - }, -/turf/simulated/floor/tiled/white, -/area/medical/recoveryrestroom) "Cg" = ( /obj/machinery/recharge_station, /obj/machinery/light/small{ @@ -18706,27 +18797,6 @@ /obj/item/weapon/book/manual/medical_diagnostics_manual, /turf/simulated/floor/tiled/white, /area/maintenance/station/sec_lower) -"Nc" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/green{ - dir = 5 - }, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/structure/disposalpipe/segment{ - dir = 1; - icon_state = "pipe-c" - }, -/turf/simulated/floor/tiled, -/area/security/brig) "Nf" = ( /obj/effect/floor_decal/borderfloor{ dir = 8 @@ -18742,21 +18812,6 @@ }, /turf/simulated/floor/tiled, /area/engineering/locker_room) -"Ng" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 1 - }, -/obj/effect/floor_decal/corner/red/border{ - dir = 1 - }, -/obj/effect/floor_decal/borderfloor/corner2{ - dir = 4 - }, -/obj/effect/floor_decal/corner/red/bordercorner2{ - dir = 4 - }, -/turf/simulated/floor/tiled, -/area/security/security_cell_hallway) "Nm" = ( /obj/structure/bed/chair{ dir = 8 @@ -27155,7 +27210,7 @@ bh af ao dk -ap +cO dj dL Tk @@ -27439,7 +27494,7 @@ Fq af cG do -dt +cW af XR UT @@ -28143,22 +28198,22 @@ UO Hc aS EE -aO +ap ak bm -DF +aO ar bb bt -cW +dQ bv bB es -dQ +lU Ye cn YK -Nc +oB hQ YN jf @@ -28473,7 +28528,7 @@ vE wm ws xj -oG +oI vT aP aP @@ -28583,7 +28638,7 @@ cd ce bK Zu -Ng +lV JD TY aE @@ -28859,13 +28914,13 @@ XT GM aS aY -cO +dt aS aY -cO +dt aS aY -cO +dt aS PJ Ph @@ -31892,8 +31947,8 @@ yp pp Ay BM -Cf -Cz +oE +oF CM xJ EG @@ -35413,10 +35468,10 @@ DI RX DL oD -oE -oE -oE -oF +oG +oG +oG +oH oY sW ef diff --git a/maps/tether/tether-07-station3.dmm b/maps/tether/tether-07-station3.dmm index aeb496cda4e..9717e5f4f0e 100644 --- a/maps/tether/tether-07-station3.dmm +++ b/maps/tether/tether-07-station3.dmm @@ -579,12 +579,12 @@ /turf/simulated/floor, /area/maintenance/cargo) "abj" = ( -/obj/structure/catwalk, -/obj/machinery/light/small{ +/obj/machinery/atmospherics/unary/engine{ dir = 1 }, -/turf/simulated/floor, -/area/maintenance/station/ai) +/turf/space, +/turf/simulated/shuttle/plating/airless/carry, +/area/shuttle/excursion/general) "abk" = ( /obj/structure/railing, /obj/machinery/light/small{ @@ -1570,6 +1570,13 @@ /obj/machinery/light/small{ dir = 1 }, +/obj/machinery/button/remote/airlock{ + id = "bathroomlock25"; + name = "Security Toilet Lock"; + pixel_x = -20; + pixel_y = -10; + specialfunctions = 4 + }, /turf/simulated/floor/tiled/white, /area/security/security_bathroom) "ade" = ( @@ -2270,20 +2277,23 @@ /turf/simulated/floor/tiled/white, /area/security/security_bathroom) "aex" = ( +/obj/machinery/door/firedoor/glass, +/obj/structure/cable/cyan{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 6 + dir = 4 }, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 6 + dir = 4 }, -/obj/structure/cable/cyan{ - d1 = 1; - d2 = 2; - icon_state = "1-2" +/obj/machinery/atmospherics/pipe/simple/hidden/aux{ + dir = 8 }, -/obj/machinery/firealarm{ - dir = 8; - pixel_x = -24 +/obj/machinery/door/airlock/hatch{ + req_one_access = list(67) }, /turf/simulated/floor/tiled/techmaint, /area/shuttle/excursion/general) @@ -2784,10 +2794,23 @@ /turf/simulated/floor/plating, /area/shuttle/excursion/cargo) "afi" = ( -/obj/structure/bed/padded, -/obj/item/weapon/bedsheet/brown, -/obj/structure/curtain/open/bed, -/turf/simulated/floor/tiled/techfloor, +/obj/structure/grille, +/obj/machinery/door/blast/regular{ + density = 0; + dir = 4; + icon_state = "pdoor0"; + id = "shuttle blast"; + name = "Shuttle Blast Doors"; + opacity = 0 + }, +/obj/machinery/door/firedoor/glass, +/obj/structure/window/reinforced/polarized/full{ + id = "pilot_room" + }, +/obj/structure/window/reinforced{ + dir = 1 + }, +/turf/simulated/floor/plating, /area/shuttle/excursion/cargo) "afj" = ( /obj/structure/disposalpipe/segment{ @@ -3327,12 +3350,17 @@ /turf/simulated/wall/rshull, /area/shuttle/excursion/general) "agd" = ( -/obj/machinery/atmospherics/unary/engine{ - dir = 1 +/obj/structure/bed/padded, +/obj/item/weapon/bedsheet/brown, +/obj/structure/curtain/open/bed, +/obj/machinery/button/windowtint{ + id = "pilot_room"; + pixel_x = 26; + pixel_y = 6; + req_access = list() }, -/turf/space, -/turf/simulated/shuttle/plating/airless/carry, -/area/shuttle/excursion/general) +/turf/simulated/floor/tiled/techfloor, +/area/shuttle/excursion/cargo) "age" = ( /obj/structure/window/reinforced{ dir = 8 @@ -3354,31 +3382,32 @@ /turf/simulated/floor/tiled/eris/steel/cyancorner, /area/shuttle/medivac/cockpit) "agf" = ( -/obj/structure/shuttle/engine/propulsion{ +/obj/machinery/firealarm{ dir = 8; - icon_state = "propulsion_l" + pixel_x = -24 }, -/turf/simulated/floor/tiled/asteroid_steel/airless, -/turf/simulated/shuttle/plating/airless/carry, -/area/shuttle/mining_outpost/shuttle) +/turf/simulated/floor/tiled/techfloor, +/area/shuttle/excursion/general) "agg" = ( /turf/simulated/floor/airless, /area/space) "agh" = ( -/obj/structure/shuttle/engine/propulsion{ +/obj/effect/floor_decal/industrial/outline/yellow, +/obj/structure/handrail, +/obj/structure/extinguisher_cabinet{ + dir = 1; + pixel_y = 32 + }, +/turf/simulated/floor/tiled/techfloor, +/area/shuttle/excursion/general) +"agi" = ( +/obj/structure/handrail{ dir = 8 }, -/turf/simulated/floor/tiled/asteroid_steel/airless, -/turf/simulated/shuttle/plating/airless/carry, -/area/shuttle/mining_outpost/shuttle) -"agi" = ( -/obj/structure/shuttle/engine/propulsion{ - dir = 8; - icon_state = "propulsion_r" - }, -/turf/simulated/floor/tiled/asteroid_steel/airless, -/turf/simulated/shuttle/plating/airless/carry, -/area/shuttle/mining_outpost/shuttle) +/obj/machinery/portable_atmospherics/canister/oxygen, +/obj/effect/floor_decal/industrial/outline/blue, +/turf/simulated/floor/tiled/techfloor, +/area/shuttle/excursion/general) "agj" = ( /obj/machinery/access_button{ command = "cycle_exterior"; @@ -3391,6 +3420,23 @@ }, /turf/simulated/floor/airless, /area/space) +"agk" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/fuel{ + dir = 8 + }, +/obj/machinery/shuttle_sensor{ + dir = 5; + id_tag = "shuttlesens_exp_int"; + pixel_y = -24 + }, +/obj/machinery/alarm{ + dir = 4; + pixel_x = -22 + }, +/obj/structure/table/steel, +/obj/machinery/recharger, +/turf/simulated/floor/tiled/techfloor, +/area/shuttle/excursion/general) "agl" = ( /obj/machinery/door/airlock/glass_external, /obj/effect/floor_decal/industrial/hatch/yellow, @@ -3401,6 +3447,104 @@ /obj/structure/grille, /turf/space, /area/space) +"agn" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/fuel{ + dir = 8 + }, +/obj/machinery/light, +/obj/machinery/suit_cycler/pilot, +/turf/simulated/floor/tiled/techfloor, +/area/shuttle/excursion/general) +"ago" = ( +/obj/machinery/door/firedoor/glass, +/obj/machinery/atmospherics/pipe/simple/hidden/fuel{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/structure/cable/cyan{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/door/airlock/hatch{ + req_one_access = list(67) + }, +/turf/simulated/floor/tiled/techmaint, +/area/shuttle/excursion/general) +"agp" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 6 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 6 + }, +/obj/structure/cable/cyan{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/obj/structure/closet/emergsuit_wall{ + dir = 8; + pixel_x = -32 + }, +/turf/simulated/floor/tiled/techmaint, +/area/shuttle/excursion/general) +"agq" = ( +/obj/machinery/door/airlock/security{ + id_tag = "bathroomlock25"; + name = "Security Restroom"; + req_one_access = list(1,38) + }, +/turf/simulated/floor/tiled/white, +/area/security/security_bathroom) +"agr" = ( +/obj/structure/shuttle/engine/propulsion{ + dir = 8; + icon_state = "propulsion_l" + }, +/turf/simulated/floor/tiled/asteroid_steel/airless, +/turf/simulated/shuttle/plating/airless/carry, +/area/shuttle/mining_outpost/shuttle) +"ags" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/obj/machinery/button/remote/airlock{ + id = "bathroomlock26"; + name = "Medical Toilet Lock"; + pixel_x = -20; + pixel_y = -10; + specialfunctions = 4 + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/medical_restroom) +"agt" = ( +/obj/machinery/door/airlock/medical{ + id_tag = "bathroomlock26"; + name = "Rest Room" + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/medical_restroom) +"agu" = ( +/obj/structure/shuttle/engine/propulsion{ + dir = 8 + }, +/turf/simulated/floor/tiled/asteroid_steel/airless, +/turf/simulated/shuttle/plating/airless/carry, +/area/shuttle/mining_outpost/shuttle) +"agv" = ( +/obj/structure/shuttle/engine/propulsion{ + dir = 8; + icon_state = "propulsion_r" + }, +/turf/simulated/floor/tiled/asteroid_steel/airless, +/turf/simulated/shuttle/plating/airless/carry, +/area/shuttle/mining_outpost/shuttle) "agx" = ( /obj/machinery/atmospherics/unary/vent_pump/high_volume{ frequency = 1379; @@ -4088,25 +4232,6 @@ }, /turf/simulated/wall/rshull, /area/shuttle/excursion/general) -"aiY" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/fuel{ - dir = 8 - }, -/obj/machinery/shuttle_sensor{ - dir = 5; - id_tag = "shuttlesens_exp_int"; - pixel_y = -24 - }, -/obj/machinery/alarm{ - dir = 4; - pixel_x = -22 - }, -/obj/structure/handrail{ - dir = 1 - }, -/obj/effect/floor_decal/industrial/outline/yellow, -/turf/simulated/floor/tiled/techfloor, -/area/shuttle/excursion/general) "ajf" = ( /obj/structure/disposalpipe/segment, /obj/effect/floor_decal/steeldecal/steel_decals6{ @@ -4532,27 +4657,6 @@ /obj/random/maintenance/clean, /turf/simulated/floor, /area/maintenance/station/sec_upper) -"akx" = ( -/obj/machinery/door/firedoor/glass, -/obj/machinery/atmospherics/pipe/simple/hidden/fuel{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/structure/cable/cyan{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/machinery/door/airlock/hatch{ - req_one_access = list() - }, -/turf/simulated/floor/tiled/techmaint, -/area/shuttle/excursion/general) "akz" = ( /obj/effect/floor_decal/borderfloorblack{ dir = 1 @@ -19688,27 +19792,6 @@ /obj/item/device/binoculars, /turf/simulated/floor/tiled, /area/quartermaster/belterdock) -"aUl" = ( -/obj/machinery/door/firedoor/glass, -/obj/structure/cable/cyan{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/aux{ - dir = 8 - }, -/obj/machinery/door/airlock/hatch{ - req_one_access = list() - }, -/turf/simulated/floor/tiled/techmaint, -/area/shuttle/excursion/general) "aUn" = ( /obj/structure/cable/green{ d1 = 4; @@ -21001,12 +21084,6 @@ }, /turf/simulated/floor/tiled/white, /area/crew_quarters/medical_restroom) -"aZx" = ( -/obj/machinery/light/small{ - dir = 8 - }, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/medical_restroom) "aZy" = ( /obj/structure/bed/chair/bay/shuttle{ dir = 1 @@ -22827,10 +22904,6 @@ }, /turf/simulated/floor/tiled, /area/hallway/station/upper) -"iPK" = ( -/obj/machinery/suit_cycler/pilot, -/turf/simulated/floor/tiled/techfloor, -/area/shuttle/excursion/general) "iUO" = ( /obj/structure/barricade, /turf/simulated/floor, @@ -23163,14 +23236,6 @@ "kTn" = ( /turf/simulated/floor/tiled/techmaint, /area/shuttle/excursion/general) -"kUK" = ( -/obj/effect/floor_decal/industrial/outline/yellow, -/obj/structure/closet/emergsuit_wall{ - pixel_y = 32 - }, -/obj/structure/handrail, -/turf/simulated/floor/tiled/techfloor, -/area/shuttle/excursion/general) "kVs" = ( /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ dir = 8 @@ -23696,14 +23761,6 @@ }, /turf/simulated/floor/tiled/eris/dark/techfloor_grid, /area/shuttle/securiship/cockpit) -"opv" = ( -/obj/structure/handrail{ - dir = 8 - }, -/obj/effect/floor_decal/industrial/outline/yellow, -/obj/machinery/portable_atmospherics/canister/oxygen, -/turf/simulated/floor/tiled/techfloor, -/area/shuttle/excursion/general) "opL" = ( /obj/effect/floor_decal/borderfloor{ dir = 1 @@ -24605,19 +24662,6 @@ }, /turf/simulated/floor/plating/eris/under, /area/shuttle/medivac/general) -"uVS" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/fuel{ - dir = 8 - }, -/obj/structure/extinguisher_cabinet{ - dir = 8; - pixel_x = 30 - }, -/obj/structure/table/steel, -/obj/machinery/recharger, -/obj/machinery/light, -/turf/simulated/floor/tiled/techfloor, -/area/shuttle/excursion/general) "uZd" = ( /obj/structure/bed/chair/bay/chair/padded/beige{ dir = 4 @@ -31331,8 +31375,8 @@ aab aab aKE aQf -aZx -aMd +ags +agt aZu aTf aKE @@ -34547,7 +34591,7 @@ abw aaB adS add -aSX +agq aST aew aUT @@ -36105,16 +36149,16 @@ aaY aaY aaR oNI -iPK +agf rFo -aex +agp jsf aWn aUJ aXb afT aez -agd +abj ams aXq abe @@ -36256,7 +36300,7 @@ wRt eug afT aeG -agd +abj ams aXq abe @@ -36383,14 +36427,14 @@ abe abX acE acK -aeI afi +agd afx aaY aVi hTW adj -akx +ago adj adj wOI @@ -36538,7 +36582,7 @@ adj hNx kTn ckU -aiY +agk xiw acK ams @@ -36961,7 +37005,7 @@ isN aXD hyH adj -kUK +agh ydG xCq qJK @@ -37097,7 +37141,7 @@ aaY abL aRZ aaY -aUl +aex adj adj adj @@ -37105,8 +37149,8 @@ wOI adj aXS rLd -opv -uVS +agi +agn xiw acK ams @@ -37392,7 +37436,7 @@ ikk efQ wPF aeG -agd +abj ams aSx krj @@ -37534,7 +37578,7 @@ iEV tEV xiw aeH -agd +abj ams eAm abe @@ -37827,7 +37871,7 @@ abe abe adV aSi -abj +aib aib aib agJ @@ -39571,11 +39615,11 @@ avt avt adD aZS -agf -agh -agh -agh -agi +agr +agu +agu +agu +agv baB adD avt diff --git a/maps/tether/tether_areas.dm b/maps/tether/tether_areas.dm index 1389266ce85..71c93bb2894 100644 --- a/maps/tether/tether_areas.dm +++ b/maps/tether/tether_areas.dm @@ -973,144 +973,185 @@ icon_state = "recreation_area_restroom" sound_env = SMALL_ENCLOSED -/area/crew_quarters/sleep - limit_mob_size = FALSE - /area/crew_quarters/sleep/maintDorm1 name = "\improper Construction Dorm 1" icon_state = "Sleep" flags = RAD_SHIELDED soundproofed = TRUE + limit_mob_size = FALSE + block_suit_sensors = TRUE /area/crew_quarters/sleep/maintDorm2 name = "\improper Construction Dorm 2" icon_state = "Sleep" flags = RAD_SHIELDED soundproofed = TRUE + limit_mob_size = FALSE + block_suit_sensors = TRUE /area/crew_quarters/sleep/maintDorm3 name = "\improper Construction Dorm 3" icon_state = "Sleep" flags = RAD_SHIELDED soundproofed = TRUE + limit_mob_size = FALSE + block_suit_sensors = TRUE /area/crew_quarters/sleep/maintDorm4 name = "\improper Construction Dorm 4" icon_state = "Sleep" flags = RAD_SHIELDED soundproofed = TRUE + limit_mob_size = FALSE + block_suit_sensors = TRUE /area/crew_quarters/sleep/vistor_room_1 flags = RAD_SHIELDED | BLUE_SHIELDED soundproofed = TRUE + limit_mob_size = FALSE + block_suit_sensors = TRUE /area/crew_quarters/sleep/vistor_room_2 flags = RAD_SHIELDED | BLUE_SHIELDED soundproofed = TRUE + limit_mob_size = FALSE + block_suit_sensors = TRUE /area/crew_quarters/sleep/vistor_room_3 flags = RAD_SHIELDED | BLUE_SHIELDED soundproofed = TRUE + limit_mob_size = FALSE + block_suit_sensors = TRUE /area/crew_quarters/sleep/vistor_room_4 flags = RAD_SHIELDED | BLUE_SHIELDED soundproofed = TRUE + limit_mob_size = FALSE + block_suit_sensors = TRUE /area/crew_quarters/sleep/vistor_room_5 flags = RAD_SHIELDED | BLUE_SHIELDED soundproofed = TRUE + limit_mob_size = FALSE + block_suit_sensors = TRUE /area/crew_quarters/sleep/vistor_room_6 flags = RAD_SHIELDED | BLUE_SHIELDED soundproofed = TRUE + limit_mob_size = FALSE + block_suit_sensors = TRUE /area/crew_quarters/sleep/vistor_room_7 flags = RAD_SHIELDED | BLUE_SHIELDED soundproofed = TRUE + limit_mob_size = FALSE + block_suit_sensors = TRUE /area/crew_quarters/sleep/vistor_room_8 flags = RAD_SHIELDED | BLUE_SHIELDED soundproofed = TRUE + limit_mob_size = FALSE + block_suit_sensors = TRUE /area/crew_quarters/sleep/vistor_room_9 flags = RAD_SHIELDED | BLUE_SHIELDED soundproofed = TRUE + limit_mob_size = FALSE + block_suit_sensors = TRUE /area/crew_quarters/sleep/vistor_room_10 flags = RAD_SHIELDED | BLUE_SHIELDED soundproofed = TRUE + limit_mob_size = FALSE + block_suit_sensors = TRUE /area/crew_quarters/sleep/vistor_room_11 flags = RAD_SHIELDED | BLUE_SHIELDED soundproofed = TRUE + limit_mob_size = FALSE + block_suit_sensors = TRUE /area/crew_quarters/sleep/vistor_room_12 flags = RAD_SHIELDED | BLUE_SHIELDED soundproofed = TRUE + limit_mob_size = FALSE + block_suit_sensors = TRUE /area/crew_quarters/sleep/Dorm_1 flags = RAD_SHIELDED | BLUE_SHIELDED soundproofed = TRUE + limit_mob_size = FALSE + block_suit_sensors = TRUE /area/crew_quarters/sleep/Dorm_2 flags = RAD_SHIELDED | BLUE_SHIELDED soundproofed = TRUE + limit_mob_size = FALSE + block_suit_sensors = TRUE /area/crew_quarters/sleep/Dorm_3 flags = RAD_SHIELDED | BLUE_SHIELDED soundproofed = TRUE + limit_mob_size = FALSE + block_suit_sensors = TRUE /area/crew_quarters/sleep/Dorm_4 flags = RAD_SHIELDED | BLUE_SHIELDED soundproofed = TRUE + limit_mob_size = FALSE + block_suit_sensors = TRUE /area/crew_quarters/sleep/Dorm_5 flags = RAD_SHIELDED | BLUE_SHIELDED soundproofed = TRUE + limit_mob_size = FALSE + block_suit_sensors = TRUE /area/crew_quarters/sleep/Dorm_6 flags = RAD_SHIELDED | BLUE_SHIELDED soundproofed = TRUE + limit_mob_size = FALSE + block_suit_sensors = TRUE /area/crew_quarters/sleep/Dorm_7 flags = RAD_SHIELDED | BLUE_SHIELDED soundproofed = TRUE + limit_mob_size = FALSE + block_suit_sensors = TRUE /area/crew_quarters/sleep/Dorm_8 flags = RAD_SHIELDED | BLUE_SHIELDED soundproofed = TRUE + limit_mob_size = FALSE + block_suit_sensors = TRUE /area/crew_quarters/sleep/Dorm_9 flags = RAD_SHIELDED | BLUE_SHIELDED soundproofed = TRUE + limit_mob_size = FALSE + block_suit_sensors = TRUE /area/crew_quarters/sleep/Dorm_10 flags = RAD_SHIELDED | BLUE_SHIELDED soundproofed = TRUE + limit_mob_size = FALSE + block_suit_sensors = TRUE /area/crew_quarters/sleep/Dorm_1/holo name = "\improper Dorm 1 Holodeck" icon_state = "dk_yellow" - flags = RAD_SHIELDED | BLUE_SHIELDED - soundproofed = TRUE /area/crew_quarters/sleep/Dorm_3/holo name = "\improper Dorm 3 Holodeck" icon_state = "dk_yellow" - flags = RAD_SHIELDED | BLUE_SHIELDED - soundproofed = TRUE /area/crew_quarters/sleep/Dorm_5/holo name = "\improper Dorm 5 Holodeck" icon_state = "dk_yellow" - flags = RAD_SHIELDED | BLUE_SHIELDED - soundproofed = TRUE /area/crew_quarters/sleep/Dorm_7/holo name = "\improper Dorm 7 Holodeck" icon_state = "dk_yellow" - flags = RAD_SHIELDED | BLUE_SHIELDED - soundproofed = TRUE /area/crew_quarters/sleep/spacedorm1 name = "\improper Visitor Lodging 1" @@ -1118,64 +1159,98 @@ lightswitch = 0 flags = RAD_SHIELDED | BLUE_SHIELDED soundproofed = TRUE + limit_mob_size = FALSE + block_suit_sensors = TRUE + /area/crew_quarters/sleep/spacedorm2 name = "\improper Visitor Lodging 2" icon_state = "dk_yellow" lightswitch = 0 flags = RAD_SHIELDED | BLUE_SHIELDED soundproofed = TRUE + limit_mob_size = FALSE + block_suit_sensors = TRUE + /area/crew_quarters/sleep/spacedorm3 name = "\improper Visitor Lodging 3" icon_state = "dk_yellow" lightswitch = 0 flags = RAD_SHIELDED | BLUE_SHIELDED soundproofed = TRUE + limit_mob_size = FALSE + block_suit_sensors = TRUE + /area/crew_quarters/sleep/spacedorm4 name = "\improper Visitor Lodging 4" icon_state = "dk_yellow" lightswitch = 0 flags = RAD_SHIELDED | BLUE_SHIELDED soundproofed = TRUE - -/area/holodeck/holodorm limit_mob_size = FALSE + block_suit_sensors = TRUE /area/holodeck/holodorm/source_basic name = "\improper Holodeck Source" flags = RAD_SHIELDED | BLUE_SHIELDED soundproofed = TRUE + limit_mob_size = FALSE + block_suit_sensors = TRUE + /area/holodeck/holodorm/source_desert name = "\improper Holodeck Source" flags = RAD_SHIELDED | BLUE_SHIELDED soundproofed = TRUE + limit_mob_size = FALSE + block_suit_sensors = TRUE + /area/holodeck/holodorm/source_seating name = "\improper Holodeck Source" flags = RAD_SHIELDED | BLUE_SHIELDED soundproofed = TRUE + limit_mob_size = FALSE + block_suit_sensors = TRUE + /area/holodeck/holodorm/source_beach name = "\improper Holodeck Source" flags = RAD_SHIELDED | BLUE_SHIELDED soundproofed = TRUE + limit_mob_size = FALSE + block_suit_sensors = TRUE + /area/holodeck/holodorm/source_garden name = "\improper Holodeck Source" flags = RAD_SHIELDED | BLUE_SHIELDED soundproofed = TRUE + limit_mob_size = FALSE + block_suit_sensors = TRUE + /area/holodeck/holodorm/source_boxing name = "\improper Holodeck Source" flags = RAD_SHIELDED | BLUE_SHIELDED soundproofed = TRUE + limit_mob_size = FALSE + block_suit_sensors = TRUE + /area/holodeck/holodorm/source_snow name = "\improper Holodeck Source" flags = RAD_SHIELDED | BLUE_SHIELDED soundproofed = TRUE + limit_mob_size = FALSE + block_suit_sensors = TRUE + /area/holodeck/holodorm/source_space name = "\improper Holodeck Source" flags = RAD_SHIELDED | BLUE_SHIELDED soundproofed = TRUE + limit_mob_size = FALSE + block_suit_sensors = TRUE + /area/holodeck/holodorm/source_off name = "\improper Holodeck Source" flags = RAD_SHIELDED | BLUE_SHIELDED soundproofed = TRUE + limit_mob_size = FALSE + block_suit_sensors = TRUE /area/ai_core_foyer name = "\improper AI Core Access" diff --git a/maps/tether/tether_defines.dm b/maps/tether/tether_defines.dm index bd903773521..c8c42c17456 100644 --- a/maps/tether/tether_defines.dm +++ b/maps/tether/tether_defines.dm @@ -164,9 +164,9 @@ ) lateload_single_pick = list( - list("Carp Farm"), - list("Snow Field"), - list("Listening Post") + //list("Carp Farm"), + //list("Snow Field"), + //list("Listening Post") ) ai_shell_restricted = TRUE diff --git a/maps/tether/tether_things.dm b/maps/tether/tether_things.dm index 52f999249ed..f511c9e1e82 100644 --- a/maps/tether/tether_things.dm +++ b/maps/tether/tether_things.dm @@ -368,6 +368,8 @@ var/global/list/latejoin_tram = list() ..() for(var/i = 1 to 2) new /obj/item/weapon/gun/energy/locked/frontier(src) + for(var/i = 1 to 2) + new /obj/item/weapon/gun/energy/locked/frontier/holdout(src) // Used at centcomm for the elevator /obj/machinery/cryopod/robot/door/dorms diff --git a/maps/tether_better/tether_things.dm b/maps/tether_better/tether_things.dm index 115f98abbd0..a2a1fdce051 100644 --- a/maps/tether_better/tether_things.dm +++ b/maps/tether_better/tether_things.dm @@ -368,6 +368,8 @@ var/global/list/latejoin_tram = list() ..() for(var/i = 1 to 2) new /obj/item/weapon/gun/energy/locked/frontier(src) + for(var/i = 1 to 2) + new /obj/item/weapon/gun/energy/locked/frontier/holdout(src) // Used at centcomm for the elevator /obj/machinery/cryopod/robot/door/dorms diff --git a/sound/effects/whistle.ogg b/sound/effects/whistle.ogg new file mode 100644 index 00000000000..c52de2f0724 Binary files /dev/null and b/sound/effects/whistle.ogg differ diff --git a/sound/items/confetti.ogg b/sound/items/confetti.ogg new file mode 100644 index 00000000000..d9b051089e2 Binary files /dev/null and b/sound/items/confetti.ogg differ diff --git a/sound/voice/Bug.ogg b/sound/voice/Bug.ogg new file mode 100644 index 00000000000..83486e436f2 Binary files /dev/null and b/sound/voice/Bug.ogg differ diff --git a/sound/voice/BugBuzz.ogg b/sound/voice/BugBuzz.ogg new file mode 100644 index 00000000000..43fda8be425 Binary files /dev/null and b/sound/voice/BugBuzz.ogg differ diff --git a/sound/voice/BugHiss.ogg b/sound/voice/BugHiss.ogg new file mode 100644 index 00000000000..3ab342f5c9d Binary files /dev/null and b/sound/voice/BugHiss.ogg differ diff --git a/sound/voice/cat_purr.ogg b/sound/voice/cat_purr.ogg new file mode 100644 index 00000000000..1125cb2bbd7 Binary files /dev/null and b/sound/voice/cat_purr.ogg differ diff --git a/sound/voice/cat_purr_long.ogg b/sound/voice/cat_purr_long.ogg new file mode 100644 index 00000000000..c74b845250d Binary files /dev/null and b/sound/voice/cat_purr_long.ogg differ diff --git a/sound/voice/moth/scream_moth.ogg b/sound/voice/moth/scream_moth.ogg new file mode 100644 index 00000000000..482086fb630 Binary files /dev/null and b/sound/voice/moth/scream_moth.ogg differ diff --git a/sound/voice/multichirp.ogg b/sound/voice/multichirp.ogg new file mode 100644 index 00000000000..2db358e942b Binary files /dev/null and b/sound/voice/multichirp.ogg differ diff --git a/sound/voice/quack.ogg b/sound/voice/quack.ogg new file mode 100644 index 00000000000..cdf3516e89c Binary files /dev/null and b/sound/voice/quack.ogg differ diff --git a/sound/voice/teshchirp.ogg b/sound/voice/teshchirp.ogg new file mode 100644 index 00000000000..f13c80dd335 Binary files /dev/null and b/sound/voice/teshchirp.ogg differ diff --git a/sound/voice/teshsqueak.ogg b/sound/voice/teshsqueak.ogg new file mode 100644 index 00000000000..41d205ab9fb Binary files /dev/null and b/sound/voice/teshsqueak.ogg differ diff --git a/sound/voice/teshtrill.ogg b/sound/voice/teshtrill.ogg new file mode 100644 index 00000000000..db30e988e53 Binary files /dev/null and b/sound/voice/teshtrill.ogg differ diff --git a/tgui/packages/tgui/components/Box.js b/tgui/packages/tgui/components/Box.js index 31bade26349..5443f72b07f 100644 --- a/tgui/packages/tgui/components/Box.js +++ b/tgui/packages/tgui/components/Box.js @@ -110,6 +110,7 @@ const styleMapperByPropName = { bold: mapBooleanPropTo('font-weight', 'bold'), italic: mapBooleanPropTo('font-style', 'italic'), nowrap: mapBooleanPropTo('white-space', 'nowrap'), + prewrap: mapBooleanPropTo('white-space', 'pre-wrap'), // Margins m: mapDirectionalUnitPropTo('margin', halfUnit, [ 'top', 'bottom', 'left', 'right', diff --git a/tgui/packages/tgui/components/LabeledList.js b/tgui/packages/tgui/components/LabeledList.js index 43dbd0d5a32..115eaea93c0 100644 --- a/tgui/packages/tgui/components/LabeledList.js +++ b/tgui/packages/tgui/components/LabeledList.js @@ -24,6 +24,7 @@ export const LabeledListItem = props => { buttons, content, children, + ...rest } = props; return ( { 'LabeledList__cell', 'LabeledList__content', ])} - colSpan={buttons ? undefined : 2}> + colSpan={buttons ? undefined : 2} + {...rest}> {content} {children} diff --git a/tgui/packages/tgui/interfaces/BodyScanner.js b/tgui/packages/tgui/interfaces/BodyScanner.js index b2500824737..9d324cd7656 100644 --- a/tgui/packages/tgui/interfaces/BodyScanner.js +++ b/tgui/packages/tgui/interfaces/BodyScanner.js @@ -496,6 +496,7 @@ const BodyScannerMainOrgansInternal = props => { {reduceOrganStatus([ germStatus(o.germ_level), + !!o.inflamed && "Appendicitis detected.", ])} diff --git a/tgui/packages/tgui/interfaces/CharacterDirectory.js b/tgui/packages/tgui/interfaces/CharacterDirectory.js index 43ba609cc19..589c50349e9 100644 --- a/tgui/packages/tgui/interfaces/CharacterDirectory.js +++ b/tgui/packages/tgui/interfaces/CharacterDirectory.js @@ -94,18 +94,18 @@ const ViewCharacter = (props, context) => {
- - {overlay.character_ad ? overlay.character_ad.split("\n").map((c, i) => {c}) : "Unset."} + + {overlay.character_ad || "Unset."}
- - {overlay.ooc_notes ? overlay.ooc_notes.split("\n").map((c, i) => {c}) : "Unset."} + + {overlay.ooc_notes || "Unset."}
- - {overlay.flavor_text ? overlay.flavor_text.split("\n").map((c, i) => {c}) : "Unset."} + + {overlay.flavor_text || "Unset."}
diff --git a/tgui/packages/tgui/interfaces/Cleanbot.js b/tgui/packages/tgui/interfaces/Cleanbot.js index 949b1794d9e..33a810b024e 100644 --- a/tgui/packages/tgui/interfaces/Cleanbot.js +++ b/tgui/packages/tgui/interfaces/Cleanbot.js @@ -12,6 +12,7 @@ export const Cleanbot = (props, context) => { version, blood, patrol, + vocal, wet_floors, spray_blood, rgbpanel, @@ -42,13 +43,37 @@ export const Cleanbot = (props, context) => { {!locked && (
- + + + + + + + + {/* VOREStation Edit: Not really used on Vore.*/} + {/* + + */} + {/* VOREStation Edit End */} +
) || null} {(!locked && open) && ( @@ -101,4 +126,4 @@ export const Cleanbot = (props, context) => { ); -}; \ No newline at end of file +}; diff --git a/tgui/packages/tgui/interfaces/CookingAppliance.js b/tgui/packages/tgui/interfaces/CookingAppliance.js index 44e68414857..2a2166c86b1 100644 --- a/tgui/packages/tgui/interfaces/CookingAppliance.js +++ b/tgui/packages/tgui/interfaces/CookingAppliance.js @@ -25,7 +25,7 @@ export const CookingAppliance = (props, context) => { + maxValue={optimalTemp}> °C / {optimalTemp}°C diff --git a/tgui/packages/tgui/interfaces/ExosuitFabricator.js b/tgui/packages/tgui/interfaces/ExosuitFabricator.js index 9063a4f3f8c..9d03d108cc9 100644 --- a/tgui/packages/tgui/interfaces/ExosuitFabricator.js +++ b/tgui/packages/tgui/interfaces/ExosuitFabricator.js @@ -5,6 +5,7 @@ import { formatSiUnit, formatMoney } from '../format'; import { Flex, Section, Tabs, Box, Button, Fragment, ProgressBar, NumberInput, Icon, Input, Tooltip } from '../components'; import { Window } from '../layouts'; import { createSearch, toTitleCase } from 'common/string'; +import { toFixed } from 'common/math'; const MATERIAL_KEYS = { "steel": "sheet-metal_3", @@ -41,7 +42,8 @@ const materialArrayToObj = materials => { let materialObj = {}; materials.forEach(m => { - materialObj[m.name] = m.amount; }); + materialObj[m.name] = m.amount; + }); return materialObj; }; @@ -147,7 +149,7 @@ export const ExosuitFabricator = (props, context) => { displayMatCost, setDisplayMatCost, ] = useSharedState(context, "display_mats", false); - + const [ displayAllMat, setDisplayAllMat, @@ -351,6 +353,18 @@ const MaterialAmount = (props, context) => { style, } = props; + let amountDisplay = "0"; + if (amount < 1 && amount > 0) { + amountDisplay = toFixed(amount, 2); + } else if (formatsi) { + amountDisplay = formatSiUnit(amount, 0); + } else if (formatmoney) { + amountDisplay = formatMoney(amount); + } else { + amountDisplay = amount; + } + + return ( { - {(formatsi && formatSiUnit(amount, 0)) - || (formatmoney && formatMoney(amount)) - || (amount)} + {amountDisplay} @@ -559,7 +571,7 @@ const PartCategory = (props, context) => { + @@ -602,7 +625,7 @@ const ResearchConsoleConstructor = (props, context) => { @@ -631,14 +654,14 @@ const ResearchConsoleConstructor = (props, context) => { disabled={!mat.removable} onClick={() => { setEjectAmt(0); - act("lathe_ejectsheet", { lathe_ejectsheet: mat.name, amount: ejectAmt }); + act(ejectSheetAction, { [ejectSheetAction]: mat.name, amount: ejectAmt }); }}> Num @@ -657,7 +680,7 @@ const ResearchConsoleConstructor = (props, context) => { @@ -670,7 +693,7 @@ const ResearchConsoleConstructor = (props, context) => { @@ -800,9 +823,11 @@ const ResearchConsoleSettings = (props, context) => { const menus = [ { name: "Protolathe", icon: "wrench", template: }, - { name: "Circuit Imprinter", + { + name: "Circuit Imprinter", icon: "digital-tachograph", - template: }, + template: , + }, { name: "Destructive Analyzer", icon: "eraser", template: }, { name: "Settings", icon: "cog", template: }, { name: "Research List", icon: "flask", template: }, diff --git a/tgui/packages/tgui/interfaces/Secbot.js b/tgui/packages/tgui/interfaces/Secbot.js index 9c2be5675a8..1257187f134 100644 --- a/tgui/packages/tgui/interfaces/Secbot.js +++ b/tgui/packages/tgui/interfaces/Secbot.js @@ -14,7 +14,8 @@ export const Secbot = (props, context) => { check_arrest, arrest_type, declare_arrests, - will_patrol, + bot_patrolling, + patrol, } = data; return ( @@ -80,13 +81,13 @@ export const Secbot = (props, context) => { {declare_arrests ? "Yes" : "No"} - {will_patrol && ( + {!!bot_patrolling && ( )} @@ -96,4 +97,4 @@ export const Secbot = (props, context) => { ); -}; \ No newline at end of file +}; diff --git a/tgui/packages/tgui/interfaces/SecurityRecords.js b/tgui/packages/tgui/interfaces/SecurityRecords.js index 4cdf09098ad..cd4f9cd00d0 100644 --- a/tgui/packages/tgui/interfaces/SecurityRecords.js +++ b/tgui/packages/tgui/interfaces/SecurityRecords.js @@ -179,8 +179,8 @@ const SecurityRecordsViewGeneral = (_properties, context) => { {general.fields.map((field, i) => ( - - {field.value.split("\n").map(m => {m})} + + {field.value} {!!field.edit && (