diff --git a/_build_dependencies.sh b/_build_dependencies.sh index b33548a58a0..835e8f81c23 100644 --- a/_build_dependencies.sh +++ b/_build_dependencies.sh @@ -8,6 +8,6 @@ export PHP_VERSION=5.6 # Byond Major export BYOND_MAJOR=513 # Byond Minor -export BYOND_MINOR=1526 +export BYOND_MINOR=1528 # Macro Count export MACRO_COUNT=4 \ No newline at end of file diff --git a/code/ATMOSPHERICS/pipes/pipe_base.dm b/code/ATMOSPHERICS/pipes/pipe_base.dm index e627fcbb46d..f95948868d3 100644 --- a/code/ATMOSPHERICS/pipes/pipe_base.dm +++ b/code/ATMOSPHERICS/pipes/pipe_base.dm @@ -128,7 +128,7 @@ return 1 playsound(src, W.usesound, 50, 1) to_chat(user, "You begin to unfasten \the [src]...") - if (do_after(user, 40 * W.toolspeed)) + if (do_after(user, 10 * W.toolspeed)) user.visible_message( \ "\The [user] unfastens \the [src].", \ "You have unfastened \the [src].", \ diff --git a/code/__defines/hoses.dm b/code/__defines/hoses.dm new file mode 100644 index 00000000000..2a7bd4d8031 --- /dev/null +++ b/code/__defines/hoses.dm @@ -0,0 +1,3 @@ +#define HOSE_INPUT "Input"// Only pull liquid. +#define HOSE_OUTPUT "Output"// Only push liquid. +#define HOSE_NEUTRAL "Neutral"// Equalize liquids, not super efficient, can waste reagents due to rounding. \ No newline at end of file diff --git a/code/__defines/misc.dm b/code/__defines/misc.dm index b3307066c3a..91b30ac228f 100644 --- a/code/__defines/misc.dm +++ b/code/__defines/misc.dm @@ -115,7 +115,7 @@ #define CUSTOM_ITEM_MOB 'icons/mob/custom_items_mob.dmi' #endif #ifndef CUSTOM_ITEM_SYNTH -#define CUSTOM_ITEM_SYNTH 'icons/mob/custom_synthetic.dmi' +#define CUSTOM_ITEM_SYNTH 'icons/mob/custom_synthetic_vr.dmi' //Vorestation edit #endif #define WALL_CAN_OPEN 1 @@ -462,3 +462,16 @@ var/global/list/##LIST_NAME = list();\ #define FONT_HUGE(X) "[X]" #define FONT_GIANT(X) "[X]" + +#define VOLUME_CHANNEL_MASTER "Master" +#define VOLUME_CHANNEL_AMBIENCE "Ambience" +#define VOLUME_CHANNEL_ALARMS "Alarms" +#define VOLUME_CHANNEL_VORE "Vore" + +// Make sure you update this or clients won't be able to adjust the channel +GLOBAL_LIST_INIT(all_volume_channels, list( + VOLUME_CHANNEL_MASTER, + VOLUME_CHANNEL_AMBIENCE, + VOLUME_CHANNEL_ALARMS, + VOLUME_CHANNEL_VORE, +)) \ No newline at end of file diff --git a/code/__defines/mobs.dm b/code/__defines/mobs.dm index da9220b3af8..ca0e186ac90 100644 --- a/code/__defines/mobs.dm +++ b/code/__defines/mobs.dm @@ -214,6 +214,13 @@ #define O_AUG_SPINE "spinal augment" #define O_AUG_PELVIC "pelvic augment" +// FBP components. + +#define O_PUMP "hydraulic hub" +#define O_CYCLER "reagent cycler" +#define O_HEATSINK "thermal regulator" +#define O_DIAGNOSTIC "diagnostic controller" + // Non-Standard organs #define O_MOUTH "mouth" #define O_CELL "cell" diff --git a/code/_global_vars/lists/misc.dm b/code/_global_vars/lists/misc.dm index adec2bf824f..e02c99290c7 100644 --- a/code/_global_vars/lists/misc.dm +++ b/code/_global_vars/lists/misc.dm @@ -2,4 +2,7 @@ GLOBAL_LIST_INIT(speech_toppings, list("|" = "i", "+" = "b", "_" = "u")) GLOBAL_LIST_EMPTY(meteor_list) /// List of wire colors for each object type of that round. One for airlocks, one for vendors, etc. -GLOBAL_LIST_EMPTY(wire_color_directory) // This is an associative list with the `holder_type` as the key, and a list of colors as the value. \ No newline at end of file +GLOBAL_LIST_EMPTY(wire_color_directory) // This is an associative list with the `holder_type` as the key, and a list of colors as the value. + +// Reference list for disposal sort junctions. Filled up by sorting junction's New() +GLOBAL_LIST_EMPTY(tagger_locations) \ No newline at end of file diff --git a/code/_helpers/global_lists.dm b/code/_helpers/global_lists.dm index d54635081d9..371f35b0515 100644 --- a/code/_helpers/global_lists.dm +++ b/code/_helpers/global_lists.dm @@ -9,6 +9,7 @@ var/global/list/ai_list = list() //List of all AIs, including clientless var/global/list/living_mob_list = list() //List of all alive mobs, including clientless. Excludes /mob/new_player var/global/list/dead_mob_list = list() //List of all dead mobs, including clientless. Excludes /mob/new_player var/global/list/listening_objects = list() //List of all objects which care about receiving messages (communicators, radios, etc) +var/global/list/cleanbot_reserved_turfs = list() //List of all turfs currently targeted by some cleanbot var/global/list/cable_list = list() //Index for all cables, so that powernets don't have to look through the entire world all the time var/global/list/landmarks_list = list() //list of all landmarks created diff --git a/code/_helpers/text.dm b/code/_helpers/text.dm index 1b028e117b7..02a8806089d 100644 --- a/code/_helpers/text.dm +++ b/code/_helpers/text.dm @@ -453,4 +453,36 @@ proc/TextPreview(var/string,var/len=40) . += .(rest) -#define gender2text(gender) capitalize(gender) \ No newline at end of file +#define gender2text(gender) capitalize(gender) + +/// Used to get a properly sanitized input, of max_length +/// no_trim is self explanatory but it prevents the input from being trimed if you intend to parse newlines or whitespace. +/proc/stripped_input(mob/user, message = "", title = "", default = "", max_length=MAX_MESSAGE_LEN, no_trim=FALSE) + var/name = input(user, message, title, default) as text|null + + if(no_trim) + return copytext(html_encode(name), 1, max_length) + else + return trim(html_encode(name), max_length) //trim is "outside" because html_encode can expand single symbols into multiple symbols (such as turning < into <) + +// Used to get a properly sanitized multiline input, of max_length +/proc/stripped_multiline_input(mob/user, message = "", title = "", default = "", max_length=MAX_MESSAGE_LEN, no_trim=FALSE) + var/name = input(user, message, title, default) as message|null + if(no_trim) + return copytext(html_encode(name), 1, max_length) + else + return trim(html_encode(name), max_length) + +//Adds 'char' ahead of 'text' until there are 'count' characters total +/proc/add_leading(text, count, char = " ") + text = "[text]" + var/charcount = count - length_char(text) + var/list/chars_to_add[max(charcount + 1, 0)] + return jointext(chars_to_add, char) + text + +//Adds 'char' behind 'text' until there are 'count' characters total +/proc/add_trailing(text, count, char = " ") + text = "[text]" + var/charcount = count - length_char(text) + var/list/chars_to_add[max(charcount + 1, 0)] + return text + jointext(chars_to_add, char) diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index afed5b2c542..98f6023e7d5 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -51,6 +51,9 @@ if(modifiers["shift"] && modifiers["ctrl"]) CtrlShiftClickOn(A) return 1 + if(modifiers["shift"] && modifiers["middle"]) + ShiftMiddleClickOn(A) + return 1 if(modifiers["middle"]) MiddleClickOn(A) return 1 @@ -111,12 +114,11 @@ trigger_aiming(TARGET_CAN_CLICK) return 1 - // VOREStation Addition Start: inbelly item interaction + // VOREStation Addition Start: inbelly interaction if(isbelly(loc) && (loc == A.loc)) if(W) - var/resolved = W.resolve_attackby(A,src) - if(!resolved && A && W) - W.afterattack(A, src, 1, params) // 1: clicking something Adjacent + to_chat(src, "The firm confines prevent that kind of dexterity!") //Only hand-based interactions in bellies + return else if(ismob(A)) // No instant mob attacking setClickCooldown(get_attack_speed()) @@ -230,6 +232,15 @@ return */ +/* + Shift middle click + Used for pointing. +*/ + +/mob/proc/ShiftMiddleClickOn(atom/A) + pointed(A) + return + /* Shift click For most mobs, examine. @@ -271,12 +282,15 @@ /atom/proc/AltClick(var/mob/user) var/turf/T = get_turf(src) if(T && user.TurfAdjacent(T)) - if(user.listed_turf == T) - user.listed_turf = null - else - user.listed_turf = T - user.client.statpanel = "Turf" + user.ToggleTurfTab(T) return 1 + +/mob/proc/ToggleTurfTab(var/turf/T) + if(listed_turf == T) + listed_turf = null + else + listed_turf = T + client.statpanel = "Turf" /mob/proc/TurfAdjacent(var/turf/T) return T.AdjacentQuick(src) diff --git a/code/_onclick/cyborg.dm b/code/_onclick/cyborg.dm index ab56dc6032d..d63d49e8d76 100644 --- a/code/_onclick/cyborg.dm +++ b/code/_onclick/cyborg.dm @@ -9,7 +9,7 @@ /mob/living/silicon/robot/ClickOn(var/atom/A, var/params) if(!checkClickCooldown()) return - + setClickCooldown(1) if(client.buildmode) // comes after object.Click to allow buildmode gui objects to be clicked @@ -20,6 +20,9 @@ if(modifiers["shift"] && modifiers["ctrl"]) CtrlShiftClickOn(A) return + if(modifiers["shift"] && modifiers["middle"]) + ShiftMiddleClickOn(A) + return if(modifiers["middle"]) MiddleClickOn(A) return diff --git a/code/_onclick/observer.dm b/code/_onclick/observer.dm index 485df1de418..c2a8a62ea8d 100644 --- a/code/_onclick/observer.dm +++ b/code/_onclick/observer.dm @@ -33,6 +33,15 @@ return if(!checkClickCooldown()) return setClickCooldown(4) + var/list/modifiers = params2list(params) + if(modifiers["shift"]) + examinate(A) + return + if(modifiers["alt"]) // alt and alt-gr (rightalt) + var/turf/T = get_turf(A) + if(T && TurfAdjacent(T)) + ToggleTurfTab(T) + return // You are responsible for checking config.ghost_interaction when you override this function // Not all of them require checking, see below A.attack_ghost(src) diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index ed77065e19f..71384823012 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -236,7 +236,8 @@ var/list/gamemode_cache = list() var/static/dooc_allowed = 1 var/static/dsay_allowed = 1 - var/persistence_enabled = 1 + var/persistence_disabled = FALSE + var/persistence_ignore_mapload = FALSE var/allow_byond_links = 0 var/allow_discord_links = 0 @@ -579,8 +580,11 @@ var/list/gamemode_cache = list() if("protect_roles_from_antagonist") config.protect_roles_from_antagonist = 1 - if ("persistence_enabled") - config.persistence_enabled = 1 + if("persistence_disabled") + config.persistence_disabled = TRUE // Previously this forcibly set persistence enabled in the saves. + + if("persistence_ignore_mapload") + config.persistence_ignore_mapload = TRUE if ("probability") var/prob_pos = findtext(value, " ") diff --git a/code/controllers/subsystems/persistence.dm b/code/controllers/subsystems/persistence.dm index 49f3d601fee..c2724c2d609 100644 --- a/code/controllers/subsystems/persistence.dm +++ b/code/controllers/subsystems/persistence.dm @@ -19,7 +19,7 @@ SUBSYSTEM_DEF(persistence) /datum/controller/subsystem/persistence/proc/track_value(var/atom/value, var/track_type) - if(config.persistence_enabled == 0) //if the config is not set to persistent nothing will save or load. + if(config.persistence_disabled) //if the config is set to persistence disabled, nothing will save or load. return var/turf/T = get_turf(value) diff --git a/code/datums/autolathe/general.dm b/code/datums/autolathe/general.dm index a2dcd047c9c..8ee77ce6564 100644 --- a/code/datums/autolathe/general.dm +++ b/code/datums/autolathe/general.dm @@ -6,38 +6,49 @@ name = "water-cooler bottle" path =/obj/item/weapon/reagent_containers/glass/cooler_bottle -/datum/category_item/autolathe/general/drinkingglass_square +/datum/category_item/autolathe/general/drinkingglass + is_stack = TRUE + +/datum/category_item/autolathe/general/drinkingglass/square name = "half-pint glass" path =/obj/item/weapon/reagent_containers/food/drinks/glass2/square -/datum/category_item/autolathe/general/drinkingglass_rocks +/datum/category_item/autolathe/general/drinkingglass/rocks name = "rocks glass" path =/obj/item/weapon/reagent_containers/food/drinks/glass2/rocks -/datum/category_item/autolathe/general/drinkingglass_shake +/datum/category_item/autolathe/general/drinkingglass/shake name = "milkshake glass" path =/obj/item/weapon/reagent_containers/food/drinks/glass2/shake -/datum/category_item/autolathe/general/drinkingglass_cocktail +/datum/category_item/autolathe/general/drinkingglass/cocktail name = "cocktail glass" path =/obj/item/weapon/reagent_containers/food/drinks/glass2/cocktail -/datum/category_item/autolathe/general/drinkingglass_shot +/datum/category_item/autolathe/general/drinkingglass/shot name = "shot glass" path =/obj/item/weapon/reagent_containers/food/drinks/glass2/shot -/datum/category_item/autolathe/general/drinkingglass_pint +/datum/category_item/autolathe/general/drinkingglass/pint name = "pint glass" path =/obj/item/weapon/reagent_containers/food/drinks/glass2/pint -/datum/category_item/autolathe/general/drinkingglass_mug +/datum/category_item/autolathe/general/drinkingglass/mug name = "glass mug" path =/obj/item/weapon/reagent_containers/food/drinks/glass2/mug -/datum/category_item/autolathe/general/drinkingglass_wine +/datum/category_item/autolathe/general/drinkingglass/wine name = "wine glass" path =/obj/item/weapon/reagent_containers/food/drinks/glass2/wine +/datum/category_item/autolathe/general/drinkingglass/metaglass + name = "metamorphic glass" + path =/obj/item/weapon/reagent_containers/food/drinks/metaglass + +/datum/category_item/autolathe/general/drinkingglass/metaglass/metapint + name = "metamorphic pint glass" + path =/obj/item/weapon/reagent_containers/food/drinks/metaglass/metapint + /datum/category_item/autolathe/general/flashlight name = "flashlight" path =/obj/item/device/flashlight diff --git a/code/datums/autolathe/general_vr.dm b/code/datums/autolathe/general_vr.dm index e1fb7ad46f0..5702a7ed499 100644 --- a/code/datums/autolathe/general_vr.dm +++ b/code/datums/autolathe/general_vr.dm @@ -2,40 +2,11 @@ name = "Holo-collar" path =/obj/item/clothing/accessory/collar/holo -/datum/category_item/autolathe/general/drinkingglass_square - is_stack = TRUE - -/datum/category_item/autolathe/general/drinkingglass_rocks - is_stack = TRUE - -/datum/category_item/autolathe/general/drinkingglass_shake - is_stack = TRUE - -/datum/category_item/autolathe/general/drinkingglass_cocktail - is_stack = TRUE - -/datum/category_item/autolathe/general/drinkingglass_shot - is_stack = TRUE - -/datum/category_item/autolathe/general/drinkingglass_pint - is_stack = TRUE - -/datum/category_item/autolathe/general/drinkingglass_mug - is_stack = TRUE - -/datum/category_item/autolathe/general/drinkingglass_wine - is_stack = TRUE - -/datum/category_item/autolathe/general/metaglass - name = "metamorphic glass" - path =/obj/item/weapon/reagent_containers/food/drinks/metaglass - is_stack = TRUE - -/datum/category_item/autolathe/general/drinkingglass_carafe +/datum/category_item/autolathe/general/drinkingglass/carafe name = "glass carafe" path =/obj/item/weapon/reagent_containers/food/drinks/glass2/carafe -/datum/category_item/autolathe/general/drinkingglass_pitcher +/datum/category_item/autolathe/general/drinkingglass/pitcher name = "plastic pitcher" path =/obj/item/weapon/reagent_containers/food/drinks/glass2/pitcher \ No newline at end of file diff --git a/code/datums/autolathe/tools.dm b/code/datums/autolathe/tools.dm index d0aa2aa196b..9e9a87ea71f 100644 --- a/code/datums/autolathe/tools.dm +++ b/code/datums/autolathe/tools.dm @@ -42,3 +42,15 @@ /datum/category_item/autolathe/tools/welder_industrial name = "industrial welding tool" path =/obj/item/weapon/weldingtool/largetank + +/datum/category_item/autolathe/tools/spraybottle + name = "spray bottle" + path = /obj/item/weapon/reagent_containers/spray + resources = list(MAT_PLASTIC = 2000) + +/datum/category_item/autolathe/tools/spraynozzle + name = "spray nozzle" + path = /obj/item/weapon/reagent_containers/spray + resources = list(MAT_PLASTIC = 5000, DEFAULT_WALL_MATERIAL = 2000) + hidden = 1 + man_rating = 2 diff --git a/code/datums/beam.dm b/code/datums/beam.dm index a35abf8c370..fc4e696702f 100644 --- a/code/datums/beam.dm +++ b/code/datums/beam.dm @@ -6,6 +6,7 @@ var/icon/base_icon = null var/icon var/icon_state = "" //icon state of the main segments of the beam + var/beam_color = null // Color of the beam segments var/max_distance = 0 var/endtime = 0 var/sleep_time = 3 @@ -15,7 +16,7 @@ var/static_beam = 0 var/beam_type = /obj/effect/ebeam //must be subtype -/datum/beam/New(beam_origin,beam_target,beam_icon='icons/effects/beam.dmi',beam_icon_state="b_beam",time=50,maxdistance=10,btype = /obj/effect/ebeam,beam_sleep_time=3) +/datum/beam/New(beam_origin,beam_target,beam_icon='icons/effects/beam.dmi',beam_icon_state="b_beam",time=50,maxdistance=10,btype = /obj/effect/ebeam,beam_sleep_time=3,new_beam_color = null) endtime = world.time+time origin = beam_origin origin_oldloc = get_turf(origin) @@ -28,6 +29,8 @@ base_icon = new(beam_icon,beam_icon_state) icon = beam_icon icon_state = beam_icon_state + if(new_beam_color) + beam_color = new_beam_color beam_type = btype /datum/beam/proc/Start() @@ -68,9 +71,12 @@ var/matrix/rot_matrix = matrix() rot_matrix.Turn(Angle) + var/turf/T_target = get_turf(target) //Turfs are referenced instead of the objects directly so that beams will link between 2 objects inside other objects. + var/turf/T_origin = get_turf(origin) + //Translation vector for origin and target - var/DX = (32*target.x+target.pixel_x)-(32*origin.x+origin.pixel_x) - var/DY = (32*target.y+target.pixel_y)-(32*origin.y+origin.pixel_y) + var/DX = (32*T_target.x+target.pixel_x)-(32*T_origin.x+origin.pixel_x) + var/DY = (32*T_target.y+target.pixel_y)-(32*T_origin.y+origin.pixel_y) var/N = 0 var/length = round(sqrt((DX)**2+(DY)**2)) //hypotenuse of the triangle formed by target and origin's displacement @@ -78,6 +84,10 @@ if(QDELETED(src) || finished) break var/obj/effect/ebeam/X = new beam_type(origin_oldloc) + + if(beam_color) + X.color = beam_color + X.owner = src elements |= X @@ -184,8 +194,8 @@ -/atom/proc/Beam(atom/BeamTarget,icon_state="b_beam",icon='icons/effects/beam.dmi',time=50, maxdistance=10,beam_type=/obj/effect/ebeam,beam_sleep_time=3) - var/datum/beam/newbeam = new(src,BeamTarget,icon,icon_state,time,maxdistance,beam_type,beam_sleep_time) +/atom/proc/Beam(atom/BeamTarget,icon_state="b_beam",icon='icons/effects/beam.dmi',time=50, maxdistance=10,beam_type=/obj/effect/ebeam,beam_sleep_time=3,beam_color = null) + var/datum/beam/newbeam = new(src,BeamTarget,icon,icon_state,time,maxdistance,beam_type,beam_sleep_time,beam_color) spawn(0) newbeam.Start() return newbeam diff --git a/code/datums/supplypacks/hospitality.dm b/code/datums/supplypacks/hospitality.dm index 2c9bbbce518..c776317ffad 100644 --- a/code/datums/supplypacks/hospitality.dm +++ b/code/datums/supplypacks/hospitality.dm @@ -38,6 +38,7 @@ /obj/item/weapon/storage/box/glasses/shot, /obj/item/weapon/storage/box/glasses/mug, /obj/item/weapon/storage/box/glasses/meta, + /obj/item/weapon/storage/box/glasses/meta/metapint, /obj/item/weapon/reagent_containers/food/drinks/shaker, /obj/item/weapon/storage/box/glass_extras/straws, /obj/item/weapon/storage/box/glass_extras/sticks @@ -57,13 +58,13 @@ group = "Hospitality" /datum/supply_pack/randomised/hospitality/pizza - num_contained = 5 contains = list( - /obj/item/pizzabox/margherita, - /obj/item/pizzabox/mushroom, - /obj/item/pizzabox/meat, - /obj/item/pizzabox/vegetable, - /obj/item/pizzabox/pineapple + /obj/random/pizzabox, + /obj/random/pizzabox, + /obj/random/pizzabox, + /obj/random/pizzabox, + /obj/random/pizzabox, + /obj/item/weapon/material/knife/plastic ) name = "Surprise pack of five pizzas" cost = 15 diff --git a/code/datums/supplypacks/medical.dm b/code/datums/supplypacks/medical.dm index 3edcbed2008..1307b8f985b 100644 --- a/code/datums/supplypacks/medical.dm +++ b/code/datums/supplypacks/medical.dm @@ -29,21 +29,21 @@ name = "BloodPack crate" contains = list(/obj/item/weapon/storage/box/bloodpacks = 3) cost = 10 - containertype = /obj/structure/closet/crate/nanocare + containertype = /obj/structure/closet/crate/nanomed containername = "BloodPack crate" /datum/supply_pack/med/bodybag name = "Body bag crate" contains = list(/obj/item/weapon/storage/box/bodybags = 3) cost = 10 - containertype = /obj/structure/closet/crate/nanocare + containertype = /obj/structure/closet/crate/nanomed containername = "Body bag crate" /datum/supply_pack/med/cryobag name = "Stasis bag crate" contains = list(/obj/item/bodybag/cryobag = 3) cost = 40 - containertype = /obj/structure/closet/crate/nanocare + containertype = /obj/structure/closet/crate/nanomed containername = "Stasis bag crate" /datum/supply_pack/med/surgery @@ -109,7 +109,7 @@ /obj/item/clothing/suit/storage/hooded/wintercoat/medical = 3 ) cost = 10 - containertype = /obj/structure/closet/crate/secure/nanocare + containertype = /obj/structure/closet/crate/secure/nanomed containername = "Medical surplus equipment" access = access_medical @@ -133,7 +133,7 @@ /obj/item/weapon/reagent_containers/syringe ) cost = 50 - containertype = /obj/structure/closet/crate/secure/nanocare + containertype = /obj/structure/closet/crate/secure/nanomed containername = "Chief medical officer equipment" access = access_cmo @@ -156,7 +156,7 @@ /obj/item/weapon/reagent_containers/syringe ) cost = 20 - containertype = /obj/structure/closet/crate/secure/nanocare + containertype = /obj/structure/closet/crate/secure/nanomed containername = "Medical Doctor equipment" access = access_medical_equip @@ -179,7 +179,7 @@ /obj/item/weapon/reagent_containers/syringe ) cost = 20 - containertype = /obj/structure/closet/crate/secure/nanocare + containertype = /obj/structure/closet/crate/secure/nanomed containername = "Chemist equipment" access = access_chemistry @@ -207,7 +207,7 @@ /obj/item/clothing/accessory/storage/white_vest ) cost = 20 - containertype = /obj/structure/closet/crate/secure/nanocare + containertype = /obj/structure/closet/crate/secure/nanomed containername = "Paramedic equipment" access = access_medical_equip @@ -226,7 +226,7 @@ /obj/item/weapon/cartridge/medical ) cost = 20 - containertype = /obj/structure/closet/crate/secure/nanocare + containertype = /obj/structure/closet/crate/secure/nanomed containername = "Psychiatrist equipment" access = access_psychiatrist @@ -247,7 +247,7 @@ /obj/item/weapon/storage/box/gloves ) cost = 10 - containertype = /obj/structure/closet/crate/secure/nanocare + containertype = /obj/structure/closet/crate/secure/nanomed containername = "Medical scrubs crate" access = access_medical_equip @@ -291,7 +291,7 @@ /obj/item/weapon/storage/box/gloves ) cost = 10 - containertype = /obj/structure/closet/crate/secure/nanocare + containertype = /obj/structure/closet/crate/secure/nanomed containername = "Medical uniform crate" access = access_medical_equip @@ -309,7 +309,7 @@ /obj/item/weapon/storage/box/gloves ) cost = 50 - containertype = /obj/structure/closet/crate/secure/nanocare + containertype = /obj/structure/closet/crate/secure/nanomed containername = "Medical biohazard equipment" access = access_medical_equip diff --git a/code/datums/supplypacks/misc.dm b/code/datums/supplypacks/misc.dm index db46de1e047..0aa29b7b9c9 100644 --- a/code/datums/supplypacks/misc.dm +++ b/code/datums/supplypacks/misc.dm @@ -189,3 +189,12 @@ cost = 40 containertype = /obj/structure/closet/crate/zenghu containername = "emergency rations" + +/datum/supply_pack/misc/reagentpump + name = "Machine - Pump" + contains = list( + /obj/machinery/pump = 1 + ) + cost = 60 + containertype = /obj/structure/closet/crate/large/xion + containername = "pump crate" diff --git a/code/datums/supplypacks/supply.dm b/code/datums/supplypacks/supply.dm index e9fa3f2d998..9414d6201d5 100644 --- a/code/datums/supplypacks/supply.dm +++ b/code/datums/supplypacks/supply.dm @@ -39,7 +39,7 @@ /obj/item/clothing/head/soft/purple, /obj/item/weapon/storage/belt/janitor, /obj/item/clothing/shoes/galoshes, - /obj/item/weapon/caution = 4, + /obj/item/clothing/suit/caution = 4, /obj/item/weapon/storage/bag/trash, /obj/item/device/lightreplacer, /obj/item/weapon/reagent_containers/spray/cleaner, diff --git a/code/datums/supplypacks/voidsuits.dm b/code/datums/supplypacks/voidsuits.dm index a867b20255a..2066c216d30 100644 --- a/code/datums/supplypacks/voidsuits.dm +++ b/code/datums/supplypacks/voidsuits.dm @@ -129,7 +129,7 @@ /obj/item/weapon/tank/oxygen = 2 ) cost = 45 - containertype = /obj/structure/closet/crate/secure/nanocare + containertype = /obj/structure/closet/crate/secure/nanomed containername = "Medical Biohazard voidsuit crate" access = access_medical_equip diff --git a/code/defines/obj/weapon.dm b/code/defines/obj/weapon.dm index 99c0f753c8a..8e7ccb4070c 100644 --- a/code/defines/obj/weapon.dm +++ b/code/defines/obj/weapon.dm @@ -110,28 +110,6 @@ item_state = "gift" w_class = ITEMSIZE_LARGE -/obj/item/weapon/caution - desc = "Caution! Wet Floor!" - name = "wet floor sign" - icon = 'icons/obj/janitor.dmi' - icon_state = "caution" - force = 1.0 - throwforce = 3.0 - throw_speed = 1 - throw_range = 5 - w_class = ITEMSIZE_SMALL - attack_verb = list("warned", "cautioned", "smashed") - -/obj/item/weapon/caution/cone - desc = "This cone is trying to warn you of something!" - name = "warning cone" - icon_state = "cone" - -/obj/item/weapon/caution/cone/candy - desc = "This cone is trying to warn you of something! It has been painted to look like candy corn." - name = "candy cone" - icon_state = "candycone" - /*/obj/item/weapon/syndicate_uplink name = "station bounced radio" desc = "Remain silent about this..." diff --git a/code/game/area/Space Station 13 areas.dm b/code/game/area/Space Station 13 areas.dm index 4d4533b4b31..fe1d3116748 100755 --- a/code/game/area/Space Station 13 areas.dm +++ b/code/game/area/Space Station 13 areas.dm @@ -1736,7 +1736,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station temp_closet.locked = 0 temp_closet.icon_state = "closed_unlocked" for(var/obj/machinery/door_timer/temp_timer in src) - temp_timer.releasetime = 1 + temp_timer.timer_duration = 1 ..() /area/security/prison @@ -1748,7 +1748,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station temp_closet.locked = 0 temp_closet.icon_state = "closed_unlocked" for(var/obj/machinery/door_timer/temp_timer in src) - temp_timer.releasetime = 1 + temp_timer.timer_duration = 1 ..() /area/security/warden diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index e69ce8cfed5..04075fe8255 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -377,8 +377,11 @@ var/list/mob/living/forced_ambiance_list = new /area/proc/play_ambience(var/mob/living/L, initial = TRUE) // Ambience goes down here -- make sure to list each area seperately for ease of adding things in later, thanks! Note: areas adjacent to each other should have the same sounds to prevent cutoff when possible.- LastyScratch - if(!(L && L.is_preference_enabled(/datum/client_preference/play_ambiance))) return - + if(!(L && L.is_preference_enabled(/datum/client_preference/play_ambiance))) + return + + var/volume_mod = L.get_preference_volume_channel(VOLUME_CHANNEL_AMBIENCE) + // If we previously were in an area with force-played ambiance, stop it. if((L in forced_ambiance_list) && initial) L << sound(null, channel = CHANNEL_AMBIENCE_FORCED) @@ -392,6 +395,7 @@ var/list/mob/living/forced_ambiance_list = new var/sound/chosen_ambiance = pick(forced_ambience) if(!istype(chosen_ambiance)) chosen_ambiance = sound(chosen_ambiance, repeat = 1, wait = 0, volume = 25, channel = CHANNEL_AMBIENCE_FORCED) + chosen_ambiance.volume *= volume_mod L << chosen_ambiance else L << sound(null, channel = CHANNEL_AMBIENCE_FORCED) @@ -399,7 +403,7 @@ var/list/mob/living/forced_ambiance_list = new var/ambience_odds = L?.client.prefs.ambience_chance if(prob(ambience_odds) && (world.time >= L.client.time_last_ambience_played + 1 MINUTE)) var/sound = pick(ambience) - L << sound(sound, repeat = 0, wait = 0, volume = 50, channel = CHANNEL_AMBIENCE) + L << sound(sound, repeat = 0, wait = 0, volume = 50 * volume_mod, channel = CHANNEL_AMBIENCE) L.client.time_last_ambience_played = world.time /area/proc/gravitychange(var/gravitystate = 0) diff --git a/code/game/gamemodes/events.dm b/code/game/gamemodes/events.dm index 083a90fc094..0136314d588 100644 --- a/code/game/gamemodes/events.dm +++ b/code/game/gamemodes/events.dm @@ -196,7 +196,7 @@ var/hadevent = 0 spawn(0) temp_glassairlock.prison_open() for (var/obj/machinery/door_timer/temp_timer in A) - temp_timer.releasetime = 1 + temp_timer.timer_duration = 1 sleep(150) command_announcement.Announce("Gr3y.T1d3 virus detected in [station_name()] imprisonment subroutines. Recommend station AI involvement.", "Security Alert") diff --git a/code/game/jobs/job/security.dm b/code/game/jobs/job/security.dm index 684e9cc7c1c..a36ad973013 100644 --- a/code/game/jobs/job/security.dm +++ b/code/game/jobs/job/security.dm @@ -77,7 +77,7 @@ spawn_positions = 2 supervisors = "the Head of Security" selection_color = "#601C1C" - access = list(access_security, access_sec_doors, access_forensics_lockers, access_morgue, access_maint_tunnels, access_eva, access_external_airlocks) + access = list(access_security, access_sec_doors, access_forensics_lockers, access_morgue, access_maint_tunnels, access_eva, access_external_airlocks, access_brig) //Vorestation edit - access_brig minimal_access = list(access_security, access_sec_doors, access_forensics_lockers, access_morgue, access_maint_tunnels, access_eva, access_external_airlocks) economic_modifier = 5 minimal_player_age = 3 diff --git a/code/game/machinery/atmoalter/canister.dm b/code/game/machinery/atmoalter/canister.dm index 7faf1115fe8..0b7c96e08a6 100644 --- a/code/game/machinery/atmoalter/canister.dm +++ b/code/game/machinery/atmoalter/canister.dm @@ -281,7 +281,7 @@ update_flag /obj/machinery/portable_atmospherics/canister/tgui_data(mob/user) var/list/data = list() - data["canLabel"] = can_label ? 1 : 0 + data["can_relabel"] = can_label ? 1 : 0 data["connected"] = connected_port ? 1 : 0 data["pressure"] = round(air_contents.return_pressure() ? air_contents.return_pressure() : 0) data["releasePressure"] = round(release_pressure ? release_pressure : 0) diff --git a/code/game/machinery/bomb_tester_vr.dm b/code/game/machinery/bomb_tester_vr.dm index b4f3b192ed4..483d6e3fb30 100644 --- a/code/game/machinery/bomb_tester_vr.dm +++ b/code/game/machinery/bomb_tester_vr.dm @@ -209,29 +209,28 @@ updateUsrDialog() /obj/machinery/bomb_tester/proc/start_simulating() + if(!tank1 || (sim_mode == MODE_DOUBLE && !tank2) || (sim_mode == MODE_CANISTER && !test_canister)) + simulation_results = "Error" + simulation_finish() + return + if(tank1?.integrity < tank1?.maxintegrity || tank2?.integrity < tank2?.maxintegrity) + simulation_results = "Unstable" + simulation_finish() + return simulating = 1 update_use_power(USE_POWER_ACTIVE) simulation_started = world.time update_icon() switch(sim_mode) if(MODE_SINGLE) - if(!tank1) - simulation_results = "Error" - return spawn() single_tank_sim() if(MODE_DOUBLE) - if(!tank1 || !tank2) - simulation_results = "Error" - return spawn() ttv_sim() if(MODE_CANISTER) - if(!tank1 || !test_canister) - simulation_results = "Error" - return spawn() canister_sim() @@ -361,6 +360,9 @@ if(simulation_results == "Error") playsound(src, 'sound/machines/buzz-sigh.ogg', 50, 0) state("Invalid parameters.") + else if(simulation_results == "Unstable") + playsound(src, 'sound/machines/buzz-two.ogg', 50, 0) + state("Tank instability detected. Please step away from the device.") else ping("Simulation complete!") playsound(src, "sound/effects/printer.ogg", 50, 1) @@ -383,4 +385,4 @@ #undef MODE_SINGLE #undef MODE_DOUBLE -#undef MODE_CANISTER \ No newline at end of file +#undef MODE_CANISTER diff --git a/code/game/machinery/computer/medical.dm b/code/game/machinery/computer/medical.dm index f775bed4c36..f3c930fe785 100644 --- a/code/game/machinery/computer/medical.dm +++ b/code/game/machinery/computer/medical.dm @@ -442,7 +442,7 @@
\n
Comments/Log

"} for(var/c in active2.fields["comments"]) - P.info += "[c]
" + P.info += "[c["header"]]
[c["text"]]
" else P.info += "Medical Record Lost!
" P.info += "" diff --git a/code/game/machinery/computer/prisoner.dm b/code/game/machinery/computer/prisoner.dm index 9e09339f479..9932934a83d 100644 --- a/code/game/machinery/computer/prisoner.dm +++ b/code/game/machinery/computer/prisoner.dm @@ -15,90 +15,81 @@ var/stop = 0.0 var/screen = 0 // 0 - No Access Denied, 1 - Access allowed - - attack_ai(var/mob/user as mob) - return src.attack_hand(user) - - attack_hand(var/mob/user as mob) - if(..()) - return - user.set_machine(src) - var/dat - dat += "Prisoner Implant Manager System
" - if(screen == 0) - dat += "
Unlock Console" - else if(screen == 1) - dat += "
Chemical Implants
" - var/turf/Tr = null - for(var/obj/item/weapon/implant/chem/C in all_chem_implants) - Tr = get_turf(C) - if(!Tr) continue//Out of range - if(!C.implanted) continue - dat += "[C.imp_in.name] | Remaining Units: [C.reagents.total_volume] | Inject: " - dat += "((1))" - dat += "((5))" - dat += "((10))
" - dat += "********************************
" - dat += "
Tracking Implants
" - for(var/obj/item/weapon/implant/tracking/T in all_tracking_implants) - Tr = get_turf(T) - if(!Tr) continue//Out of range - if(!T.implanted) continue - var/loc_display = "Unknown" - var/mob/living/carbon/M = T.imp_in - if((M.z in using_map.station_levels) && !istype(M.loc, /turf/space)) - var/turf/mob_loc = get_turf(M) - loc_display = mob_loc.loc - if(T.malfunction) - loc_display = pick(teleportlocs) - dat += "ID: [T.id] | Location: [loc_display]
" - dat += "(Message Holder) |
" - dat += "********************************
" - dat += "
Lock Console" - - user << browse(dat, "window=computer;size=400x500") - onclose(user, "computer") +/obj/machinery/computer/prisoner/attack_hand(mob/user) + if(..()) return + tgui_interact(user) +/obj/machinery/computer/prisoner/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "PrisonerManagement", name) + ui.open() - process() - if(!..()) - src.updateDialog() - return +/obj/machinery/computer/prisoner/tgui_data(mob/user) + var/list/data = list() + + data["locked"] = !screen + data["chemImplants"] = list() + data["trackImplants"] = list() + if(screen) + for(var/obj/item/weapon/implant/chem/C in all_chem_implants) + var/turf/T = get_turf(C) + if(!T) + continue + if(!C.implanted) + continue + data["chemImplants"].Add(list(list( + "host" = C.imp_in, + "units" = C.reagents.total_volume, + "ref" = "\ref[C]" + ))) + for(var/obj/item/weapon/implant/tracking/track in all_tracking_implants) + var/turf/T = get_turf(track) + if(!T) + continue + if(!track.implanted) + continue + var/loc_display = "Unknown" + var/mob/living/L = track.imp_in + if((get_z(L) in using_map.station_levels) && !istype(L.loc, /turf/space)) + loc_display = T.loc + if(track.malfunction) + loc_display = pick(teleportlocs) + data["trackImplants"].Add(list(list( + "host" = L, + "ref" = "\ref[track]", + "id" = "[track.id]", + "loc" = "[loc_display]", + ))) + return data - Topic(href, href_list) - if(..()) - return - if((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon))) - usr.set_machine(src) +/obj/machinery/computer/prisoner/tgui_act(action, list/params) + if(..()) + return TRUE - if(href_list["inject1"]) - var/obj/item/weapon/implant/I = locate(href_list["inject1"]) - if(I) I.activate(1) + switch(action) + if("inject") + var/obj/item/weapon/implant/I = locate(params["imp"]) + if(I) + I.activate(clamp(params["val"], 0, 10)) + . = TRUE - else if(href_list["inject5"]) - var/obj/item/weapon/implant/I = locate(href_list["inject5"]) - if(I) I.activate(5) + if("lock") + if(allowed(usr)) + screen = !screen + else + to_chat(usr, "Unauthorized Access.") + . = TRUE - else if(href_list["inject10"]) - var/obj/item/weapon/implant/I = locate(href_list["inject10"]) - if(I) I.activate(10) + if("warn") + var/warning = sanitize(input(usr, "Message:", "Enter your message here!", "")) + if(!warning) + return + var/obj/item/weapon/implant/I = locate(params["imp"]) + if(I && I.imp_in) + to_chat(I.imp_in, "You hear a voice in your head saying: '[warning]'") + . = TRUE - else if(href_list["lock"]) - if(src.allowed(usr)) - screen = !screen - else - to_chat(usr, "Unauthorized Access.") - - else if(href_list["warn"]) - var/warning = sanitize(input(usr,"Message:","Enter your message here!","")) - if(!warning) return - var/obj/item/weapon/implant/I = locate(href_list["warn"]) - if((I)&&(I.imp_in)) - var/mob/living/carbon/R = I.imp_in - to_chat(R, "You hear a voice in your head saying: '[warning]'") - - src.add_fingerprint(usr) - src.updateUsrDialog() - return + add_fingerprint(usr) diff --git a/code/game/machinery/computer/security.dm b/code/game/machinery/computer/security.dm index 2d9353a640d..be93c2ce4fd 100644 --- a/code/game/machinery/computer/security.dm +++ b/code/game/machinery/computer/security.dm @@ -1,4 +1,8 @@ -//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31 +#define SEC_DATA_R_LIST 2 // Record list +#define SEC_DATA_MAINT 3 // Records maintenance +#define SEC_DATA_RECORD 4 // Record + +#define FIELD(N, V, E) list(field = N, value = V, edit = E) /obj/machinery/computer/secure_data//TODO:SANITY name = "security records console" @@ -14,15 +18,42 @@ var/screen = null var/datum/data/record/active1 = null var/datum/data/record/active2 = null - var/a_id = null - var/temp = null + var/list/temp = null var/printing = null - var/can_change_id = 0 - var/list/Perp - var/tempname = null - //Sorting Variables - var/sortBy = "name" - var/order = 1 // -1 = Descending - 1 = Ascending + // The below are used to make modal generation more convenient + var/static/list/field_edit_questions + var/static/list/field_edit_choices + +/obj/machinery/computer/secure_data/Initialize() + ..() + field_edit_questions = list( + // General + "name" = "Please enter new name:", + "id" = "Please enter new id:", + "sex" = "Please select new sex:", + "age" = "Please input new age:", + "rank" = "Please enter new rank:", + "fingerprint" = "Please input new fingerprint hash:", + // Security + "brain_type" = "Please select new brain type:", + "criminal" = "Please select new criminal status:", + "mi_crim" = "Please input new minor crime:", + "mi_crim_d" = "Please input minor crime summary.", + "ma_crim" = "Please input new major crime:", + "ma_crim_d" = "Please input new major crime summary.", + "notes" = "Please input new important notes:", + ) + field_edit_choices = list( + // General + "sex" = all_genders_text_list, + // Security + "criminal" = list("*Arrest*", "Incarcerated", "Parolled", "Released", "None"), + ) + +/obj/machinery/computer/secure_data/Destroy() + active1 = null + active2 = null + return ..() /obj/machinery/computer/secure_data/verb/eject_id() set category = "Object" @@ -41,13 +72,14 @@ to_chat(usr, "There is nothing to remove from the console.") return -/obj/machinery/computer/secure_data/attackby(obj/item/O as obj, user as mob) - if(istype(O, /obj/item/weapon/card/id) && !scan) - usr.drop_item() +/obj/machinery/computer/secure_data/attackby(var/obj/item/O, var/mob/user) + if(istype(O, /obj/item/weapon/card/id) && !scan && user.unEquip(O)) O.loc = src scan = O - to_chat(user, "You insert [O].") - ..() + to_chat(user, "You insert \the [O].") + tgui_interact(user) + else + ..() /obj/machinery/computer/secure_data/attack_ai(mob/user as mob) return attack_hand(user) @@ -56,518 +88,380 @@ /obj/machinery/computer/secure_data/attack_hand(mob/user as mob) if(..()) return - if (using_map && !(src.z in using_map.contact_levels)) - to_chat(user, "Unable to establish a connection: You're too far away from the station!") - return - var/dat + add_fingerprint(user) + tgui_interact(user) - if (temp) - dat = text("[]

Clear Screen", temp, src) - else - dat = text("Confirm Identity: []
", src, (scan ? text("[]", scan.name) : "----------")) - if (authenticated) - switch(screen) - if(1.0) - dat += {" -

"} - dat += text("Search Records
", src) - dat += text("New Record
", src) - dat += {" -

- - - - -
Records:
- - - - - - - -"} - if(!isnull(data_core.general)) - for(var/datum/data/record/R in sortRecord(data_core.general, sortBy, order)) - var/crimstat = "" - for(var/datum/data/record/E in data_core.security) - if ((E.fields["name"] == R.fields["name"] && E.fields["id"] == R.fields["id"])) - crimstat = E.fields["criminal"] - var/background - switch(crimstat) - if("*Arrest*") - background = "'background-color:#DC143C;'" - if("Incarcerated") - background = "'background-color:#CD853F;'" - if("Parolled") - background = "'background-color:#CD853F;'" - if("Released") - background = "'background-color:#3BB9FF;'" - if("None") - background = "'background-color:#00FF7F;'" - if("") - background = "'background-color:#FFFFFF;'" - crimstat = "No Record." - dat += text("", background, src, R, R.fields["name"]) - dat += text("", R.fields["id"]) - dat += text("", R.fields["rank"]) - dat += text("", R.fields["fingerprint"]) - dat += text("", crimstat) - dat += "
NameIDRankFingerprintsCriminal Status
[][][][][]

" - dat += text("Record Maintenance

", src) - dat += text("{Log Out}",src) - if(2.0) - dat += "Records Maintenance
" - dat += "
Delete All Records

Back" - if(3.0) - dat += "
Security Record

" - if ((istype(active1, /datum/data/record) && data_core.general.Find(active1))) - user << browse_rsc(active1.fields["photo_front"], "front.png") - user << browse_rsc(active1.fields["photo_side"], "side.png") - dat += text(" \ -
\ - Name: [active1.fields["name"]]
\ - ID: [active1.fields["id"]]
\n \ - Entity Classification: [active1.fields["brain_type"]]
\n \ - Sex: [active1.fields["sex"]]
\n \ - Age: [active1.fields["age"]]
\n \ - Rank: [active1.fields["rank"]]
\n \ - Fingerprint: [active1.fields["fingerprint"]]
\n \ - Physical Status: [active1.fields["p_stat"]]
\n \ - Mental Status: [active1.fields["m_stat"]]
Photo:
\ - \ -

Update front photo

Update side photo
\ -
") - else - dat += "General Record Lost!
" - if ((istype(active2, /datum/data/record) && data_core.security.Find(active2))) - dat += text("
\n
Security Data

\nCriminal Status: []
\n
\nMinor Crimes: []
\nDetails: []
\n
\nMajor Crimes: []
\nDetails: []
\n
\nImportant Notes:
\n\t[]
\n
\n
Comments/Log

", src, active2.fields["criminal"], src, active2.fields["mi_crim"], src, active2.fields["mi_crim_d"], src, active2.fields["ma_crim"], src, active2.fields["ma_crim_d"], src, decode(active2.fields["notes"])) - var/counter = 1 - while(active2.fields[text("com_[]", counter)]) - dat += text("[]
Delete Entry

", active2.fields[text("com_[]", counter)], src, counter) - counter++ - dat += text("Add Entry

", src) - dat += text("Delete Record (Security Only)

", src) - else - dat += "Security Record Lost!
" - dat += text("New Security Record

", src) - dat += text("\nDelete Record (ALL)

\nPrint Record
\nBack
", src, src, src) - if(4.0) - if(!Perp.len) - dat += text("ERROR. String could not be located.

Back", src) - else - dat += {" - - "} - dat += text("", tempname) - dat += {" - -
Search Results for '[]':
- - - - - - - - "} - for(var/i=1, i<=Perp.len, i += 2) - var/crimstat = "" - var/datum/data/record/R = Perp[i] - if(istype(Perp[i+1],/datum/data/record/)) - var/datum/data/record/E = Perp[i+1] - crimstat = E.fields["criminal"] - var/background - switch(crimstat) - if("*Arrest*") - background = "'background-color:#DC143C;'" - if("Incarcerated") - background = "'background-color:#CD853F;'" - if("Parolled") - background = "'background-color:#CD853F;'" - if("Released") - background = "'background-color:#3BB9FF;'" - if("None") - background = "'background-color:#00FF7F;'" - if("") - background = "'background-color:#FFFFFF;'" - crimstat = "No Record." - dat += text("", background, src, R, R.fields["name"]) - dat += text("", R.fields["id"]) - dat += text("", R.fields["rank"]) - dat += text("", R.fields["fingerprint"]) - dat += text("", crimstat) - dat += "
NameIDRankFingerprintsCriminal Status
[][][][][]

" - dat += text("
Return to index.", src) +/obj/machinery/computer/secure_data/tgui_interact(mob/user, datum/tgui/ui = null) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "SecurityRecords", "Security Records") // 800, 380 + ui.open() + ui.set_autoupdate(FALSE) + + +/obj/machinery/computer/secure_data/tgui_data(mob/user) + var/data[0] + data["temp"] = temp + data["scan"] = scan ? scan.name : null + data["authenticated"] = authenticated + data["rank"] = rank + data["screen"] = screen + data["printing"] = printing + data["isAI"] = isAI(user) + data["isRobot"] = isrobot(user) + if(authenticated) + switch(screen) + if(SEC_DATA_R_LIST) + if(!isnull(data_core.general)) + var/list/records = list() + data["records"] = records + for(var/datum/data/record/R in sortRecord(data_core.general)) + var/color = null + var/criminal = "None" + for(var/datum/data/record/M in data_core.security) + if(M.fields["name"] == R.fields["name"] && M.fields["id"] == R.fields["id"]) + switch(M.fields["criminal"]) + if("*Arrest*") + color = "bad" + if("Incarcerated") + color = "brown" + if("Parolled", "Released") + color = "average" + if("None") + color = "good" + criminal = M.fields["criminal"] + break + records[++records.len] = list( + "ref" = "\ref[R]", + "id" = R.fields["id"], + "name" = R.fields["name"], + "color" = color, + "criminal" = criminal + ) + if(SEC_DATA_RECORD) + var/list/general = list() + data["general"] = general + if(istype(active1, /datum/data/record) && data_core.general.Find(active1)) + var/list/fields = list() + general["fields"] = fields + fields[++fields.len] = FIELD("Name", active1.fields["name"], "name") + fields[++fields.len] = FIELD("ID", active1.fields["id"], "id") + fields[++fields.len] = FIELD("Entity Classification", active1.fields["brain_type"], "brain_type") + fields[++fields.len] = FIELD("Sex", active1.fields["sex"], "sex") + fields[++fields.len] = FIELD("Age", active1.fields["age"], "age") + fields[++fields.len] = FIELD("Rank", active1.fields["rank"], "rank") + fields[++fields.len] = FIELD("Fingerprint", active1.fields["fingerprint"], "fingerprint") + fields[++fields.len] = FIELD("Physical Status", active1.fields["p_stat"], null) + fields[++fields.len] = FIELD("Mental Status", active1.fields["m_stat"], null) + var/list/photos = list() + general["photos"] = photos + photos[++photos.len] = active1.fields["photo-south"] + photos[++photos.len] = active1.fields["photo-west"] + general["has_photos"] = (active1.fields["photo-south"] || active1.fields["photo-west"] ? 1 : 0) + general["empty"] = 0 else - else - dat += text("{Log In}", src) - user << browse(text("Security Records[]", dat), "window=secure_rec;size=600x400") - onclose(user, "secure_rec") - return + general["empty"] = 1 -/*Revised /N -I can't be bothered to look more of the actual code outside of switch but that probably needs revising too. -What a mess.*/ -/obj/machinery/computer/secure_data/Topic(href, href_list) + var/list/security = list() + data["security"] = security + if(istype(active2, /datum/data/record) && data_core.security.Find(active2)) + var/list/fields = list() + security["fields"] = fields + fields[++fields.len] = FIELD("Criminal Status", active2.fields["criminal"], "criminal") + fields[++fields.len] = FIELD("Minor Crimes", active2.fields["mi_crim"], "mi_crim") + fields[++fields.len] = FIELD("Details", active2.fields["mi_crim_d"], "mi_crim_d") + fields[++fields.len] = FIELD("Major Crimes", active2.fields["ma_crim"], "ma_crim") + fields[++fields.len] = FIELD("Details", active2.fields["ma_crim_d"], "ma_crim_d") + fields[++fields.len] = FIELD("Important Notes", active2.fields["notes"], "notes") + if(!active2.fields["comments"] || !islist(active2.fields["comments"])) + active2.fields["comments"] = list() + security["comments"] = active2.fields["comments"] + security["empty"] = 0 + else + security["empty"] = 1 + + data["modal"] = tgui_modal_data(src) + return data + +/obj/machinery/computer/secure_data/tgui_act(action, params) if(..()) - return 1 - if (!( data_core.general.Find(active1) )) - active1 = null - if (!( data_core.security.Find(active2) )) - active2 = null - if ((usr.contents.Find(src) || (in_range(src, usr) && istype(loc, /turf))) || (istype(usr, /mob/living/silicon))) - usr.set_machine(src) - switch(href_list["choice"]) -// SORTING! - if("Sorting") - // Reverse the order if clicked twice - if(sortBy == href_list["sort"]) - if(order == 1) - order = -1 - else - order = 1 - else - // New sorting order! - sortBy = href_list["sort"] - order = initial(order) -//BASIC FUNCTIONS - if("Clear Screen") - temp = null + return TRUE - if ("Return") - screen = 1 + if(!data_core.general.Find(active1)) + active1 = null + if(!data_core.security.Find(active2)) + active2 = null + + . = TRUE + if(tgui_act_modal(action, params)) + return + + switch(action) + if("cleartemp") + temp = null + if("scan") + if(scan) + scan.forceMove(loc) + if(ishuman(usr) && !usr.get_active_hand()) + usr.put_in_hands(scan) + scan = null + else + var/obj/item/I = usr.get_active_hand() + if(istype(I, /obj/item/weapon/card/id)) + usr.drop_item() + I.forceMove(src) + scan = I + if("login") + var/login_type = text2num(params["login_type"]) + if(login_type == LOGIN_TYPE_NORMAL && istype(scan)) + if(check_access(scan)) + authenticated = scan.registered_name + rank = scan.assignment + else if(login_type == LOGIN_TYPE_AI && isAI(usr)) + authenticated = usr.name + rank = "AI" + else if(login_type == LOGIN_TYPE_ROBOT && isrobot(usr)) + authenticated = usr.name + var/mob/living/silicon/robot/R = usr + rank = "[R.modtype] [R.braintype]" + if(authenticated) active1 = null active2 = null + screen = SEC_DATA_R_LIST + else + . = FALSE - if("Confirm Identity") - if (scan) - if(istype(usr,/mob/living/carbon/human) && !usr.get_active_hand()) + if(.) + return + + if(authenticated) + . = TRUE + switch(action) + if("logout") + if(scan) + scan.forceMove(loc) + if(ishuman(usr) && !usr.get_active_hand()) usr.put_in_hands(scan) - else - scan.loc = get_turf(src) scan = null - else - var/obj/item/I = usr.get_active_hand() - if (istype(I, /obj/item/weapon/card/id) && usr.unEquip(I)) - I.loc = src - scan = I - - if("Log Out") authenticated = null screen = null active1 = null active2 = null - - if("Log In") - if (istype(usr, /mob/living/silicon/ai)) - src.active1 = null - src.active2 = null - src.authenticated = usr.name - src.rank = "AI" - src.screen = 1 - else if (istype(usr, /mob/living/silicon/robot)) - src.active1 = null - src.active2 = null - src.authenticated = usr.name - var/mob/living/silicon/robot/R = usr - src.rank = "[R.modtype] [R.braintype]" - src.screen = 1 - else if (istype(scan, /obj/item/weapon/card/id)) - active1 = null - active2 = null - if(check_access(scan)) - authenticated = scan.registered_name - rank = scan.assignment - screen = 1 -//RECORD FUNCTIONS - if("Search Records") - var/t1 = input("Search String: (Partial Name or ID or Fingerprints or Rank)", "Secure. records", null, null) as text - if ((!( t1 ) || usr.stat || !( authenticated ) || usr.restrained() || !in_range(src, usr))) - return - Perp = new/list() - t1 = lowertext(t1) - var/list/components = splittext(t1, " ") - if(components.len > 5) - return //Lets not let them search too greedily. - for(var/datum/data/record/R in data_core.general) - var/temptext = R.fields["name"] + " " + R.fields["id"] + " " + R.fields["fingerprint"] + " " + R.fields["rank"] - for(var/i = 1, i<=components.len, i++) - if(findtext(temptext,components[i])) - var/prelist = new/list(2) - prelist[1] = R - Perp += prelist - for(var/i = 1, i<=Perp.len, i+=2) - for(var/datum/data/record/E in data_core.security) - var/datum/data/record/R = Perp[i] - if ((E.fields["name"] == R.fields["name"] && E.fields["id"] == R.fields["id"])) - Perp[i+1] = E - tempname = t1 - screen = 4 - - if("Record Maintenance") - screen = 2 + if("screen") + screen = clamp(text2num(params["screen"]) || 0, SEC_DATA_R_LIST, SEC_DATA_RECORD) active1 = null active2 = null - - if ("Browse Record") - var/datum/data/record/R = locate(href_list["d_rec"]) - var/S = locate(href_list["d_rec"]) - if (!( data_core.general.Find(R) )) - temp = "Record Not Found!" - else - for(var/datum/data/record/E in data_core.security) - if ((E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"])) - S = E - active1 = R - active2 = S - screen = 3 - -/* if ("Search Fingerprints") - var/t1 = input("Search String: (Fingerprint)", "Secure. records", null, null) as text - if ((!( t1 ) || usr.stat || !( authenticated ) || usr.restrained() || (!in_range(src, usr)) && (!istype(usr, /mob/living/silicon)))) - return - active1 = null - active2 = null - t1 = lowertext(t1) - for(var/datum/data/record/R in data_core.general) - if (lowertext(R.fields["fingerprint"]) == t1) - active1 = R - if (!( active1 )) - temp = text("Could not locate record [].", t1) - else - for(var/datum/data/record/E in data_core.security) - if ((E.fields["name"] == active1.fields["name"] || E.fields["id"] == active1.fields["id"])) - active2 = E - screen = 3 */ - - if ("Print Record") - if (!( printing )) - printing = 1 - var/datum/data/record/record1 = null - var/datum/data/record/record2 = null - if ((istype(active1, /datum/data/record) && data_core.general.Find(active1))) - record1 = active1 - if ((istype(active2, /datum/data/record) && data_core.security.Find(active2))) - record2 = active2 - sleep(50) - var/obj/item/weapon/paper/P = new /obj/item/weapon/paper( loc ) - P.info = "
Security Record

" - if (record1) - P.info += text("Name: [] ID: []
\nSex: []
\nAge: []
\nFingerprint: []
\nPhysical Status: []
\nMental Status: []
", record1.fields["name"], record1.fields["id"], record1.fields["sex"], record1.fields["age"], record1.fields["fingerprint"], record1.fields["p_stat"], record1.fields["m_stat"]) - P.name = text("Security Record ([])", record1.fields["name"]) - else - P.info += "General Record Lost!
" - P.name = "Security Record" - if (record2) - P.info += text("
\n
Security Data

\nCriminal Status: []
\n
\nMinor Crimes: []
\nDetails: []
\n
\nMajor Crimes: []
\nDetails: []
\n
\nImportant Notes:
\n\t[]
\n
\n
Comments/Log

", record2.fields["criminal"], record2.fields["mi_crim"], record2.fields["mi_crim_d"], record2.fields["ma_crim"], record2.fields["ma_crim_d"], decode(record2.fields["notes"])) - var/counter = 1 - while(record2.fields[text("com_[]", counter)]) - P.info += text("[]
", record2.fields[text("com_[]", counter)]) - counter++ - else - P.info += "Security Record Lost!
" - P.info += "" - printing = null - updateUsrDialog() -//RECORD DELETE - if ("Delete All Records") - temp = "" - temp += "Are you sure you wish to delete all Security records?
" - temp += "Yes
" - temp += "No" - - if ("Purge All Records") + if("del_all") for(var/datum/data/record/R in data_core.security) qdel(R) - temp = "All Security records deleted." - - if ("Add Entry") - if (!( istype(active2, /datum/data/record) )) + set_temp("All security records deleted.") + if("del_r") + if(active2) + set_temp("Security record deleted.") + qdel(active2) + if("del_r_2") + set_temp("All records for [active1.fields["name"]] deleted.") + if(active1) + for(var/datum/data/record/R in data_core.medical) + if((R.fields["name"] == active1.fields["name"] || R.fields["id"] == active1.fields["id"])) + qdel(R) + qdel(active1) + if(active2) + qdel(active2) + if("d_rec") + var/datum/data/record/general_record = locate(params["d_rec"] || "") + if(!data_core.general.Find(general_record)) + set_temp("Record not found.", "danger") return - var/a2 = active2 - var/t1 = sanitize(input("Add Comment:", "Secure. records", null, null) as message) - if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || active2 != a2)) + + var/datum/data/record/security_record + for(var/datum/data/record/M in data_core.security) + if(M.fields["name"] == general_record.fields["name"] && M.fields["id"] == general_record.fields["id"]) + security_record = M + break + + active1 = general_record + active2 = security_record + screen = SEC_DATA_RECORD + if("new") + if(istype(active1, /datum/data/record) && !istype(active2, /datum/data/record)) + var/datum/data/record/R = new /datum/data/record() + R.fields["name"] = active1.fields["name"] + R.fields["id"] = active1.fields["id"] + R.name = "Security Record #[R.fields["id"]]" + R.fields["brain_type"] = "Unknown" + R.fields["criminal"] = "None" + R.fields["mi_crim"] = "None" + R.fields["mi_crim_d"] = "No minor crime convictions." + R.fields["ma_crim"] = "None" + R.fields["ma_crim_d"] = "No major crime convictions." + R.fields["notes"] = "No notes." + R.fields["notes"] = "No notes." + data_core.security += R + active2 = R + screen = SEC_DATA_RECORD + set_temp("Security record created.", "success") + if("del_c") + var/index = text2num(params["del_c"] || "") + if(!index || !istype(active2, /datum/data/record)) return - var/counter = 1 - while(active2.fields[text("com_[]", counter)]) - counter++ - active2.fields[text("com_[counter]")] = text("Made by [authenticated] ([rank]) on [time2text(world.realtime, "DDD MMM DD")] [stationtime2text()], [game_year]
[t1]") - if ("Delete Record (ALL)") - if (active1) - temp = "
Are you sure you wish to delete the record (ALL)?
" - temp += "Yes
" - temp += "No" - - if ("Delete Record (Security)") - if (active2) - temp = "
Are you sure you wish to delete the record (Security Portion Only)?
" - temp += "Yes
" - temp += "No" - - if ("Delete Entry") - if ((istype(active2, /datum/data/record) && active2.fields[text("com_[]", href_list["del_c"])])) - active2.fields[text("com_[]", href_list["del_c"])] = "Deleted" -//RECORD CREATE - if ("New Record (Security)") - if ((istype(active1, /datum/data/record) && !( istype(active2, /datum/data/record) ))) - active2 = data_core.CreateSecurityRecord(active1.fields["name"], active1.fields["id"]) - screen = 3 - - if ("New Record (General)") - active1 = data_core.CreateGeneralRecord() + var/list/comments = active2.fields["comments"] + index = clamp(index, 1, length(comments)) + if(comments[index]) + comments.Cut(index, index + 1) + if("search") + active1 = null active2 = null - -//FIELD FUNCTIONS - if ("Edit Field") - if (is_not_allowed(usr)) + var/t1 = lowertext(params["t1"] || "") + if(!length(t1)) return - var/a1 = active1 - var/a2 = active2 - switch(href_list["field"]) - if("name") - if (istype(active1, /datum/data/record)) - var/t1 = sanitizeName(input("Please input name:", "Secure. records", active1.fields["name"], null) as text) - if (!t1 || active1 != a1) - return - active1.fields["name"] = t1 - if("id") - if (istype(active2, /datum/data/record)) - var/t1 = sanitize(input("Please input id:", "Secure. records", active1.fields["id"], null) as text) - if (!t1 || active1 != a1) - return - active1.fields["id"] = t1 - if("fingerprint") - if (istype(active1, /datum/data/record)) - var/t1 = sanitize(input("Please input fingerprint hash:", "Secure. records", active1.fields["fingerprint"], null) as text) - if (!t1 || active1 != a1) - return - active1.fields["fingerprint"] = t1 - if("sex") - if (istype(active1, /datum/data/record)) - if (active1.fields["sex"] == "Male") - active1.fields["sex"] = "Female" - else - active1.fields["sex"] = "Male" - if("age") - if (istype(active1, /datum/data/record)) - var/t1 = input("Please input age:", "Secure. records", active1.fields["age"], null) as num - if (!t1 || active1 != a1) - return - active1.fields["age"] = t1 - if("mi_crim") - if (istype(active2, /datum/data/record)) - var/t1 = sanitize(input("Please input minor disabilities list:", "Secure. records", active2.fields["mi_crim"], null) as text) - if (!t1 || active2 != a2) - return - active2.fields["mi_crim"] = t1 - if("mi_crim_d") - if (istype(active2, /datum/data/record)) - var/t1 = sanitize(input("Please summarize minor dis.:", "Secure. records", active2.fields["mi_crim_d"], null) as message) - if (!t1 || active2 != a2) - return - active2.fields["mi_crim_d"] = t1 - if("ma_crim") - if (istype(active2, /datum/data/record)) - var/t1 = sanitize(input("Please input major diabilities list:", "Secure. records", active2.fields["ma_crim"], null) as text) - if (!t1 || active2 != a2) - return - active2.fields["ma_crim"] = t1 - if("ma_crim_d") - if (istype(active2, /datum/data/record)) - var/t1 = sanitize(input("Please summarize major dis.:", "Secure. records", active2.fields["ma_crim_d"], null) as message) - if (!t1 || active2 != a2) - return - active2.fields["ma_crim_d"] = t1 - if("notes") - if (istype(active2, /datum/data/record)) - var/t1 = sanitize(input("Please summarize notes:", "Secure. records", html_decode(active2.fields["notes"]), null) as message, extra = 0, max_length = MAX_RECORD_LENGTH) - if (!t1 || active2 != a2) - return - active2.fields["notes"] = t1 - if("criminal") - if (istype(active2, /datum/data/record)) - temp = "
Criminal Status:
" - temp += "" - if("rank") - var/list/L = list( "Head of Personnel", "Colony Director", "AI" ) - //This was so silly before the change. Now it actually works without beating your head against the keyboard. /N - if ((istype(active1, /datum/data/record) && L.Find(rank))) - temp = "
Rank:
" - temp += "" - else - alert(usr, "You do not have the required rank to do this!") - if("species") - if (istype(active1, /datum/data/record)) - var/t1 = sanitize(input("Please enter race:", "General records", active1.fields["species"], null) as message) - if (!t1 || active1 != a1) - return - active1.fields["species"] = t1 - if("photo front") - var/icon/photo = get_photo(usr) - if(photo) - active1.fields["photo_front"] = photo - if("photo side") - var/icon/photo = get_photo(usr) - if(photo) - active1.fields["photo_side"] = photo + for(var/datum/data/record/R in data_core.security) + if(t1 == lowertext(R.fields["name"]) || t1 == lowertext(R.fields["id"]) || t1 == lowertext(R.fields["b_dna"])) + active2 = R + break + if(!active2) + set_temp("Security record not found. You must enter the person's exact name, ID or DNA.", "danger") + return + for(var/datum/data/record/E in data_core.general) + if(E.fields["name"] == active2.fields["name"] && E.fields["id"] == active2.fields["id"]) + active1 = E + break + screen = SEC_DATA_RECORD + if("print_p") + if(!printing) + printing = TRUE + // playsound(loc, 'sound/goonstation/machines/printer_dotmatrix.ogg', 50, TRUE) + SStgui.update_uis(src) + addtimer(CALLBACK(src, .proc/print_finish), 5 SECONDS) + if("photo_front") + var/icon/photo = get_photo(usr) + if(photo && active1) + active1.fields["photo_front"] = photo + active1.fields["photo-south"] = "'data:image/png;base64,[icon2base64(photo)]'" + if("photo_side") + var/icon/photo = get_photo(usr) + if(photo && active1) + active1.fields["photo_side"] = photo + active1.fields["photo-west"] = "'data:image/png;base64,[icon2base64(photo)]'" + else + return FALSE -//TEMPORARY MENU FUNCTIONS - else//To properly clear as per clear screen. - temp=null - switch(href_list["choice"]) - if ("Change Rank") - if (active1) - active1.fields["rank"] = href_list["rank"] - if(href_list["rank"] in joblist) - active1.fields["real_rank"] = href_list["real_rank"] - - if ("Change Criminal Status") - if (active2) - for(var/mob/living/carbon/human/H in player_list) - BITSET(H.hud_updateflag, WANTED_HUD) - switch(href_list["criminal2"]) - if("none") - active2.fields["criminal"] = "None" - if("arrest") - active2.fields["criminal"] = "*Arrest*" - if("incarcerated") - active2.fields["criminal"] = "Incarcerated" - if("parolled") - active2.fields["criminal"] = "Parolled" - if("released") - active2.fields["criminal"] = "Released" - - if ("Delete Record (Security) Execute") - if (active2) - qdel(active2) - - if ("Delete Record (ALL) Execute") - if (active1) - for(var/datum/data/record/R in data_core.medical) - if ((R.fields["name"] == active1.fields["name"] || R.fields["id"] == active1.fields["id"])) - qdel(R) - else - qdel(active1) - if (active2) - qdel(active2) +/** + * Called in tgui_act() to process modal actions + * + * Arguments: + * * action - The action passed by tgui + * * params - The params passed by tgui + */ +/obj/machinery/computer/secure_data/proc/tgui_act_modal(action, params) + . = 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("edit") + var/field = arguments["field"] + if(!length(field) || !field_edit_questions[field]) + return + var/question = field_edit_questions[field] + var/choices = field_edit_choices[field] + if(length(choices)) + tgui_modal_choice(src, id, question, arguments = arguments, value = arguments["value"], choices = choices) else - temp = "This function does not appear to be working at the moment. Our apologies." + tgui_modal_input(src, id, question, arguments = arguments, value = arguments["value"]) + if("add_c") + tgui_modal_input(src, id, "Please enter your message:") + else + return FALSE + if(TGUI_MODAL_ANSWER) + var/answer = params["answer"] + switch(id) + if("edit") + var/field = arguments["field"] + if(!length(field) || !field_edit_questions[field]) + return + var/list/choices = field_edit_choices[field] + if(length(choices) && !(answer in choices)) + return - add_fingerprint(usr) - updateUsrDialog() - return + if(field == "age") + answer = text2num(answer) + + if(field == "rank") + if(answer in joblist) + active1.fields["real_rank"] = answer + + if(field == "criminal") + for(var/mob/living/carbon/human/H in player_list) + BITSET(H.hud_updateflag, WANTED_HUD) + + if(istype(active2) && (field in active2.fields)) + active2.fields[field] = answer + if(istype(active1) && (field in active1.fields)) + active1.fields[field] = answer + if("add_c") + if(!length(answer) || !istype(active2) || !length(authenticated)) + return + active2.fields["comments"] += list(list( + header = "Made by [authenticated] ([rank]) at [worldtime2stationtime(world.time)]", + text = answer + )) + else + return FALSE + else + return FALSE + + +/** + * Called when the print timer finishes + */ +/obj/machinery/computer/secure_data/proc/print_finish() + var/obj/item/weapon/paper/P = new(loc) + P.info = "
Security Record

" + if(istype(active1, /datum/data/record) && data_core.general.Find(active1)) + P.info += {"Name: [active1.fields["name"]] ID: [active1.fields["id"]] +
\nSex: [active1.fields["sex"]] +
\nAge: [active1.fields["age"]] +
\nFingerprint: [active1.fields["fingerprint"]] +
\nPhysical Status: [active1.fields["p_stat"]] +
\nMental Status: [active1.fields["m_stat"]]
"} + else + P.info += "General Record Lost!
" + if(istype(active2, /datum/data/record) && data_core.security.Find(active2)) + P.info += {"
\n
Security Data
+
\nCriminal Status: [active2.fields["criminal"]]
\n +
\nMinor Crimes: [active2.fields["mi_crim"]] +
\nDetails: [active2.fields["mi_crim_d"]]
\n +
\nMajor Crimes: [active2.fields["ma_crim"]] +
\nDetails: [active2.fields["ma_crim_d"]]
\n +
\nImportant Notes: +
\n\t[active2.fields["notes"]]
\n +
\n +
Comments/Log

"} + for(var/c in active2.fields["comments"]) + P.info += "[c["header"]]
[c["text"]]
" + else + P.info += "Security Record Lost!
" + P.info += "" + P.name = "paper - 'Security Record: [active1.fields["name"]]'" + printing = FALSE + SStgui.update_uis(src) + + +/** + * Sets a temporary message to display to the user + * + * Arguments: + * * text - Text to display, null/empty to clear the message from the UI + * * style - The style of the message: (color name), info, success, warning, danger, virus + */ +/obj/machinery/computer/secure_data/proc/set_temp(text = "", style = "info", update_now = FALSE) + temp = list(text = text, style = style) + if(update_now) + SStgui.update_uis(src) /obj/machinery/computer/secure_data/proc/is_not_allowed(var/mob/user) return !src.authenticated || user.stat || user.restrained() || (!in_range(src, user) && (!istype(user, /mob/living/silicon))) @@ -614,3 +508,5 @@ What a mess.*/ /obj/machinery/computer/secure_data/detective_computer icon_state = "messyfiles" + +#undef FIELD \ No newline at end of file diff --git a/code/game/machinery/computer/skills.dm b/code/game/machinery/computer/skills.dm index bde923a2171..47b9e8ce256 100644 --- a/code/game/machinery/computer/skills.dm +++ b/code/game/machinery/computer/skills.dm @@ -315,7 +315,7 @@
\n
Comments/Log

"} for(var/c in active1.fields["comments"]) - P.info += "[c]
" + P.info += "[c["header"]]
[c["text"]]
" else P.info += "General Record Lost!
" P.info += "" diff --git a/code/game/machinery/computer/supply.dm b/code/game/machinery/computer/supply.dm index a310b33f785..6a6fd607038 100644 --- a/code/game/machinery/computer/supply.dm +++ b/code/game/machinery/computer/supply.dm @@ -36,7 +36,7 @@ if(!allowed(user)) return user.set_machine(src) - ui_interact(user) + tgui_interact(user) return /obj/machinery/computer/supplycomp/emag_act(var/remaining_charges, var/mob/user) @@ -44,24 +44,27 @@ to_chat(user, "Special supplies unlocked.") authorization |= SUP_CONTRABAND req_access = list() + can_order_contraband = TRUE return 1 +// TGUI +/obj/machinery/computer/supplycomp/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "SupplyConsole", name) + ui.open() - -/obj/machinery/computer/supplycomp/ui_interact(mob/user, ui_key = "supply_records", var/datum/nanoui/ui = null, var/force_open = 1, var/key_state = null) - var/data[0] - var/shuttle_status[0] // Supply shuttle status - var/pack_list[0] // List of supply packs within the active_category - var/orders[0] - var/receipts[0] +/obj/machinery/computer/supplycomp/tgui_data(mob/user) + var/list/data = ..() + var/list/shuttle_status = list() var/datum/shuttle/autodock/ferry/supply/shuttle = SSsupply.shuttle if(shuttle) if(shuttle.has_arrive_time()) shuttle_status["location"] = "In transit" shuttle_status["mode"] = SUP_SHUTTLE_TRANSIT - shuttle_status["time"] = shuttle.eta_minutes() + shuttle_status["time"] = shuttle.eta_seconds() else shuttle_status["time"] = 0 @@ -107,149 +110,192 @@ shuttle_status["engine"] = "Engaged" else - shuttle["mode"] = SUP_SHUTTLE_ERROR - - for(var/pack_name in SSsupply.supply_pack) - var/datum/supply_pack/P = SSsupply.supply_pack[pack_name] - if(P.group == active_category) - var/list/pack = list( - "name" = P.name, - "cost" = P.cost, - "contraband" = P.contraband, - "manifest" = uniquelist(P.manifest), - "random" = P.num_contained, - "expand" = 0, - "ref" = "\ref[P]" - ) - - if(P in expanded_packs) - pack["expand"] = 1 - - pack_list[++pack_list.len] = pack + shuttle_status["mode"] = SUP_SHUTTLE_ERROR // Compile user-side orders // Status determines which menus the entry will display in // Organized in field-entry list for iterative display // List is nested so both the list of orders, and the list of elements in each order, can be iterated over + var/list/orders = list() for(var/datum/supply_order/S in SSsupply.order_history) - orders[++orders.len] = list( - "ref" = "\ref[S]", - "status" = S.status, - "entries" = list( - list("field" = "Supply Pack", "entry" = S.name), - list("field" = "Cost", "entry" = S.cost), - list("field" = "Index", "entry" = S.index), - list("field" = "Reason", "entry" = S.comment), - list("field" = "Ordered by", "entry" = S.ordered_by), - list("field" = "Ordered at", "entry" = S.ordered_at), - list("field" = "Approved by", "entry" = S.approved_by), - list("field" = "Approved at", "entry" = S.approved_at) - ) - ) + orders.Add(list(list( + "ref" = "\ref[S]", + "status" = S.status, + "cost" = S.cost, + "entries" = list( + list("field" = "Supply Pack", "entry" = S.name), + list("field" = "Cost", "entry" = S.cost), + list("field" = "Index", "entry" = S.index), + list("field" = "Reason", "entry" = S.comment), + list("field" = "Ordered by", "entry" = S.ordered_by), + list("field" = "Ordered at", "entry" = S.ordered_at), + list("field" = "Approved by", "entry" = S.approved_by), + list("field" = "Approved at", "entry" = S.approved_at) + ) + ))) // Compile exported crates + var/list/receipts = list() for(var/datum/exported_crate/E in SSsupply.exported_crates) - receipts[++receipts.len] = list( - "ref" = "\ref[E]", - "contents" = E.contents, - "error" = E.contents["error"], - "title" = list( - list("field" = "Name", "entry" = E.name), - list("field" = "Value", "entry" = E.value) - ) + receipts.Add(list(list( + "ref" = "\ref[E]", + "contents" = E.contents, + "error" = E.contents["error"], + "title" = list( + list("field" = "Name", "entry" = E.name), + list("field" = "Value", "entry" = E.value) ) + ))) - data["user"] = "\ref[user]" - data["currentTab"] = menu_tab // Communicator compatibility, controls which menu is in use data["shuttle_auth"] = (authorization & SUP_SEND_SHUTTLE) // Whether this ui is permitted to control the supply shuttle data["order_auth"] = (authorization & SUP_ACCEPT_ORDERS) // Whether this ui is permitted to accept/deny requested orders data["shuttle"] = shuttle_status data["supply_points"] = SSsupply.points - data["categories"] = all_supply_groups - data["active_category"] = active_category - data["supply_packs"] = pack_list data["orders"] = orders data["receipts"] = receipts data["contraband"] = can_order_contraband || (authorization & SUP_CONTRABAND) + data["modal"] = tgui_modal_data(src) + return data - // update the ui if it exists, returns null if no ui is passed/found - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if(!ui) - // the ui does not exist, so we'll create a new() one - // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm - ui = new(user, src, ui_key, "supply_records.tmpl", "Supply Console", 475, 700, state = key_state) - // when the ui is first opened this is the data it will use - ui.set_initial_data(data) - // open the new ui window - ui.open() - // auto update every 20 Master Controller tick - ui.set_auto_update(20) // Longer term to reduce the rate of data collection and processing +/obj/machinery/computer/supplycomp/tgui_static_data(mob/user) + var/list/data = ..() + + var/list/pack_list = list() + for(var/pack_name in SSsupply.supply_pack) + var/datum/supply_pack/P = SSsupply.supply_pack[pack_name] + var/list/pack = list( + "name" = P.name, + "cost" = P.cost, + "group" = P.group, + "contraband" = P.contraband, + "manifest" = uniquelist(P.manifest), + "random" = P.num_contained, + "ref" = "\ref[P]" + ) + pack_list.Add(list(pack)) + data["supply_packs"] = pack_list + data["categories"] = all_supply_groups + return data - - -/obj/machinery/computer/supplycomp/Topic(href, href_list) - if(!SSsupply) - to_world_log("## ERROR: The SSsupply datum is missing.") - return - var/datum/shuttle/autodock/ferry/supply/shuttle = SSsupply.shuttle - if (!shuttle) - to_world_log("## ERROR: The supply shuttle datum is missing.") - return +/obj/machinery/computer/supplycomp/tgui_act(action, params) if(..()) - return 1 + return TRUE + if(!SSsupply) + log_runtime(EXCEPTION("## ERROR: The SSsupply datum is missing.")) + return TRUE + var/datum/shuttle/autodock/ferry/supply/shuttle = SSsupply.shuttle + if(!shuttle) + log_runtime(EXCEPTION("## ERROR: The supply shuttle datum is missing.")) + return TRUE - if(isturf(loc) && ( in_range(src, usr) || istype(usr, /mob/living/silicon) ) ) - usr.set_machine(src) + if(tgui_modal_act(src, action, params)) + return TRUE - // NEW TOPIC + switch(action) + if("view_crate") + var/datum/supply_pack/P = locate(params["crate"]) + if(!istype(P)) + return FALSE + var/list/payload = list( + "name" = P.name, + "cost" = P.cost, + "manifest" = uniquelist(P.manifest), + "ref" = "\ref[P]", + "random" = P.num_contained, + ) + tgui_modal_message(src, action, "", null, payload) + . = TRUE + if("request_crate_multi") + var/datum/supply_pack/S = locate(params["ref"]) - // Switch menu - if(href_list["switch_tab"]) - menu_tab = href_list["switch_tab"] + // Invalid ref + if(!istype(S)) + return FALSE - if(href_list["active_category"]) - active_category = href_list["active_category"] - - if(href_list["pack_ref"]) - var/datum/supply_pack/S = locate(href_list["pack_ref"]) - - // Invalid ref - if(!istype(S)) - return - - // Expand the supply pack's contents - if(href_list["expand"]) - expanded_packs ^= S - - // Make a request for the pack - if(href_list["request"]) - var/mob/user = locate(href_list["user"]) - if(!istype(user)) // Invalid ref - return + if(S.contraband && !(authorization & SUP_CONTRABAND || can_order_contraband)) + return FALSE if(world.time < reqtime) visible_message("[src]'s monitor flashes, \"[reqtime - world.time] seconds remaining until another requisition form may be printed.\"") - return + return FALSE + + var/amount = clamp(input(usr, "How many crates? (0 to 20)") as num|null, 0, 20) + if(!amount) + return FALSE var/timeout = world.time + 600 - var/reason = sanitize(input(user, "Reason:","Why do you require this item?","") as null|text) + var/reason = sanitize(input(usr, "Reason:","Why do you require this item?","") as null|text) if(world.time > timeout) - to_chat(user, "Error. Request timed out.") - return + to_chat(usr, "Error. Request timed out.") + return FALSE if(!reason) - return + return FALSE - SSsupply.create_order(S, user, reason) + for(var/i in 1 to amount) + SSsupply.create_order(S, usr, reason) var/idname = "*None Provided*" var/idrank = "*None Provided*" - if(ishuman(user)) - var/mob/living/carbon/human/H = user + if(ishuman(usr)) + var/mob/living/carbon/human/H = usr idname = H.get_authentification_name() idrank = H.get_assignment() - else if(issilicon(user)) - idname = user.real_name + else if(issilicon(usr)) + idname = usr.real_name + idrank = "Stationbound synthetic" + + var/obj/item/weapon/paper/reqform = new /obj/item/weapon/paper(loc) + reqform.name = "Requisition Form - [S.name]" + reqform.info += "

[station_name()] Supply Requisition Form


" + reqform.info += "INDEX: #[SSsupply.ordernum]
" + reqform.info += "REQUESTED BY: [idname]
" + reqform.info += "RANK: [idrank]
" + reqform.info += "REASON: [reason]
" + reqform.info += "SUPPLY CRATE TYPE: [S.name]
" + reqform.info += "ACCESS RESTRICTION: [get_access_desc(S.access)]
" + reqform.info += "AMOUNT: [amount]
" + reqform.info += "CONTENTS:
" + reqform.info += S.get_html_manifest() + reqform.info += "
" + reqform.info += "STAMP BELOW TO APPROVE THIS REQUISITION:
" + + reqform.update_icon() //Fix for appearing blank when printed. + reqtime = (world.time + 5) % 1e5 + . = TRUE + + if("request_crate") + var/datum/supply_pack/S = locate(params["ref"]) + + // Invalid ref + if(!istype(S)) + return FALSE + + if(S.contraband && !(authorization & SUP_CONTRABAND || can_order_contraband)) + return FALSE + + if(world.time < reqtime) + visible_message("[src]'s monitor flashes, \"[reqtime - world.time] seconds remaining until another requisition form may be printed.\"") + return FALSE + + var/timeout = world.time + 600 + var/reason = sanitize(input(usr, "Reason:","Why do you require this item?","") as null|text) + if(world.time > timeout) + to_chat(usr, "Error. Request timed out.") + return FALSE + if(!reason) + return FALSE + + SSsupply.create_order(S, usr, reason) + + var/idname = "*None Provided*" + var/idrank = "*None Provided*" + if(ishuman(usr)) + var/mob/living/carbon/human/H = usr + idname = H.get_authentification_name() + idrank = H.get_assignment() + else if(issilicon(usr)) + idname = usr.real_name idrank = "Stationbound synthetic" var/obj/item/weapon/paper/reqform = new /obj/item/weapon/paper(loc) @@ -268,24 +314,19 @@ reqform.update_icon() //Fix for appearing blank when printed. reqtime = (world.time + 5) % 1e5 - - if(href_list["order_ref"]) - var/datum/supply_order/O = locate(href_list["order_ref"]) - - // Invalid ref - if(!istype(O)) - return - - var/mob/user = locate(href_list["user"]) - if(!istype(user)) // Invalid ref - return - - if(href_list["edit"]) - var/new_val = sanitize(input(user, href_list["edit"], "Enter the new value for this field:", href_list["default"]) as null|text) + . = TRUE + // Approving Orders + if("edit_order_value") + var/datum/supply_order/O = locate(params["ref"]) + if(!istype(O)) + return FALSE + if(!(authorization & SUP_ACCEPT_ORDERS)) + return FALSE + var/new_val = sanitize(input(usr, params["edit"], "Enter the new value for this field:", params["default"]) as null|text) if(!new_val) - return + return FALSE - switch(href_list["edit"]) + switch(params["edit"]) if("Supply Pack") O.name = new_val @@ -313,68 +354,95 @@ if("Approved at") O.approved_at = new_val + . = TRUE + if("approve_order") + var/datum/supply_order/O = locate(params["ref"]) + if(!istype(O)) + return FALSE + if(!(authorization & SUP_ACCEPT_ORDERS)) + return FALSE + SSsupply.approve_order(O, usr) + . = TRUE + if("deny_order") + var/datum/supply_order/O = locate(params["ref"]) + if(!istype(O)) + return FALSE + if(!(authorization & SUP_ACCEPT_ORDERS)) + return FALSE + SSsupply.deny_order(O, usr) + . = TRUE + if("delete_order") + var/datum/supply_order/O = locate(params["ref"]) + if(!istype(O)) + return FALSE + if(!(authorization & SUP_ACCEPT_ORDERS)) + return FALSE + SSsupply.delete_order(O, usr) + . = TRUE + if("clear_all_requests") + if(!(authorization & SUP_ACCEPT_ORDERS)) + return FALSE + SSsupply.deny_all_pending(usr) + . = TRUE + // Exports + if("export_edit_field") + var/datum/exported_crate/E = locate(params["ref"]) + // Invalid ref + if(!istype(E)) + return FALSE + if(!(authorization & SUP_ACCEPT_ORDERS)) + return FALSE + var/list/L = E.contents[params["index"]] + var/field = alert(usr, "Select which field to edit", , "Name", "Quantity", "Value") - if(href_list["approve"]) - SSsupply.approve_order(O, user) - - if(href_list["deny"]) - SSsupply.deny_order(O, user) - - if(href_list["delete"]) - SSsupply.delete_order(O, user) - - if(href_list["clear_all_requests"]) - var/mob/user = locate(href_list["user"]) - if(!istype(user)) // Invalid ref - return - - SSsupply.deny_all_pending(user) - - if(href_list["export_ref"]) - var/datum/exported_crate/E = locate(href_list["export_ref"]) - - // Invalid ref - if(!istype(E)) - return - - var/mob/user = locate(href_list["user"]) - if(!istype(user)) // Invalid ref - return - - if(href_list["index"]) - var/list/L = E.contents[href_list["index"]] - - if(href_list["edit"]) - var/field = alert(user, "Select which field to edit", , "Name", "Quantity", "Value") - - var/new_val = sanitize(input(user, href_list["edit"], "Enter the new value for this field:", href_list["default"]) as null|text) - if(!new_val) - return - - switch(field) - if("Name") - L["object"] = new_val - - if("Quantity") - var/num = text2num(new_val) - if(num) - L["quantity"] = num - - if("Value") - var/num = text2num(new_val) - if(num) - L["value"] = num - - if(href_list["delete"]) - E.contents.Cut(href_list["index"], href_list["index"] + 1) - - // Else clause means they're editing/deleting the whole export report, rather than a specific item in it - else if(href_list["edit"]) - var/new_val = sanitize(input(user, href_list["edit"], "Enter the new value for this field:", href_list["default"]) as null|text) + var/new_val = sanitize(input(usr, field, "Enter the new value for this field:", L[lowertext(field)]) as null|text) if(!new_val) return - switch(href_list["edit"]) + switch(field) + if("Name") + L["object"] = new_val + + if("Quantity") + var/num = text2num(new_val) + if(num) + L["quantity"] = num + + if("Value") + var/num = text2num(new_val) + if(num) + L["value"] = num + . = TRUE + if("export_delete_field") + var/datum/exported_crate/E = locate(params["ref"]) + // Invalid ref + if(!istype(E)) + return FALSE + if(!(authorization & SUP_ACCEPT_ORDERS)) + return FALSE + E.contents.Cut(params["index"], params["index"] + 1) + . = TRUE + if("export_add_field") + var/datum/exported_crate/E = locate(params["ref"]) + // Invalid ref + if(!istype(E)) + return FALSE + if(!(authorization & SUP_ACCEPT_ORDERS)) + return FALSE + SSsupply.add_export_item(E, usr) + . = TRUE + if("export_edit") + var/datum/exported_crate/E = locate(params["ref"]) + // Invalid ref + if(!istype(E)) + return FALSE + if(!(authorization & SUP_ACCEPT_ORDERS)) + return FALSE + var/new_val = sanitize(input(usr, params["edit"], "Enter the new value for this field:", params["default"]) as null|text) + if(!new_val) + return + + switch(params["edit"]) if("Name") E.name = new_val @@ -382,39 +450,39 @@ var/num = text2num(new_val) if(num) E.value = num + . = TRUE + if("export_delete") + var/datum/exported_crate/E = locate(params["ref"]) + // Invalid ref + if(!istype(E)) + return FALSE + if(!(authorization & SUP_ACCEPT_ORDERS)) + return FALSE + SSsupply.delete_export(E, usr) + . = TRUE + if("send_shuttle") + switch(params["mode"]) + if("send_away") + if (shuttle.forbidden_atoms_check()) + to_chat(usr, "For safety reasons the automated supply shuttle cannot transport live organisms, classified nuclear weaponry or homing beacons.") + else + shuttle.launch(src) + to_chat(usr, "Initiating launch sequence.") - else if(href_list["delete"]) - SSsupply.delete_export(E, user) + if("send_to_station") + shuttle.launch(src) + to_chat(usr, "The supply shuttle has been called and will arrive in approximately [round(SSsupply.movetime/600,1)] minutes.") - else if(href_list["add_item"]) - SSsupply.add_export_item(E, user) + if("cancel_shuttle") + shuttle.cancel_launch(src) - - - switch(href_list["send_shuttle"]) - if("send_away") - if (shuttle.forbidden_atoms_check()) - to_chat(usr, "For safety reasons the automated supply shuttle cannot transport live organisms, classified nuclear weaponry or homing beacons.") - else - shuttle.launch(src) - to_chat(usr, "Initiating launch sequence.") - - if("send_to_station") - shuttle.launch(src) - to_chat(usr, "The supply shuttle has been called and will arrive in approximately [round(SSsupply.movetime/600,1)] minutes.") - - if("cancel_shuttle") - shuttle.cancel_launch(src) - - if("force_shuttle") - shuttle.force_launch(src) + if("force_shuttle") + shuttle.force_launch(src) + . = TRUE add_fingerprint(usr) - updateUsrDialog() - return /obj/machinery/computer/supplycomp/proc/post_signal(var/command) - var/datum/radio_frequency/frequency = radio_controller.return_frequency(1435) if(!frequency) return diff --git a/code/game/machinery/doors/brigdoors.dm b/code/game/machinery/doors/brigdoors.dm index 3722e66cf6c..30e0d6f82fb 100644 --- a/code/game/machinery/doors/brigdoors.dm +++ b/code/game/machinery/doors/brigdoors.dm @@ -1,7 +1,12 @@ #define CHARS_PER_LINE 5 #define FONT_SIZE "5pt" #define FONT_COLOR "#09f" -#define FONT_STYLE "Arial Black" +#define FONT_STYLE "Small Fonts" +#define MAX_TIMER 36000 + +#define PRESET_SHORT 1 MINUTES +#define PRESET_MEDIUM 5 MINUTES +#define PRESET_LONG 10 MINUTES //This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31 @@ -19,14 +24,15 @@ icon_state = "frame" desc = "A remote control for a door." req_access = list(access_brig) - anchored = 1.0 // can't pick it up - density = 0 // can walk through it. - var/id = null // id of door it controls. - var/releasetime = 0 // when world.timeofday reaches it - release the prisoner - var/timing = 1 // boolean, true/1 timer is on, false/0 means it's not timing - var/picture_state // icon_state of alert picture, if not displaying text/numbers - var/list/obj/machinery/targets - var/timetoset = 0 // Used to set releasetime upon starting the timer + anchored = 1.0 // can't pick it up + density = 0 // can walk through it. + var/id = null // id of door it controls. + + var/activation_time = 0 + var/timer_duration = 0 + + var/timing = FALSE // boolean, true/1 timer is on, false/0 means it's not timing + var/list/obj/machinery/targets = list() maptext_height = 26 maptext_width = 32 @@ -40,15 +46,15 @@ . = ..() for(var/obj/machinery/door/window/brigdoor/M in machines) - if (M.id == src.id) + if(M.id == id) LAZYADD(targets,M) for(var/obj/machinery/flasher/F in machines) - if(F.id == src.id) + if(F.id == id) LAZYADD(targets,F) for(var/obj/structure/closet/secure_closet/brig/C in all_brig_closets) - if(C.id == src.id) + if(C.id == id) LAZYADD(targets,C) if(!LAZYLEN(targets)) @@ -63,213 +69,152 @@ // if it's less than 0, open door, reset timer // update the door_timer window and the icon /obj/machinery/door_timer/process() + if(stat & (NOPOWER|BROKEN)) + return - if(stat & (NOPOWER|BROKEN)) return - if(src.timing) - - // poorly done midnight rollover - // (no seriously there's gotta be a better way to do this) - var/timeleft = timeleft() - if(timeleft > 1e5) - src.releasetime = 0 - - - if(world.timeofday > src.releasetime) - src.timer_end() // open doors, reset timer, clear status screen - src.timing = 0 - - src.updateUsrDialog() - src.update_icon() - - else - timer_end() - - return - + if(timing) + if(world.time - activation_time >= timer_duration) + timer_end() // open doors, reset timer, clear status screen + update_icon() // has the door power situation changed, if so update icon. /obj/machinery/door_timer/power_change() ..() update_icon() - return - // open/closedoor checks if door_timer has power, if so it checks if the // linked door is open/closed (by density) then opens it/closes it. // Closes and locks doors, power check /obj/machinery/door_timer/proc/timer_start() - if(stat & (NOPOWER|BROKEN)) return 0 - if(!LAZYLEN(targets)) return 0 + if(stat & (NOPOWER|BROKEN)) + return 0 - // Set releasetime - releasetime = world.timeofday + timetoset + activation_time = world.time + timing = TRUE for(var/obj/machinery/door/window/brigdoor/door in targets) - if(door.density) continue - spawn(0) - door.close() + if(door.density) + continue + INVOKE_ASYNC(door, /obj/machinery/door/window/brigdoor.proc/close) for(var/obj/structure/closet/secure_closet/brig/C in targets) - if(C.broken) continue - if(C.opened && !C.close()) continue - C.locked = 1 + if(C.broken) + continue + if(C.opened && !C.close()) + continue + C.locked = TRUE C.icon_state = "closed_locked" return 1 - // Opens and unlocks doors, power check -/obj/machinery/door_timer/proc/timer_end() - if(stat & (NOPOWER|BROKEN)) return 0 - if(!LAZYLEN(targets)) return 0 +/obj/machinery/door_timer/proc/timer_end(forced = FALSE) + if(stat & (NOPOWER|BROKEN)) + return 0 - // Reset releasetime - releasetime = 0 + timing = FALSE + activation_time = null + set_timer(0) + update_icon() for(var/obj/machinery/door/window/brigdoor/door in targets) - if(!door.density) continue - spawn(0) - door.open() + if(!door.density) + continue + INVOKE_ASYNC(door, /obj/machinery/door/window/brigdoor.proc/open) for(var/obj/structure/closet/secure_closet/brig/C in targets) - if(C.broken) continue - if(C.opened) continue - C.locked = 0 + if(C.broken) + continue + if(C.opened) + continue + C.locked = FALSE C.icon_state = "closed_unlocked" return 1 +/obj/machinery/door_timer/proc/time_left(seconds = FALSE) + . = max(0, timer_duration - (activation_time ? (world.time - activation_time) : 0)) + if(seconds) + . /= 10 -// Check for releasetime timeleft -/obj/machinery/door_timer/proc/timeleft() - . = (releasetime - world.timeofday)/10 - if(. < 0) - . = 0 +/obj/machinery/door_timer/proc/set_timer(value) + var/new_time = clamp(value, 0, MAX_TIMER) + . = new_time == timer_duration //return 1 on no change + timer_duration = new_time + if(timer_duration && activation_time && timing) // Setting it while active will reset the activation time + activation_time = world.time -// Set timetoset -/obj/machinery/door_timer/proc/timeset(var/seconds) - timetoset = seconds * 10 +/obj/machinery/door_timer/attack_hand(mob/user) + if(..()) + return TRUE + tgui_interact(user) - if(timetoset <= 0) - timetoset = 0 +/obj/machinery/door_timer/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "BrigTimer", name) + ui.open() - return +/obj/machinery/door_timer/tgui_data() + var/list/data = list() + data["time_left"] = time_left() + data["max_time_left"] = MAX_TIMER + data["timing"] = timing + data["flash_found"] = FALSE + data["flash_charging"] = FALSE + data["preset_short"] = PRESET_SHORT + data["preset_medium"] = PRESET_MEDIUM + data["preset_long"] = PRESET_LONG + for(var/obj/machinery/flasher/F in targets) + data["flash_found"] = TRUE + if(F.last_flash && (F.last_flash + 150) > world.time) + data["flash_charging"] = TRUE + break + return data -//Allows AIs to use door_timer, see human attack_hand function below -/obj/machinery/door_timer/attack_ai(var/mob/user as mob) - return src.attack_hand(user) - - -//Allows humans to use door_timer -//Opens dialog window when someone clicks on door timer -// Allows altering timer and the timing boolean. -// Flasher activation limited to 150 seconds -/obj/machinery/door_timer/attack_hand(var/mob/user as mob) +/obj/machinery/door_timer/tgui_act(action, params) if(..()) return + . = TRUE - // Used for the 'time left' display - var/second = round(timeleft() % 60) - var/minute = round((timeleft() - second) / 60) + if(!allowed(usr)) + to_chat(usr, "Access denied.") + return FALSE - // Used for 'set timer' - var/setsecond = round((timetoset / 10) % 60) - var/setminute = round(((timetoset / 10) - setsecond) / 60) - - user.set_machine(src) - - // dat - var/dat = "" - - dat += "
Timer System:" - dat += " Door [src.id] controls
" - - // Start/Stop timer - if (src.timing) - dat += "Stop Timer and open door
" - else - dat += "Activate Timer and close door
" - - // Time Left display (uses releasetime) - dat += "Time Left: [(minute ? text("[minute]:") : null)][second]
" - dat += "
" - - // Set Timer display (uses timetoset) - if(src.timing) - dat += "Set Timer: [(setminute ? text("[setminute]:") : null)][setsecond] Set
" - else - dat += "Set Timer: [(setminute ? text("[setminute]:") : null)][setsecond]
" - - // Controls - dat += "- - + +
" - - // Mounted flash controls - if(LAZYLEN(targets)) - for(var/obj/machinery/flasher/F in targets) - if(F.last_flash && (F.last_flash + 150) > world.time) - dat += "
Flash Charging" + switch(action) + if("time") + var/real_new_time = 0 + var/new_time = params["time"] + var/list/L = splittext(new_time, ":") + if(LAZYLEN(L)) + for(var/i in 1 to LAZYLEN(L)) + real_new_time += text2num(L[i]) * (60 ** (LAZYLEN(L) - i)) else - dat += "
Activate Flash" - - dat += "

Close" - dat += "
" - - user << browse(dat, "window=computer;size=400x500") - onclose(user, "computer") - return - - -//Function for using door_timer dialog input, checks if user has permission -// href_list to -// "timing" turns on timer -// "tp" value to modify timer -// "fc" activates flasher -// "change" resets the timer to the timetoset amount while the timer is counting down -// Also updates dialog window and timer icon -/obj/machinery/door_timer/Topic(href, href_list) - if(..()) - return - if(!src.allowed(usr)) - return - - usr.set_machine(src) - - if(href_list["timing"]) - src.timing = text2num(href_list["timing"]) - - if(src.timing) - src.timer_start() + real_new_time = text2num(new_time) + if(real_new_time) + set_timer(real_new_time * 10) + if("start") + timer_start() + if("stop") + timer_end(forced = TRUE) + if("flash") + for(var/obj/machinery/flasher/F in targets) + F.flash() + if("preset") + var/preset = params["preset"] + var/preset_time = time_left() + switch(preset) + if("short") + preset_time = PRESET_SHORT + if("medium") + preset_time = PRESET_MEDIUM + if("long") + preset_time = PRESET_LONG + set_timer(timer_duration + preset_time) + if(timing) + activation_time = world.time else - src.timer_end() - - else - if(href_list["tp"]) //adjust timer, close door if not already closed - var/tp = text2num(href_list["tp"]) - var/addtime = (timetoset / 10) - addtime += tp - addtime = min(max(round(addtime), 0), 3600) - - timeset(addtime) - - if(href_list["fc"]) - if(LAZYLEN(targets)) - for(var/obj/machinery/flasher/F in targets) - F.flash() - - if(href_list["change"]) - src.timer_start() - - src.add_fingerprint(usr) - src.updateUsrDialog() - src.update_icon() - - /* if(src.timing) - src.timer_start() - - else - src.timer_end() */ - - return + . = FALSE //icon update function @@ -280,53 +225,39 @@ if(stat & (NOPOWER)) icon_state = "frame" return + if(stat & (BROKEN)) set_picture("ai_bsod") return - if(src.timing) + + if(timing) var/disp1 = id - var/timeleft = timeleft() - var/disp2 = "[add_zero(num2text((timeleft / 60) % 60),2)]~[add_zero(num2text(timeleft % 60), 2)]" + var/timeleft = time_left(seconds = TRUE) + var/disp2 = "[add_leading(num2text((timeleft / 60) % 60), 2, "0")]:[add_leading(num2text(timeleft % 60), 2, "0")]" if(length(disp2) > CHARS_PER_LINE) disp2 = "Error" update_display(disp1, disp2) else - if(maptext) maptext = "" + if(maptext) + maptext = "" return - // Adds an icon in case the screen is broken/off, stolen from status_display.dm -/obj/machinery/door_timer/proc/set_picture(var/state) - picture_state = state - overlays.Cut() - overlays += image('icons/obj/status_display.dmi', icon_state=picture_state) - +/obj/machinery/door_timer/proc/set_picture(state) + if(maptext) + maptext = "" + cut_overlays() + add_overlay(mutable_appearance('icons/obj/status_display.dmi', state)) //Checks to see if there's 1 line or 2, adds text-icons-numbers/letters over display // Stolen from status_display -/obj/machinery/door_timer/proc/update_display(var/line1, var/line2) +/obj/machinery/door_timer/proc/update_display(line1, line2) + line1 = uppertext(line1) + line2 = uppertext(line2) var/new_text = {"
[line1]
[line2]
"} if(maptext != new_text) maptext = new_text - -//Actual string input to icon display for loop, with 5 pixel x offsets for each letter. -//Stolen from status_display -/obj/machinery/door_timer/proc/texticon(var/tn, var/px = 0, var/py = 0) - var/image/I = image('icons/obj/status_display.dmi', "blank") - var/len = length(tn) - - for(var/d = 1 to len) - var/char = copytext(tn, len-d+1, len-d+2) - if(char == " ") - continue - var/image/ID = image('icons/obj/status_display.dmi', icon_state=char) - ID.pixel_x = -(d-1)*5 + px - ID.pixel_y = py - I.overlays += ID - return I - - /obj/machinery/door_timer/cell_1 name = "Cell 1" id = "Cell 1" @@ -351,7 +282,6 @@ name = "Cell 6" id = "Cell 6" - /obj/machinery/door_timer/tactical_pet_storage //Vorestation Addition name = "Tactical Pet Storage" id = "tactical_pet_storage" diff --git a/code/game/machinery/fire_alarm.dm b/code/game/machinery/fire_alarm.dm index 3ed93f79b3e..e80869e4d94 100644 --- a/code/game/machinery/fire_alarm.dm +++ b/code/game/machinery/fire_alarm.dm @@ -155,7 +155,7 @@ FIRE ALARM for(var/obj/machinery/firealarm/FA in area) fire_alarm.triggerAlarm(loc, FA, duration, hidden = alarms_hidden) update_icon() - playsound(src, 'sound/machines/airalarm.ogg', 25, 0, 4) + playsound(src, 'sound/machines/airalarm.ogg', 25, 0, 4, volume_channel = VOLUME_CHANNEL_ALARMS) if(user) log_game("[user] triggered a fire alarm at [COORD(src)]") diff --git a/code/game/machinery/pointdefense.dm b/code/game/machinery/pointdefense.dm index f135bdd5684..8eeb73fbc5e 100644 --- a/code/game/machinery/pointdefense.dm +++ b/code/game/machinery/pointdefense.dm @@ -15,7 +15,6 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/power/pointdefense) anchored = TRUE circuit = /obj/item/weapon/circuitboard/pointdefense_control var/list/targets = list() // Targets being engaged by associated batteries - var/ui_template = "pointdefense_control.tmpl" var/id_tag = null /obj/machinery/pointdefense_control/Initialize(mapload) @@ -37,48 +36,42 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/power/pointdefense) if(!id_tag) . += "[desc_panel_image("multitool")]to set ident tag" -/obj/machinery/pointdefense_control/ui_interact(var/mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - if(ui_template) - var/list/data = build_ui_data() - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, ui_template, name, 400, 600) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) +/obj/machinery/pointdefense_control/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "PointDefenseControl") // 400, 600 + ui.open() /obj/machinery/pointdefense_control/attack_hand(mob/user) - if((. = ..())) - return - if(CanUseTopic(user, global.default_state) > STATUS_CLOSE) - ui_interact(user) + if(..()) + return TRUE + tgui_interact(user) + return TRUE + +/obj/machinery/pointdefense_control/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) + if(..()) return TRUE -/obj/machinery/pointdefense_control/Topic(var/mob/user, var/href_list) - if((. = ..())) - return - - if(href_list["toggle_active"]) - var/obj/machinery/power/pointdefense/PD = locate(href_list["toggle_active"]) + if(action == "toggle_active") + var/obj/machinery/power/pointdefense/PD = locate(params["target"]) if(!istype(PD)) - return TOPIC_NOACTION + return FALSE //if(!lan || !lan.is_connected(PD)) if(PD.id_tag != id_tag) - return TOPIC_NOACTION + return FALSE if(!(get_z(PD) in GetConnectedZlevels(get_z(src)))) - to_chat(user, "[PD] is not within control range.") - return TOPIC_NOACTION + to_chat(usr, "[PD] is not within control range.") + return FALSE if(!PD.Activate()) //Activate() whilst the device is active will return false. PD.Deactivate() - return TOPIC_REFRESH + return TRUE -/obj/machinery/pointdefense_control/proc/build_ui_data() +/obj/machinery/pointdefense_control/tgui_data(mob/user) var/list/data = list() data["id"] = id_tag - data["name"] = name var/list/turrets = list() if(id_tag) var/list/connected_z_levels = GetConnectedZlevels(get_z(src)) diff --git a/code/game/machinery/reagents/pump.dm b/code/game/machinery/reagents/pump.dm new file mode 100644 index 00000000000..04916d4d9bf --- /dev/null +++ b/code/game/machinery/reagents/pump.dm @@ -0,0 +1,270 @@ + +/obj/machinery/pump + name = "fluid pump" + desc = "A fluid pumping machine." + + description_info = "A machine that can pump fluid from certain turfs.
\ + Water can be pumped from any body of water. Certain locations or environmental\ + conditions can cause different byproducts to be produced.
\ + Magma or Lava can be pumped to produce mineralized fluid." + + anchored = 0 + density = 1 + + icon = 'icons/obj/machines/reagent.dmi' + icon_state = "pump" + + circuit = /obj/item/weapon/circuitboard/fluidpump + + var/on = 0 + var/obj/item/weapon/cell/cell = null + var/use = 200 + var/efficiency = 1 + var/reagents_per_cycle = 40 + var/unlocked = 0 + var/open = 0 + + var/obj/item/hose_connector/output/Output + +// Overlay cache vars. + var/icon/liquid + var/icon/tank + var/icon/powerlow + var/icon/glass + var/icon/open_overlay + var/icon/cell_overlay + +/obj/machinery/pump/Initialize() + create_reagents(200) + . = ..() + default_apply_parts() + + if(ispath(cell)) + cell = new cell(src) + + Output = new(src) + + RefreshParts() + update_icon() + +/obj/machinery/pump/update_icon() + ..() + if(!tank) + tank = new/icon(icon, "[icon_state]-volume") + + if(!powerlow) + powerlow = new/icon(icon, "[icon_state]-lowpower") + + if(!liquid) + var/icon/cutter = new/icon(icon, "[icon_state]-volume") + + cutter.Blend(rgb(0, 0, 0,), ICON_MULTIPLY) + + liquid = new/icon(icon, "[icon_state]-cutting") + + liquid.Blend(cutter,ICON_AND) + + if(!glass) + glass = new/icon(icon, "[icon_state]-glass") + + glass.Blend(rgb(1,1,1,0.5), ICON_MULTIPLY) + + if(!open_overlay) + open_overlay = new/icon(icon, "[icon_state]-open") + + if(!cell_overlay) + cell_overlay = new/icon(icon, "[icon_state]-cell") + + cut_overlays() + add_overlay(tank) + + if(cell && cell.charge < (use * CELLRATE / efficiency)) + add_overlay(powerlow) + + if(reagents.total_volume >= 1) + var/list/hextorgb = hex2rgb(reagents.get_color()) + liquid.GrayScale() + + liquid.Blend(rgb(hextorgb[1],hextorgb[2],hextorgb[3]),ICON_MULTIPLY) + + add_overlay(liquid) + + add_overlay(glass) + + if(open) + add_overlay(open_overlay) + + if(cell) + add_overlay(cell_overlay) + + if(on) + icon_state = "[initial(icon_state)]-running" + + else + icon_state = "[initial(icon_state)]" + +/obj/machinery/pump/process() + if(Output.get_pairing()) + reagents.trans_to_holder(Output.reagents, Output.reagents.maximum_volume) + if(prob(5)) + visible_message("\The [src] gurgles as it exports fluid.") + + if(!on) + return + + if(!cell || (cell.charge < (use * CELLRATE / efficiency))) + turn_off(TRUE) + return + + handle_pumping() + update_icon() + +/obj/machinery/pump/RefreshParts() + for(var/obj/item/weapon/stock_parts/manipulator/SM in component_parts) + efficiency = SM.rating + + var/total_bin_rating = 0 + for(var/obj/item/weapon/stock_parts/matter_bin/SB in component_parts) + total_bin_rating += SB.rating + + reagents.maximum_volume = round(initial(reagents.maximum_volume) + 100 * total_bin_rating) + + return + +/obj/machinery/pump/power_change() + if(!cell || cell.charge < (use * CELLRATE) || !anchored) + return turn_off(TRUE) + + return FALSE + + +// Returns 0 on failure and 1 on success +/obj/machinery/pump/proc/turn_on(var/loud = 0) + if(!cell) + return 0 + if(cell.charge < (use * CELLRATE)) + return 0 + + on = 1 + update_icon() + if(loud) + visible_message("\The [src] turns on.") + return 1 + +/obj/machinery/pump/proc/turn_off(var/loud = 0) + on = 0 + set_light(0, 0) + update_icon() + if(loud) + visible_message("\The [src] shuts down.") + + if(!on) + return TRUE + + return FALSE + +/obj/machinery/pump/attack_ai(mob/user as mob) + if(istype(user, /mob/living/silicon/robot) && Adjacent(user)) + return attack_hand(user) + + if(on) + turn_off(TRUE) + else + if(!turn_on(1)) + to_chat(user, "You try to turn on \the [src] but it does not work.") + +/obj/machinery/pump/attack_hand(mob/user as mob) + if(open && cell) + if(ishuman(user)) + if(!user.get_active_hand()) + user.put_in_hands(cell) + cell.loc = user.loc + else + cell.loc = src.loc + + cell.add_fingerprint(user) + cell.update_icon() + + cell = null + on = 0 + set_light(0) + to_chat(user, "You remove the power cell.") + update_icon() + return + + if(on) + turn_off(TRUE) + else if(anchored) + if(!turn_on(1)) + to_chat(user, "You try to turn on \the [src] but it does not work.") + + update_icon() + +/obj/machinery/pump/attackby(obj/item/weapon/W as obj, mob/user as mob) + if(W.is_screwdriver()) + if(!open) + if(unlocked) + unlocked = 0 + to_chat(user, "You screw the battery panel in place.") + else + unlocked = 1 + to_chat(user, "You unscrew the battery panel.") + + else if(W.is_crowbar()) + if(unlocked) + if(open) + open = 0 + overlays = null + to_chat(user, "You crowbar the battery panel in place.") + else + if(unlocked) + open = 1 + to_chat(user, "You remove the battery panel.") + + else if(W.is_wrench()) + if(on) + to_chat(user, "\The [src] is active. Turn it off before trying to move it!") + return + default_unfasten_wrench(user, W, 2 SECONDS) + + else if(istype(W, /obj/item/weapon/cell)) + if(open) + if(cell) + to_chat(user, "There is a power cell already installed.") + else + user.drop_item() + W.loc = src + cell = W + to_chat(user, "You insert the power cell.") + else + ..() + RefreshParts() + update_icon() + +/obj/machinery/pump/proc/handle_pumping() + var/turf/T = get_turf(src) + + if(istype(T, /turf/simulated/floor/water)) + cell.use(use * CELLRATE / efficiency) + reagents.add_reagent("water", reagents_per_cycle) + + if(T.temperature <= T0C) + reagents.add_reagent("ice", round(reagents_per_cycle / 2, 0.1)) + + if((istype(T,/turf/simulated/floor/water/pool) || istype(T,/turf/simulated/floor/water/deep/pool))) + reagents.add_reagent("chlorine", round(reagents_per_cycle / 10 * efficiency, 0.1)) + + else if(istype(T,/turf/simulated/floor/water/contaminated)) + reagents.add_reagent("vatstabilizer", round(reagents_per_cycle / 2)) + + if(T.loc.name == "Sea") // Saltwater. + reagents.add_reagent("sodiumchloride", round(reagents_per_cycle / 10 * efficiency, 0.1)) + + for(var/turf/simulated/mineral/MT in range(5)) + if(MT.mineral) + var/obj/effect/mineral/OR = MT.mineral + reagents.add_reagent(OR.ore_reagent, round(reagents_per_cycle / 20 * efficiency, 0.1)) + + else if(istype(T, /turf/simulated/floor/lava)) + cell.use(use * CELLRATE / efficiency * 4) + reagents.add_reagent("mineralizedfluid", round(reagents_per_cycle * efficiency / 2, 0.1)) diff --git a/code/game/machinery/requests_console.dm b/code/game/machinery/requests_console.dm index d3eec4057a9..e87de196d96 100644 --- a/code/game/machinery/requests_console.dm +++ b/code/game/machinery/requests_console.dm @@ -38,7 +38,7 @@ var/list/obj/machinery/requests_console/allConsoles = list() // 0 = no new message // 1 = normal priority // 2 = high priority - var/screen = RCS_MAINMENU + var/screen = RCS_VIEWMSGS var/silent = 0 // set to 1 for it not to beep all the time // var/hackState = 0 // 0 = not hacked @@ -105,10 +105,16 @@ var/list/obj/machinery/requests_console/allConsoles = list() if(..(user)) return ui_interact(user) + tgui_interact(user) -/obj/machinery/requests_console/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - var/data[0] +/obj/machinery/requests_console/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "RequestConsole", "[department] Request Console") + ui.open() +/obj/machinery/requests_console/tgui_data(mob/user) + var/list/data = ..() data["department"] = department data["screen"] = screen data["message_log"] = message_log @@ -122,93 +128,103 @@ var/list/obj/machinery/requests_console/allConsoles = list() data["message"] = message data["recipient"] = recipient - data["priortiy"] = priority + data["priority"] = priority data["msgStamped"] = msgStamped data["msgVerified"] = msgVerified data["announceAuth"] = announceAuth + return data - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if(!ui) - ui = new(user, src, ui_key, "request_console.tmpl", "[department] Request Console", 520, 410) - ui.set_initial_data(data) - ui.open() - -/obj/machinery/requests_console/Topic(href, href_list) - if(..()) return - usr.set_machine(src) +/obj/machinery/requests_console/tgui_act(action, list/params) + if(..()) + return TRUE + add_fingerprint(usr) + + switch(action) + if("write") + if(reject_bad_text(params["write"])) + recipient = params["write"] //write contains the string of the receiving department's name - if(reject_bad_text(href_list["write"])) - recipient = href_list["write"] //write contains the string of the receiving department's name + var/new_message = sanitize(input("Write your message:", "Awaiting Input", "")) + if(new_message) + message = new_message + screen = RCS_MESSAUTH + switch(params["priority"]) + if(1) + priority = 1 + if(2) + priority = 2 + else + priority = 0 + else + reset_message(1) + . = TRUE - var/new_message = sanitize(input("Write your message:", "Awaiting Input", "")) - if(new_message) - message = new_message - screen = RCS_MESSAUTH - switch(href_list["priority"]) - if("1") priority = 1 - if("2") priority = 2 - else priority = 0 - else + if("writeAnnouncement") + var/new_message = sanitize(input("Write your message:", "Awaiting Input", "")) + if(new_message) + message = new_message + else + reset_message(1) + . = TRUE + + if("sendAnnouncement") + if(!announcementConsole) + return FALSE + announcement.Announce(message, msg_sanitized = 1) reset_message(1) + . = TRUE - if(href_list["writeAnnouncement"]) - var/new_message = sanitize(input("Write your message:", "Awaiting Input", "")) - if(new_message) - message = new_message - else - reset_message(1) + if("department") + if(!message) + return FALSE + var/log_msg = message + var/pass = 0 + screen = RCS_SENTFAIL + for(var/obj/machinery/message_server/MS in machines) + if(!MS.active) + continue + MS.send_rc_message(ckey(params["department"]), department, log_msg, msgStamped, msgVerified, priority) + pass = 1 + if(pass) + screen = RCS_SENTPASS + message_log += list(list("Message sent to [recipient]", "[message]")) + else + audible_message(text("[bicon(src)] *The Requests Console beeps: 'NOTICE: No server detected!'"),,4) + . = TRUE - if(href_list["sendAnnouncement"]) - if(!announcementConsole) return - announcement.Announce(message, msg_sanitized = 1) - reset_message(1) + //Handle printing + if("print") + var/msg = message_log[text2num(params["print"])]; + if(msg) + msg = "[msg[1]]:
[msg[2]]" + msg = replacetext(msg, "
", "\n") + msg = strip_html_properly(msg) + var/obj/item/weapon/paper/R = new(src.loc) + R.name = "[department] Message" + R.info = "

[department] Requests Console

[msg]
" + . = TRUE - if(href_list["department"] && message) - var/log_msg = message - var/pass = 0 - screen = RCS_SENTFAIL - for (var/obj/machinery/message_server/MS in machines) - if(!MS.active) continue - MS.send_rc_message(ckey(href_list["department"]),department,log_msg,msgStamped,msgVerified,priority) - pass = 1 - if(pass) - screen = RCS_SENTPASS - message_log += "Message sent to [recipient]
[message]" - else - audible_message(text("[bicon(src)] *The Requests Console beeps: 'NOTICE: No server detected!'"),,4) + //Handle screen switching + if("setScreen") + var/tempScreen = text2num(params["setScreen"]) + if(tempScreen == RCS_ANNOUNCE && !announcementConsole) + return + if(tempScreen == RCS_VIEWMSGS) + for (var/obj/machinery/requests_console/Console in allConsoles) + if(Console.department == department) + Console.newmessagepriority = 0 + Console.icon_state = "req_comp0" + Console.set_light(1) + if(tempScreen == RCS_MAINMENU) + reset_message() + screen = tempScreen + . = TRUE - //Handle printing - if (href_list["print"]) - var/msg = message_log[text2num(href_list["print"])]; - if(msg) - msg = replacetext(msg, "
", "\n") - msg = strip_html_properly(msg) - var/obj/item/weapon/paper/R = new(src.loc) - R.name = "[department] Message" - R.info = "

[department] Requests Console

[msg]
" - - //Handle screen switching - if(href_list["setScreen"]) - var/tempScreen = text2num(href_list["setScreen"]) - if(tempScreen == RCS_ANNOUNCE && !announcementConsole) - return - if(tempScreen == RCS_VIEWMSGS) - for (var/obj/machinery/requests_console/Console in allConsoles) - if(Console.department == department) - Console.newmessagepriority = 0 - Console.icon_state = "req_comp0" - Console.set_light(1) - if(tempScreen == RCS_MAINMENU) - reset_message() - screen = tempScreen - - //Handle silencing the console - if(href_list["toggleSilent"]) - silent = !silent - - updateUsrDialog() - return + //Handle silencing the console + if("toggleSilent") + silent = !silent + . = TRUE //err... hacking code, which has no reason for existing... but anyway... it was once supposed to unlock priority 3 messaging on that console (EXTREME priority...), but the code for that was removed. /obj/machinery/requests_console/attackby(var/obj/item/weapon/O as obj, var/mob/user as mob) @@ -238,7 +254,7 @@ var/list/obj/machinery/requests_console/allConsoles = list() if(screen == RCS_MESSAUTH) var/obj/item/weapon/card/id/T = O msgVerified = text("Verified by [T.registered_name] ([T.assignment])") - updateUsrDialog() + SStgui.update_uis(src) if(screen == RCS_ANNOUNCE) var/obj/item/weapon/card/id/ID = O if(access_RC_announce in ID.GetAccess()) @@ -247,13 +263,13 @@ var/list/obj/machinery/requests_console/allConsoles = list() else reset_message() to_chat(user, "You are not authorized to send announcements.") - updateUsrDialog() + SStgui.update_uis(src) if(istype(O, /obj/item/weapon/stamp)) if(inoperable(MAINT)) return if(screen == RCS_MESSAUTH) var/obj/item/weapon/stamp/T = O msgStamped = text("Stamped with the [T.name]") - updateUsrDialog() + SStgui.update_uis(src) return /obj/machinery/requests_console/proc/reset_message(var/mainmenu = 0) diff --git a/code/game/machinery/vending_machines.dm b/code/game/machinery/vending_machines.dm index b631ee807e8..5cd055c5a54 100644 --- a/code/game/machinery/vending_machines.dm +++ b/code/game/machinery/vending_machines.dm @@ -38,7 +38,7 @@ /obj/machinery/vending/boozeomat name = "Booze-O-Mat" - desc = "A technological marvel, supposedly able to mix just the mixture you'd like to drink the moment you ask for one." + desc = "A technological marvel, the ads would have you believe this is able to mix just the mixture you'd like to drink the moment you ask for one." icon_state = "fridge_dark" products = list(/obj/item/weapon/reagent_containers/food/drinks/glass2/square = 10, /obj/item/weapon/reagent_containers/food/drinks/glass2/rocks = 10, @@ -72,7 +72,11 @@ /obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey = 5, /obj/item/weapon/reagent_containers/food/drinks/bottle/wine = 5, /obj/item/weapon/reagent_containers/food/drinks/bottle/small/ale = 15, + /obj/item/weapon/reagent_containers/food/drinks/bottle/small/ale/hushedwhisper = 15, /obj/item/weapon/reagent_containers/food/drinks/bottle/small/beer = 15, + /obj/item/weapon/reagent_containers/food/drinks/bottle/small/beer/silverdragon = 15, + /obj/item/weapon/reagent_containers/food/drinks/bottle/small/beer/meteor = 15, + /obj/item/weapon/reagent_containers/food/drinks/bottle/small/litebeer = 15, /obj/item/weapon/reagent_containers/food/drinks/bottle/small/cider = 15, /obj/item/weapon/reagent_containers/food/drinks/bottle/orangejuice = 5, /obj/item/weapon/reagent_containers/food/drinks/bottle/tomatojuice = 5, @@ -104,61 +108,144 @@ vending_sound = "machines/vending/vending_cans.ogg" /obj/machinery/vending/assist - products = list( /obj/item/device/assembly/prox_sensor = 5,/obj/item/device/assembly/igniter = 3,/obj/item/device/assembly/signaler = 4, - /obj/item/weapon/tool/wirecutters = 1, /obj/item/weapon/cartridge/signal = 4) - contraband = list(/obj/item/device/flashlight = 5,/obj/item/device/assembly/timer = 2) + products = list( /obj/item/device/assembly/prox_sensor = 5, + /obj/item/device/assembly/igniter = 3, + /obj/item/device/assembly/signaler = 4, + /obj/item/weapon/tool/wirecutters = 1, + /obj/item/weapon/cartridge/signal = 4) + contraband = list(/obj/item/device/flashlight = 5, + /obj/item/device/assembly/timer = 2) product_ads = "Only the finest!;Have some tools.;The most robust equipment.;The finest gear in space!" /obj/machinery/vending/coffee name = "Hot Drinks machine" - desc = "A vending machine which dispenses hot drinks." + desc = "A Galaksi brand vending machine which dispenses hot drinks." + description_fluff = "The Ward-Takahashi Galaksi Samovar 55 has been reconstituting hot drinks from their powdered forms since... Well, 2555, but the design has hardly changed in a century or so." product_ads = "Have a drink!;Drink up!;It's good for you!;Would you like a hot joe?;I'd kill for some coffee!;The best beans in the galaxy.;Only the finest brew for you.;Mmmm. Nothing like a coffee.;I like coffee, don't you?;Coffee helps you work!;Try some tea.;We hope you like the best!;Try our new chocolate!;Admin conspiracies" icon_state = "coffee" vend_delay = 34 idle_power_usage = 211 //refrigerator - believe it or not, this is actually the average power consumption of a refrigerated vending machine according to NRCan. vend_power_usage = 85000 //85 kJ to heat a 250 mL cup of coffee - products = list(/obj/item/weapon/reagent_containers/food/drinks/coffee = 25,/obj/item/weapon/reagent_containers/food/drinks/tea = 25,/obj/item/weapon/reagent_containers/food/drinks/h_chocolate = 25) + products = list(/obj/item/weapon/reagent_containers/food/drinks/coffee = 25, + /obj/item/weapon/reagent_containers/food/drinks/decaf = 15, + /obj/item/weapon/reagent_containers/food/drinks/tea = 25, + /obj/item/weapon/reagent_containers/food/drinks/h_chocolate = 25, + /obj/item/weapon/reagent_containers/food/drinks/greentea = 15, + /obj/item/weapon/reagent_containers/food/drinks/chaitea = 15) contraband = list(/obj/item/weapon/reagent_containers/food/drinks/ice = 10) - prices = list(/obj/item/weapon/reagent_containers/food/drinks/coffee = 2, /obj/item/weapon/reagent_containers/food/drinks/tea = 2, /obj/item/weapon/reagent_containers/food/drinks/h_chocolate = 2) //VOREStation Edit + prices = list(/obj/item/weapon/reagent_containers/food/drinks/coffee = 2, + /obj/item/weapon/reagent_containers/food/drinks/decaf = 3, + /obj/item/weapon/reagent_containers/food/drinks/tea = 2, + /obj/item/weapon/reagent_containers/food/drinks/h_chocolate = 2, + /obj/item/weapon/reagent_containers/food/drinks/greentea = 10, + /obj/item/weapon/reagent_containers/food/drinks/chaitea = 5) // VOREStation Edit - Lowers Coffee/Hot Chocolate/Tea Prices from 3 -> 2. vending_sound = "machines/vending/vending_coffee.ogg" /obj/machinery/vending/snack name = "Getmore Chocolate Corp" - desc = "A snack machine courtesy of the Getmore Chocolate Corporation, based out of Mars." + desc = "A snack machine courtesy of the Getmore Chocolate Corporation, a Centauri Provisions brand." + description_fluff = "Despite its name, the Getmore Chocolate Corporation does not produce chocolate - or any foods at all. The company exists soley to refit Ward-Takahashi's Galaksi brand vending products to accept Centauri Provisions' massive range of snackfoods, and sell them at a significant markup. Generic vendors are not authorized to vend Centauri products, and their popularity forces the market to Getmore or Get Lost." product_slogans = "Try our new nougat bar!;Twice the calories for half the price!" - product_ads = "The healthiest!;Award-winning chocolate bars!;Mmm! So good!;Oh my god it's so juicy!;Have a snack.;Snacks are good for you!;Have some more Getmore!;Best quality snacks straight from mars.;We love chocolate!;Try our new jerky!" + product_ads = "The healthiest!;Award-winning chocolate bars!;Mmm! So good!;Oh my god it's so juicy!;Have a snack.;Snacks are good for you!;Get More with Getmore!;Best quality snacks from Centauri Provisions.;We love chocolate!;Try our new jerky!" icon_state = "snack" - products = list(/obj/item/weapon/reagent_containers/food/snacks/candy = 12,/obj/item/weapon/reagent_containers/food/drinks/dry_ramen = 12,/obj/item/weapon/reagent_containers/food/snacks/chips =12, - /obj/item/weapon/reagent_containers/food/snacks/sosjerky = 12,/obj/item/weapon/reagent_containers/food/snacks/no_raisin = 12,/obj/item/weapon/reagent_containers/food/snacks/spacetwinkie = 12, - /obj/item/weapon/reagent_containers/food/snacks/cheesiehonkers = 12, /obj/item/weapon/reagent_containers/food/snacks/tastybread = 12, /obj/item/weapon/reagent_containers/food/snacks/skrellsnacks = 6) - contraband = list(/obj/item/weapon/reagent_containers/food/snacks/syndicake = 6,/obj/item/weapon/reagent_containers/food/snacks/unajerky = 12,) - prices = list(/obj/item/weapon/reagent_containers/food/snacks/candy = 1,/obj/item/weapon/reagent_containers/food/drinks/dry_ramen = 5,/obj/item/weapon/reagent_containers/food/snacks/chips = 1, - /obj/item/weapon/reagent_containers/food/snacks/sosjerky = 2,/obj/item/weapon/reagent_containers/food/snacks/no_raisin = 1,/obj/item/weapon/reagent_containers/food/snacks/spacetwinkie = 1, - /obj/item/weapon/reagent_containers/food/snacks/cheesiehonkers = 1, /obj/item/weapon/reagent_containers/food/snacks/tastybread = 2, /obj/item/weapon/reagent_containers/food/snacks/skrellsnacks = 2) + products = list(/obj/item/weapon/reagent_containers/food/snacks/candy = 12, + /obj/item/weapon/reagent_containers/food/snacks/candy/gummy = 12, + /obj/item/weapon/reagent_containers/food/drinks/dry_ramen = 12, + /obj/item/weapon/reagent_containers/food/snacks/chips = 12, + /obj/item/weapon/reagent_containers/food/snacks/chips/bbq = 12, + /obj/item/weapon/reagent_containers/food/snacks/cheesiehonkers = 12, + /obj/item/weapon/reagent_containers/food/snacks/pistachios = 12, + /obj/item/weapon/reagent_containers/food/snacks/semki = 12, + /obj/item/weapon/reagent_containers/food/snacks/sosjerky = 12, + /obj/item/weapon/reagent_containers/food/snacks/no_raisin = 12, + /obj/item/weapon/reagent_containers/food/snacks/spacetwinkie = 12, + /obj/item/weapon/reagent_containers/food/snacks/tastybread = 12, + /obj/item/weapon/reagent_containers/food/snacks/skrellsnacks = 6, + /obj/item/weapon/reagent_containers/food/snacks/cookiesnack = 6, + /obj/item/weapon/storage/box/gum = 4, + /obj/item/clothing/mask/chewable/candy/lolli = 8, + /obj/item/weapon/storage/box/admints = 4, + /obj/item/weapon/reagent_containers/food/snacks/cb01 = 6, + /obj/item/weapon/reagent_containers/food/snacks/cb02 = 6, + /obj/item/weapon/reagent_containers/food/snacks/cb03 = 6, + /obj/item/weapon/reagent_containers/food/snacks/cb04 = 6, + /obj/item/weapon/reagent_containers/food/snacks/cb05 = 6, + /obj/item/weapon/reagent_containers/food/snacks/cb06 = 6, + /obj/item/weapon/reagent_containers/food/snacks/cb07 = 6, + /obj/item/weapon/reagent_containers/food/snacks/cb08 = 6, + /obj/item/weapon/reagent_containers/food/snacks/cb09 = 6, + /obj/item/weapon/reagent_containers/food/snacks/cb10 = 6, + /obj/item/weapon/reagent_containers/food/snacks/tuna = 2) + contraband = list(/obj/item/weapon/reagent_containers/food/snacks/syndicake = 6, + /obj/item/weapon/reagent_containers/food/snacks/unajerky = 12) + prices = list(/obj/item/weapon/reagent_containers/food/snacks/candy = 1, + /obj/item/weapon/reagent_containers/food/snacks/candy/gummy = 2, + /obj/item/weapon/reagent_containers/food/drinks/dry_ramen = 5, + /obj/item/weapon/reagent_containers/food/snacks/chips = 1, + /obj/item/weapon/reagent_containers/food/snacks/chips/bbq = 1, + /obj/item/weapon/reagent_containers/food/snacks/cheesiehonkers = 1, + /obj/item/weapon/reagent_containers/food/snacks/pistachios = 1, + /obj/item/weapon/reagent_containers/food/snacks/semki = 1, + /obj/item/weapon/reagent_containers/food/snacks/sosjerky = 2, + /obj/item/weapon/reagent_containers/food/snacks/no_raisin = 1, + /obj/item/weapon/reagent_containers/food/snacks/spacetwinkie = 1, + /obj/item/weapon/reagent_containers/food/snacks/tastybread = 2, + /obj/item/weapon/reagent_containers/food/snacks/skrellsnacks = 4, + /obj/item/weapon/storage/box/gum = 15, + /obj/item/clothing/mask/chewable/candy/lolli = 2, + /obj/item/weapon/storage/box/admints = 5, + /obj/item/weapon/reagent_containers/food/snacks/cookiesnack = 20, + /obj/item/weapon/reagent_containers/food/snacks/cb01 = 5, + /obj/item/weapon/reagent_containers/food/snacks/cb02 = 3, + /obj/item/weapon/reagent_containers/food/snacks/cb03 = 5, + /obj/item/weapon/reagent_containers/food/snacks/cb04 = 4, + /obj/item/weapon/reagent_containers/food/snacks/cb05 = 3, + /obj/item/weapon/reagent_containers/food/snacks/cb06 = 7, + /obj/item/weapon/reagent_containers/food/snacks/cb07 = 4, + /obj/item/weapon/reagent_containers/food/snacks/cb08 = 6, + /obj/item/weapon/reagent_containers/food/snacks/cb09 = 10, + /obj/item/weapon/reagent_containers/food/snacks/cb10 = 8, + /obj/item/weapon/reagent_containers/food/snacks/tuna = 23) /obj/machinery/vending/cola name = "Robust Softdrinks" - desc = "A softdrink vendor provided by Robust Industries, LLC." + desc = "A softdrink vendor graciously provided by NanoTrasen's own vending division." + description_fluff = "In a genius sales move, the only vendor authorized to dispense 'outside' beverages (at temperatures lower than 30 degrees celcius) aboard NanoTrasen stations... Is NanoTrasen themselves." icon_state = "Cola_Machine" product_slogans = "Robust Softdrinks: More robust than a toolbox to the head!" - product_ads = "Refreshing!;Hope you're thirsty!;Over 1 million drinks sold!;Thirsty? Why not cola?;Please, have a drink!;Drink up!;The best drinks in space." - products = list(/obj/item/weapon/reagent_containers/food/drinks/cans/cola = 10,/obj/item/weapon/reagent_containers/food/drinks/cans/space_mountain_wind = 10, - /obj/item/weapon/reagent_containers/food/drinks/cans/dr_gibb = 10,/obj/item/weapon/reagent_containers/food/drinks/cans/starkist = 10, - /obj/item/weapon/reagent_containers/food/drinks/cans/waterbottle = 10,/obj/item/weapon/reagent_containers/food/drinks/cans/space_up = 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) - contraband = list(/obj/item/weapon/reagent_containers/food/drinks/cans/thirteenloko = 5, /obj/item/weapon/reagent_containers/food/snacks/liquidfood = 6) - prices = list(/obj/item/weapon/reagent_containers/food/drinks/cans/cola = 1,/obj/item/weapon/reagent_containers/food/drinks/cans/space_mountain_wind = 1, - /obj/item/weapon/reagent_containers/food/drinks/cans/dr_gibb = 1,/obj/item/weapon/reagent_containers/food/drinks/cans/starkist = 1, - /obj/item/weapon/reagent_containers/food/drinks/cans/waterbottle = 2,/obj/item/weapon/reagent_containers/food/drinks/cans/space_up = 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) + product_ads = "Refreshing!;Hope you're thirsty!;Over 1 million drinks sold!;Thirsty? Why not cola?;Please, have a drink!;Drink up!;The best drinks in the galaxy." + products = list(/obj/item/weapon/reagent_containers/food/drinks/cans/cola = 10, + /obj/item/weapon/reagent_containers/food/drinks/cans/space_mountain_wind = 10, + /obj/item/weapon/reagent_containers/food/drinks/cans/dr_gibb = 10, + /obj/item/weapon/reagent_containers/food/drinks/cans/dr_gibb_diet = 10, + /obj/item/weapon/reagent_containers/food/drinks/cans/starkist = 10, + /obj/item/weapon/reagent_containers/food/drinks/cans/waterbottle = 10, + /obj/item/weapon/reagent_containers/food/drinks/cans/space_up = 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) + + contraband = list(/obj/item/weapon/reagent_containers/food/drinks/cans/thirteenloko = 5, + /obj/item/weapon/reagent_containers/food/snacks/liquidfood = 6) + prices = list(/obj/item/weapon/reagent_containers/food/drinks/cans/cola = 1, + /obj/item/weapon/reagent_containers/food/drinks/cans/space_mountain_wind = 1, + /obj/item/weapon/reagent_containers/food/drinks/cans/dr_gibb = 1, + /obj/item/weapon/reagent_containers/food/drinks/cans/dr_gibb_diet = 1, + /obj/item/weapon/reagent_containers/food/drinks/cans/starkist = 1, + /obj/item/weapon/reagent_containers/food/drinks/cans/waterbottle = 2, + /obj/item/weapon/reagent_containers/food/drinks/cans/space_up = 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" /obj/machinery/vending/fitness name = "SweatMAX" desc = "Fueled by your inner inadequacy!" + description_fluff = "Provided by NanoMed, SweatMAX promises solutions to all of your problems. Premium gains at premium prices. Resale of SweatMAX products is a violation of NanoTrasen guidelines." icon_state = "fitness" //VOREStation Edit Start products = list(/obj/item/weapon/reagent_containers/food/drinks/smallmilk = 16, @@ -166,6 +253,7 @@ /obj/item/weapon/reagent_containers/food/drinks/glass2/fitnessflask/proteinshake = 8, /obj/item/weapon/reagent_containers/food/drinks/glass2/fitnessflask = 8, /obj/item/weapon/reagent_containers/food/snacks/candy/proteinbar = 16, + /obj/item/weapon/reagent_containers/food/snacks/fruitbar = 16, /obj/item/weapon/reagent_containers/food/snacks/liquidfood = 8, /obj/item/weapon/reagent_containers/pill/diet = 8, ///obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/glucose = 5, //VOREStation Removal, @@ -177,6 +265,7 @@ /obj/item/weapon/reagent_containers/food/drinks/glass2/fitnessflask/proteinshake = 15, /obj/item/weapon/reagent_containers/food/drinks/glass2/fitnessflask = 1, /obj/item/weapon/reagent_containers/food/snacks/candy/proteinbar = 5, + /obj/item/weapon/reagent_containers/food/snacks/fruitbar = 5, /obj/item/weapon/reagent_containers/food/snacks/liquidfood = 5, /obj/item/weapon/reagent_containers/pill/diet = 25, ///obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/glucose = 5, @@ -201,6 +290,7 @@ /obj/machinery/vending/cigarette name = "cigarette machine" desc = "If you want to get cancer, might as well do it in style!" + description_fluff = "As the ease of cancer treatment progressed to the almost routine (if costly) in the 22nd century, the tobacco industry was quick to make sure smoking went back into style. Take your pick, you've got health insurance don't ya, kid?" product_slogans = "Space cigs taste good like a cigarette should.;I'd rather toolbox than switch.;Smoke!;Don't believe the reports - smoke today!" product_ads = "Probably not bad for you!;Don't believe the scientists!;It's good for you!;Don't quit, buy more!;Smoke!;Nicotine heaven.;Best cigarettes since 2150.;Award-winning cigs.;Feeling temperamental? Try a Temperamento!;Carcinoma Angels - go fuck yerself!;Don't be so hard on yourself, kid. Smoke a Lucky Star!" vend_delay = 34 @@ -212,35 +302,76 @@ /obj/item/weapon/storage/fancy/cigarettes/jerichos = 10, /obj/item/weapon/storage/fancy/cigarettes/menthols = 10, /obj/item/weapon/storage/rollingpapers = 10, + /obj/item/weapon/storage/chewables/tobacco = 5, + /obj/item/weapon/storage/chewables/tobacco/fine = 5, /obj/item/weapon/storage/box/matches = 10, - /obj/item/weapon/flame/lighter/random = 4) + /obj/item/weapon/flame/lighter/random = 4, + /obj/item/clothing/mask/smokable/ecig/util = 2, + ///obj/item/clothing/mask/smokable/ecig/deluxe = 2, + /obj/item/clothing/mask/smokable/ecig/simple = 2, + /obj/item/weapon/reagent_containers/ecig_cartridge/med_nicotine = 10, + /obj/item/weapon/reagent_containers/ecig_cartridge/high_nicotine = 5, + /obj/item/weapon/reagent_containers/ecig_cartridge/orange = 5, + /obj/item/weapon/reagent_containers/ecig_cartridge/mint = 5, + /obj/item/weapon/reagent_containers/ecig_cartridge/watermelon = 5, + /obj/item/weapon/reagent_containers/ecig_cartridge/grape = 5, + /obj/item/weapon/reagent_containers/ecig_cartridge/lemonlime = 5, + /obj/item/weapon/reagent_containers/ecig_cartridge/coffee = 5, + /obj/item/weapon/reagent_containers/ecig_cartridge/blanknico = 2, + /obj/item/weapon/storage/box/fancy/chewables/tobacco/nico = 5) contraband = list(/obj/item/weapon/flame/lighter/zippo = 4) premium = list(/obj/item/weapon/storage/fancy/cigar = 5, /obj/item/weapon/storage/fancy/cigarettes/carcinomas = 5, /obj/item/weapon/storage/fancy/cigarettes/professionals = 5) prices = list(/obj/item/weapon/storage/fancy/cigarettes = 12, - /obj/item/weapon/storage/fancy/cigarettes/dromedaryco = 15, - /obj/item/weapon/storage/fancy/cigarettes/killthroat = 17, + /obj/item/weapon/storage/fancy/cigarettes/dromedaryco = 20, + /obj/item/weapon/storage/fancy/cigarettes/killthroat = 14, /obj/item/weapon/storage/fancy/cigarettes/luckystars = 17, /obj/item/weapon/storage/fancy/cigarettes/jerichos = 22, /obj/item/weapon/storage/fancy/cigarettes/menthols = 18, /obj/item/weapon/storage/rollingpapers = 10, + /obj/item/weapon/storage/chewables/tobacco = 10, + /obj/item/weapon/storage/chewables/tobacco/fine = 20, /obj/item/weapon/storage/box/matches = 1, - /obj/item/weapon/flame/lighter/random = 2) + /obj/item/weapon/flame/lighter/random = 2, + /obj/item/clothing/mask/smokable/ecig/util = 100, + ///obj/item/clothing/mask/smokable/ecig/deluxe = 300, + /obj/item/clothing/mask/smokable/ecig/simple = 150, + /obj/item/weapon/reagent_containers/ecig_cartridge/med_nicotine = 10, + /obj/item/weapon/reagent_containers/ecig_cartridge/high_nicotine = 15, + /obj/item/weapon/reagent_containers/ecig_cartridge/orange = 15, + /obj/item/weapon/reagent_containers/ecig_cartridge/mint = 15, + /obj/item/weapon/reagent_containers/ecig_cartridge/watermelon = 15, + /obj/item/weapon/reagent_containers/ecig_cartridge/grape = 15, + /obj/item/weapon/reagent_containers/ecig_cartridge/lemonlime = 15, + /obj/item/weapon/reagent_containers/ecig_cartridge/coffee = 15, + /obj/item/weapon/reagent_containers/ecig_cartridge/blanknico = 15, + /obj/item/weapon/storage/box/fancy/chewables/tobacco/nico = 15) + /obj/machinery/vending/medical name = "NanoMed Plus" desc = "Medical drug dispenser." + description_fluff = "NanoMed is NanoTrasen's medical science division, and provides almost all of the modern medbay essentials in-house at no extra charge. By using this vending machine, employees accept liability for products that may or may not be temporarily replaced by placebos or experimental treatments." icon_state = "med" product_ads = "Go save some lives!;The best stuff for your medbay.;Only the finest tools.;Natural chemicals!;This stuff saves lives.;Don't you want some?;Ping!" req_access = list(access_medical) - products = list(/obj/item/weapon/reagent_containers/glass/bottle/antitoxin = 4,/obj/item/weapon/reagent_containers/glass/bottle/inaprovaline = 4, - /obj/item/weapon/reagent_containers/glass/bottle/stoxin = 4,/obj/item/weapon/reagent_containers/glass/bottle/toxin = 4, - /obj/item/weapon/reagent_containers/syringe/antiviral = 4,/obj/item/weapon/reagent_containers/syringe = 12, - /obj/item/device/healthanalyzer = 5,/obj/item/weapon/reagent_containers/glass/beaker = 4, /obj/item/weapon/reagent_containers/dropper = 2, - /obj/item/stack/medical/advanced/bruise_pack = 6, /obj/item/stack/medical/advanced/ointment = 6, /obj/item/stack/medical/splint = 4, + products = list(/obj/item/weapon/reagent_containers/glass/bottle/antitoxin = 4, + /obj/item/weapon/reagent_containers/glass/bottle/inaprovaline = 4, + /obj/item/weapon/reagent_containers/glass/bottle/stoxin = 4, + /obj/item/weapon/reagent_containers/glass/bottle/toxin = 4, + /obj/item/weapon/reagent_containers/syringe/antiviral = 4, + /obj/item/weapon/reagent_containers/syringe = 12, + /obj/item/device/healthanalyzer = 5, + /obj/item/weapon/reagent_containers/glass/beaker = 4, + /obj/item/weapon/reagent_containers/dropper = 2, + /obj/item/stack/medical/advanced/bruise_pack = 6, + /obj/item/stack/medical/advanced/ointment = 6, + /obj/item/stack/medical/splint = 4, /obj/item/weapon/storage/pill_bottle/carbon = 2) - contraband = list(/obj/item/weapon/reagent_containers/pill/tox = 3,/obj/item/weapon/reagent_containers/pill/stox = 4,/obj/item/weapon/reagent_containers/pill/antitox = 6) + contraband = list(/obj/item/weapon/reagent_containers/pill/tox = 3, + /obj/item/weapon/reagent_containers/pill/stox = 4, + /obj/item/weapon/reagent_containers/pill/antitox = 6) idle_power_usage = 211 //refrigerator - believe it or not, this is actually the average power consumption of a refrigerated vending machine according to NRCan. req_log_access = access_cmo has_logs = 1 @@ -248,20 +379,31 @@ /obj/machinery/vending/phoronresearch name = "Toximate 3000" desc = "All the fine parts you need in one vending machine!" - products = list(/obj/item/clothing/under/rank/scientist = 6,/obj/item/clothing/suit/bio_suit = 6,/obj/item/clothing/head/bio_hood = 6, - /obj/item/device/transfer_valve = 6,/obj/item/device/assembly/timer = 6,/obj/item/device/assembly/signaler = 6, - /obj/item/device/assembly/prox_sensor = 6,/obj/item/device/assembly/igniter = 6) + products = list(/obj/item/clothing/under/rank/scientist = 6, + /obj/item/clothing/suit/bio_suit = 6, + /obj/item/clothing/head/bio_hood = 6, + /obj/item/device/transfer_valve = 6, + /obj/item/device/assembly/timer = 6, + /obj/item/device/assembly/signaler = 6, + /obj/item/device/assembly/prox_sensor = 6, + /obj/item/device/assembly/igniter = 6) req_log_access = access_rd has_logs = 1 /obj/machinery/vending/wallmed1 name = "NanoMed" desc = "A wall-mounted version of the NanoMed." + description_fluff = "NanoMed is NanoTrasen's medical science division, and provides almost all of the modern medbay essentials in-house at no extra charge. By using this vending machine, employees accept liability for products that may or may not be temporarily replaced by placebos or experimental treatments." product_ads = "Go save some lives!;The best stuff for your medbay.;Only the finest tools.;Natural chemicals!;This stuff saves lives.;Don't you want some?" icon_state = "wallmed" density = 0 //It is wall-mounted, and thus, not dense. --Superxpdude - products = list(/obj/item/stack/medical/bruise_pack = 2,/obj/item/stack/medical/ointment = 2,/obj/item/weapon/reagent_containers/hypospray/autoinjector = 4,/obj/item/device/healthanalyzer = 1) - contraband = list(/obj/item/weapon/reagent_containers/syringe/antitoxin = 4,/obj/item/weapon/reagent_containers/syringe/antiviral = 4,/obj/item/weapon/reagent_containers/pill/tox = 1) + products = list(/obj/item/stack/medical/bruise_pack = 2, + /obj/item/stack/medical/ointment = 2, + /obj/item/weapon/reagent_containers/hypospray/autoinjector = 4, + /obj/item/device/healthanalyzer = 1) + contraband = list(/obj/item/weapon/reagent_containers/syringe/antitoxin = 4, + /obj/item/weapon/reagent_containers/syringe/antiviral = 4, + /obj/item/weapon/reagent_containers/pill/tox = 1) req_log_access = access_cmo has_logs = 1 can_rotate = 0 @@ -269,10 +411,14 @@ /obj/machinery/vending/wallmed2 name = "NanoMed" desc = "A wall-mounted version of the NanoMed, containing only vital first aid equipment." + description_fluff = "NanoMed is NanoTrasen's medical science division, and provides almost all of the modern medbay essentials in-house at no extra charge. By using this vending machine, employees accept liability for products that may or may not be temporarily replaced by placebos or experimental treatments." icon_state = "wallmed" density = 0 //It is wall-mounted, and thus, not dense. --Superxpdude - products = list(/obj/item/weapon/reagent_containers/hypospray/autoinjector = 5,/obj/item/weapon/reagent_containers/syringe/antitoxin = 3,/obj/item/stack/medical/bruise_pack = 3, - /obj/item/stack/medical/ointment =3,/obj/item/device/healthanalyzer = 3) + products = list(/obj/item/weapon/reagent_containers/hypospray/autoinjector = 5, + /obj/item/weapon/reagent_containers/syringe/antitoxin = 3, + /obj/item/stack/medical/bruise_pack = 3, + /obj/item/stack/medical/ointment =3, + /obj/item/device/healthanalyzer = 3) contraband = list(/obj/item/weapon/reagent_containers/pill/tox = 3) req_log_access = access_cmo has_logs = 1 @@ -281,24 +427,35 @@ /obj/machinery/vending/security name = "SecTech" desc = "A security equipment vendor." + description_fluff = "Security vending is kindly provided by the Lawson Arms company, Hephaestus Industries' law enforcement division." product_ads = "Crack capitalist skulls!;Beat some heads in!;Don't forget - harm is good!;Your weapons are right here.;Handcuffs!;Freeze, scumbag!;Don't tase me bro!;Tase them, bro.;Why not have a donut?" icon_state = "sec" req_access = list(access_security) - products = list(/obj/item/weapon/handcuffs = 8,/obj/item/weapon/grenade/flashbang = 4,/obj/item/device/flash = 5, - /obj/item/weapon/reagent_containers/food/snacks/donut/normal = 12,/obj/item/weapon/storage/box/evidence = 6) - contraband = list(/obj/item/clothing/glasses/sunglasses = 2,/obj/item/weapon/storage/box/donut = 2) + products = list(/obj/item/weapon/handcuffs = 8, + /obj/item/weapon/grenade/flashbang = 4, + /obj/item/device/flash = 5, + /obj/item/weapon/reagent_containers/food/snacks/donut/normal = 12, + /obj/item/weapon/storage/box/evidence = 6) + contraband = list(/obj/item/clothing/glasses/sunglasses = 2, + /obj/item/weapon/storage/box/donut = 2) req_log_access = access_armory has_logs = 1 /obj/machinery/vending/hydronutrients name = "NutriMax" - desc = "A plant nutrients vendor." + desc = "A plant nutrients vendor by the NanoPastures company." product_slogans = "Aren't you glad you don't have to fertilize the natural way?;Now with 50% less stink!;Plants are people too!" product_ads = "We like plants!;Don't you want some?;The greenest thumbs ever.;We like big plants.;Soft soil..." icon_state = "nutri_generic" - products = list(/obj/item/weapon/reagent_containers/glass/bottle/eznutrient = 6,/obj/item/weapon/reagent_containers/glass/bottle/left4zed = 4,/obj/item/weapon/reagent_containers/glass/bottle/robustharvest = 3,/obj/item/weapon/plantspray/pests = 20, - /obj/item/weapon/reagent_containers/syringe = 5,/obj/item/weapon/reagent_containers/glass/beaker = 4,/obj/item/weapon/storage/bag/plants = 5) - premium = list(/obj/item/weapon/reagent_containers/glass/bottle/ammonia = 10,/obj/item/weapon/reagent_containers/glass/bottle/diethylamine = 5) + products = list(/obj/item/weapon/reagent_containers/glass/bottle/eznutrient = 6, + /obj/item/weapon/reagent_containers/glass/bottle/left4zed = 4, + /obj/item/weapon/reagent_containers/glass/bottle/robustharvest = 3, + /obj/item/weapon/plantspray/pests = 20, + /obj/item/weapon/reagent_containers/syringe = 5, + /obj/item/weapon/reagent_containers/glass/beaker = 4, + /obj/item/weapon/storage/bag/plants = 5) + premium = list(/obj/item/weapon/reagent_containers/glass/bottle/ammonia = 10, + /obj/item/weapon/reagent_containers/glass/bottle/diethylamine = 5) idle_power_usage = 211 //refrigerator - believe it or not, this is actually the average power consumption of a refrigerated vending machine according to NRCan. @@ -309,14 +466,48 @@ product_ads = "We like plants!;Grow some crops!;Grow, baby, growww!;Aw h'yeah son!" icon_state = "seeds_generic" - products = list(/obj/item/seeds/bananaseed = 3,/obj/item/seeds/berryseed = 3,/obj/item/seeds/carrotseed = 3,/obj/item/seeds/chantermycelium = 3,/obj/item/seeds/chiliseed = 3, - /obj/item/seeds/cornseed = 3, /obj/item/seeds/eggplantseed = 3, /obj/item/seeds/potatoseed = 3, /obj/item/seeds/replicapod = 3,/obj/item/seeds/soyaseed = 3, - /obj/item/seeds/sunflowerseed = 3,/obj/item/seeds/tomatoseed = 3,/obj/item/seeds/towermycelium = 3,/obj/item/seeds/wheatseed = 3,/obj/item/seeds/appleseed = 3, - /obj/item/seeds/poppyseed = 3,/obj/item/seeds/sugarcaneseed = 3,/obj/item/seeds/ambrosiavulgarisseed = 3,/obj/item/seeds/peanutseed = 3,/obj/item/seeds/whitebeetseed = 3,/obj/item/seeds/watermelonseed = 3,/obj/item/seeds/lavenderseed = 3,/obj/item/seeds/limeseed = 3, - /obj/item/seeds/lemonseed = 3,/obj/item/seeds/orangeseed = 3,/obj/item/seeds/grassseed = 3,/obj/item/seeds/cocoapodseed = 3,/obj/item/seeds/plumpmycelium = 2, - /obj/item/seeds/cabbageseed = 3,/obj/item/seeds/grapeseed = 3,/obj/item/seeds/pumpkinseed = 3,/obj/item/seeds/cherryseed = 3,/obj/item/seeds/plastiseed = 3,/obj/item/seeds/riceseed = 3) - contraband = list(/obj/item/seeds/amanitamycelium = 2,/obj/item/seeds/glowshroom = 2,/obj/item/seeds/libertymycelium = 2,/obj/item/seeds/mtearseed = 2, - /obj/item/seeds/nettleseed = 2,/obj/item/seeds/reishimycelium = 2,/obj/item/seeds/reishimycelium = 2,/obj/item/seeds/shandseed = 2,) + products = list(/obj/item/seeds/bananaseed = 3, + /obj/item/seeds/berryseed = 3, + /obj/item/seeds/carrotseed = 3, + /obj/item/seeds/chantermycelium = 3, + /obj/item/seeds/chiliseed = 3, + /obj/item/seeds/cornseed = 3, + /obj/item/seeds/eggplantseed = 3, + /obj/item/seeds/potatoseed = 3, + /obj/item/seeds/replicapod = 3, + /obj/item/seeds/soyaseed = 3, + /obj/item/seeds/sunflowerseed = 3, + /obj/item/seeds/tomatoseed = 3, + /obj/item/seeds/towermycelium = 3, + /obj/item/seeds/wheatseed = 3, + /obj/item/seeds/appleseed = 3, + /obj/item/seeds/poppyseed = 3, + /obj/item/seeds/sugarcaneseed = 3, + /obj/item/seeds/ambrosiavulgarisseed = 3, + /obj/item/seeds/peanutseed = 3, + /obj/item/seeds/whitebeetseed = 3, + /obj/item/seeds/watermelonseed = 3, + /obj/item/seeds/lavenderseed = 3, + /obj/item/seeds/limeseed = 3, + /obj/item/seeds/lemonseed = 3, + /obj/item/seeds/orangeseed = 3, + /obj/item/seeds/grassseed = 3, + /obj/item/seeds/cocoapodseed = 3, + /obj/item/seeds/plumpmycelium = 2, + /obj/item/seeds/cabbageseed = 3, + /obj/item/seeds/grapeseed = 3, + /obj/item/seeds/pumpkinseed = 3, + /obj/item/seeds/cherryseed = 3, + /obj/item/seeds/plastiseed = 3, + /obj/item/seeds/riceseed = 3) + contraband = list(/obj/item/seeds/amanitamycelium = 2, + /obj/item/seeds/glowshroom = 2, + /obj/item/seeds/libertymycelium = 2, + /obj/item/seeds/mtearseed = 2, + /obj/item/seeds/nettleseed = 2, + /obj/item/seeds/reishimycelium = 2, + /obj/item/seeds/reishimycelium = 2, + /obj/item/seeds/shandseed = 2,) premium = list(/obj/item/weapon/reagent_containers/spray/waterflower = 1) /** @@ -357,7 +548,7 @@ /obj/machinery/vending/dinnerware name = "Dinnerware" - desc = "A kitchen and restaurant equipment vendor." + desc = "A WT Galaksi brand kitchen and restaurant equipment vendor." product_ads = "Mm, food stuffs!;Food and food accessories.;Get your plates!;You like forks?;I like forks.;Woo, utensils.;You don't really need these..." icon_state = "dinnerware" products = list( @@ -403,11 +594,21 @@ desc = "Tools for tools." icon_state = "tool" //req_access = list(access_maint_tunnels) //Maintenance access - products = list(/obj/item/stack/cable_coil/random = 10,/obj/item/weapon/tool/crowbar = 5,/obj/item/weapon/weldingtool = 3,/obj/item/weapon/tool/wirecutters = 5, - /obj/item/weapon/tool/wrench = 5,/obj/item/device/analyzer = 5,/obj/item/device/t_scanner = 5,/obj/item/weapon/tool/screwdriver = 5, - /obj/item/device/flashlight/glowstick = 3, /obj/item/device/flashlight/glowstick/red = 3, /obj/item/device/flashlight/glowstick/blue = 3, - /obj/item/device/flashlight/glowstick/orange =3, /obj/item/device/flashlight/glowstick/yellow = 3) - contraband = list(/obj/item/weapon/weldingtool/hugetank = 2,/obj/item/clothing/gloves/fyellow = 2,) + products = list(/obj/item/stack/cable_coil/random = 10, + /obj/item/weapon/tool/crowbar = 5, + /obj/item/weapon/weldingtool = 3, + /obj/item/weapon/tool/wirecutters = 5, + /obj/item/weapon/tool/wrench = 5, + /obj/item/device/analyzer = 5, + /obj/item/device/t_scanner = 5, + /obj/item/weapon/tool/screwdriver = 5, + /obj/item/device/flashlight/glowstick = 3, + /obj/item/device/flashlight/glowstick/red = 3, + /obj/item/device/flashlight/glowstick/blue = 3, + /obj/item/device/flashlight/glowstick/orange =3, + /obj/item/device/flashlight/glowstick/yellow = 3) + contraband = list(/obj/item/weapon/weldingtool/hugetank = 2, + /obj/item/clothing/gloves/fyellow = 2) premium = list(/obj/item/clothing/gloves/yellow = 1) req_log_access = access_ce has_logs = 1 @@ -417,16 +618,35 @@ desc = "Spare tool vending. What? Did you expect some witty description?" icon_state = "engivend" req_access = list(access_engine_equip) - products = list(/obj/item/device/geiger = 4,/obj/item/clothing/glasses/meson = 2,/obj/item/device/multitool = 4,/obj/item/weapon/cell/high = 10, - /obj/item/weapon/airlock_electronics = 10,/obj/item/weapon/module/power_control = 10, - /obj/item/weapon/circuitboard/airalarm = 10,/obj/item/weapon/circuitboard/firealarm = 10,/obj/item/weapon/circuitboard/status_display = 2, - /obj/item/weapon/circuitboard/ai_status_display = 2,/obj/item/weapon/circuitboard/newscaster = 2,/obj/item/weapon/circuitboard/holopad = 2, - /obj/item/weapon/circuitboard/intercom = 4,/obj/item/weapon/circuitboard/security/telescreen/entertainment = 4, - /obj/item/weapon/stock_parts/motor = 2,/obj/item/weapon/stock_parts/spring = 2,/obj/item/weapon/stock_parts/gear = 2, - /obj/item/weapon/circuitboard/atm,/obj/item/weapon/circuitboard/guestpass,/obj/item/weapon/circuitboard/keycard_auth, - /obj/item/weapon/circuitboard/photocopier,/obj/item/weapon/circuitboard/fax,/obj/item/weapon/circuitboard/request, - /obj/item/weapon/circuitboard/microwave,/obj/item/weapon/circuitboard/washing,/obj/item/weapon/circuitboard/scanner_console, - /obj/item/weapon/circuitboard/sleeper_console,/obj/item/weapon/circuitboard/body_scanner,/obj/item/weapon/circuitboard/sleeper, + products = list(/obj/item/device/geiger = 4, + /obj/item/clothing/glasses/meson = 2, + /obj/item/device/multitool = 4, + /obj/item/weapon/cell/high = 10, + /obj/item/weapon/airlock_electronics = 10, + /obj/item/weapon/module/power_control = 10, + /obj/item/weapon/circuitboard/airalarm = 10, + /obj/item/weapon/circuitboard/firealarm = 10, + /obj/item/weapon/circuitboard/status_display = 2, + /obj/item/weapon/circuitboard/ai_status_display = 2, + /obj/item/weapon/circuitboard/newscaster = 2, + /obj/item/weapon/circuitboard/holopad = 2, + /obj/item/weapon/circuitboard/intercom = 4, + /obj/item/weapon/circuitboard/security/telescreen/entertainment = 4, + /obj/item/weapon/stock_parts/motor = 2, + /obj/item/weapon/stock_parts/spring = 2, + /obj/item/weapon/stock_parts/gear = 2, + /obj/item/weapon/circuitboard/atm, + /obj/item/weapon/circuitboard/guestpass, + /obj/item/weapon/circuitboard/keycard_auth, + /obj/item/weapon/circuitboard/photocopier, + /obj/item/weapon/circuitboard/fax, + /obj/item/weapon/circuitboard/request, + /obj/item/weapon/circuitboard/microwave, + /obj/item/weapon/circuitboard/washing, + /obj/item/weapon/circuitboard/scanner_console, + /obj/item/weapon/circuitboard/sleeper_console, + /obj/item/weapon/circuitboard/body_scanner, + /obj/item/weapon/circuitboard/sleeper, /obj/item/weapon/circuitboard/dna_analyzer) contraband = list(/obj/item/weapon/cell/potato = 3) premium = list(/obj/item/weapon/storage/belt/utility = 3) @@ -439,15 +659,30 @@ desc = "Everything you need for do-it-yourself station repair." icon_state = "engi" req_access = list(access_engine_equip) - products = list(/obj/item/clothing/under/rank/chief_engineer = 4,/obj/item/clothing/under/rank/engineer = 4,/obj/item/clothing/shoes/orange = 4,/obj/item/clothing/head/hardhat = 4, - /obj/item/weapon/storage/belt/utility = 4,/obj/item/clothing/glasses/meson = 4,/obj/item/clothing/gloves/yellow = 4, /obj/item/weapon/tool/screwdriver = 12, - /obj/item/weapon/tool/crowbar = 12,/obj/item/weapon/tool/wirecutters = 12,/obj/item/device/multitool = 12,/obj/item/weapon/tool/wrench = 12,/obj/item/device/t_scanner = 12, - /obj/item/stack/cable_coil/heavyduty = 8, /obj/item/weapon/cell = 8, /obj/item/weapon/weldingtool = 8,/obj/item/clothing/head/welding = 8, - /obj/item/weapon/light/tube = 10,/obj/item/clothing/suit/fire = 4, /obj/item/weapon/stock_parts/scanning_module = 5,/obj/item/weapon/stock_parts/micro_laser = 5, - /obj/item/weapon/stock_parts/matter_bin = 5,/obj/item/weapon/stock_parts/manipulator = 5,/obj/item/weapon/stock_parts/console_screen = 5) - // There was an incorrect entry (cablecoil/power). I improvised to cablecoil/heavyduty. - // Another invalid entry, /obj/item/weapon/circuitry. I don't even know what that would translate to, removed it. - // The original products list wasn't finished. The ones without given quantities became quantity 5. -Sayu + products = list(/obj/item/clothing/under/rank/chief_engineer = 4, + /obj/item/clothing/under/rank/engineer = 4, + /obj/item/clothing/shoes/orange = 4, + /obj/item/clothing/head/hardhat = 4, + /obj/item/weapon/storage/belt/utility = 4, + /obj/item/clothing/glasses/meson = 4, + /obj/item/clothing/gloves/yellow = 4, + /obj/item/weapon/tool/screwdriver = 12, + /obj/item/weapon/tool/crowbar = 12, + /obj/item/weapon/tool/wirecutters = 12, + /obj/item/device/multitool = 12, + /obj/item/weapon/tool/wrench = 12, + /obj/item/device/t_scanner = 12, + /obj/item/stack/cable_coil/heavyduty = 8, + /obj/item/weapon/cell = 8, + /obj/item/weapon/weldingtool = 8, + /obj/item/clothing/head/welding = 8, + /obj/item/weapon/light/tube = 10, + /obj/item/clothing/suit/fire = 4, + /obj/item/weapon/stock_parts/scanning_module = 5, + /obj/item/weapon/stock_parts/micro_laser = 5, + /obj/item/weapon/stock_parts/matter_bin = 5, + /obj/item/weapon/stock_parts/manipulator = 5, + /obj/item/weapon/stock_parts/console_screen = 5) req_log_access = access_ce has_logs = 1 @@ -456,17 +691,27 @@ desc = "All the tools you need to create your own robot army." icon_state = "robotics" req_access = list(access_robotics) - products = list(/obj/item/clothing/suit/storage/toggle/labcoat = 4,/obj/item/clothing/under/rank/roboticist = 4,/obj/item/stack/cable_coil = 4,/obj/item/device/flash = 4, - /obj/item/weapon/cell/high = 12, /obj/item/device/assembly/prox_sensor = 3,/obj/item/device/assembly/signaler = 3,/obj/item/device/healthanalyzer = 3, - /obj/item/weapon/surgical/scalpel = 2,/obj/item/weapon/surgical/circular_saw = 2,/obj/item/weapon/tank/anesthetic = 2,/obj/item/clothing/mask/breath/medical = 5, - /obj/item/weapon/tool/screwdriver = 5,/obj/item/weapon/tool/crowbar = 5) - //everything after the power cell had no amounts, I improvised. -Sayu + products = list(/obj/item/clothing/suit/storage/toggle/labcoat = 4, + /obj/item/clothing/under/rank/roboticist = 4, + /obj/item/stack/cable_coil = 4, + /obj/item/device/flash = 4, + /obj/item/weapon/cell/high = 12, + /obj/item/device/assembly/prox_sensor = 3, + /obj/item/device/assembly/signaler = 3, + /obj/item/device/healthanalyzer = 3, + /obj/item/weapon/surgical/scalpel = 2, + /obj/item/weapon/surgical/circular_saw = 2, + /obj/item/weapon/tank/anesthetic = 2, + /obj/item/clothing/mask/breath/medical = 5, + /obj/item/weapon/tool/screwdriver = 5, + /obj/item/weapon/tool/crowbar = 5) req_log_access = access_rd has_logs = 1 /obj/machinery/vending/giftvendor name = "AlliCo Baubles and Confectionaries" desc = "For that special someone!" + description_fluff = "AlliCo Ltd. is a NanoTrasen subsidiary focused on the design and licensing of 'cute' products including toys, gifts, stationary and accessories. Their range of original characters feature in all aspects of popular culture, from snacks to animated series." icon_state = "giftvendor" vend_delay = 15 products = list(/obj/item/weapon/storage/fancy/heartbox = 5, diff --git a/code/game/mecha/components/armor.dm b/code/game/mecha/components/armor.dm index b64c37bca55..ac4ce81ec53 100644 --- a/code/game/mecha/components/armor.dm +++ b/code/game/mecha/components/armor.dm @@ -92,7 +92,7 @@ /obj/item/mecha_parts/component/armor/military name = "military grade mecha plating" - step_delay = 6 + step_delay = 4 max_integrity = 100 @@ -121,14 +121,14 @@ typepass = TRUE if(typepass) - step_delay = 3 + step_delay = 0 else step_delay = initial(step_delay) /obj/item/mecha_parts/component/armor/marshal name = "marshal mecha plating" - step_delay = 5 + step_delay = 3 max_integrity = 100 @@ -215,7 +215,7 @@ /obj/item/mecha_parts/component/armor/alien name = "strange mecha plating" - step_delay = 3 + step_delay = 2 damage_absorption = list( "brute"=0.7, "fire"=0.7, diff --git a/code/game/mecha/equipment/tools/armor_melee.dm b/code/game/mecha/equipment/tools/armor_melee.dm index 085148d938c..ed5724ce649 100644 --- a/code/game/mecha/equipment/tools/armor_melee.dm +++ b/code/game/mecha/equipment/tools/armor_melee.dm @@ -9,7 +9,7 @@ var/deflect_coeff = 1.15 var/damage_coeff = 0.8 - step_delay = 1 + step_delay = 0.5 equip_type = EQUIP_HULL diff --git a/code/game/mecha/equipment/tools/armor_ranged.dm b/code/game/mecha/equipment/tools/armor_ranged.dm index 5b8d6d81721..e1a06bef2d9 100644 --- a/code/game/mecha/equipment/tools/armor_ranged.dm +++ b/code/game/mecha/equipment/tools/armor_ranged.dm @@ -9,7 +9,7 @@ var/deflect_coeff = 1.15 var/damage_coeff = 0.8 - step_delay = 2 + step_delay = 1 equip_type = EQUIP_HULL diff --git a/code/game/mecha/equipment/tools/drill.dm b/code/game/mecha/equipment/tools/drill.dm index 6f44c92d5f9..346481eb66b 100644 --- a/code/game/mecha/equipment/tools/drill.dm +++ b/code/game/mecha/equipment/tools/drill.dm @@ -5,6 +5,7 @@ equip_cooldown = 30 energy_drain = 10 force = 15 + var/advanced = 0 //Determines if you can pierce the heavens or not. Used in diamond drill. required_type = list(/obj/mecha/working/ripley) /obj/item/mecha_parts/mecha_equipment/tool/drill/action(atom/target) @@ -22,11 +23,17 @@ if(T == chassis.loc && src == chassis.selected) if(istype(target, /turf/simulated/wall)) var/turf/simulated/wall/W = target - if(W.reinf_material) + if(W.reinf_material && !advanced)//R wall but no good drill occupant_message("[target] is too durable to drill through.") + return + + else if((W.reinf_material && advanced) || do_after_cooldown(target))//R wall with good drill + log_message("Drilled through [target]") + target.ex_act(3) else log_message("Drilled through [target]") target.ex_act(2) + else if(istype(target, /turf/simulated/mineral)) if(enable_special) for(var/turf/simulated/mineral/M in range(chassis,1)) @@ -54,44 +61,7 @@ origin_tech = list(TECH_MATERIAL = 4, TECH_ENGINEERING = 3) equip_cooldown = 10 force = 15 - -/obj/item/mecha_parts/mecha_equipment/tool/drill/diamonddrill/action(atom/target) - if(!action_checks(target)) return - if(isobj(target)) - var/obj/target_obj = target - if(target_obj.unacidable) return - set_ready_state(0) - chassis.use_power(energy_drain) - chassis.visible_message("[chassis] starts to drill [target]", "You hear the drill.") - occupant_message("You start to drill [target]") - var/T = chassis.loc - var/C = target.loc //why are these backwards? we may never know -Pete - if(do_after_cooldown(target)) - if(T == chassis.loc && src == chassis.selected) - if(istype(target, /turf/simulated/wall)) - var/turf/simulated/wall/W = target - if(!W.reinf_material || do_after_cooldown(target))//To slow down how fast mechs can drill through the station - log_message("Drilled through [target]") - target.ex_act(3) - else if(istype(target, /turf/simulated/mineral)) - if(enable_special) - for(var/turf/simulated/mineral/M in range(chassis,1)) - if(get_dir(chassis,M)&chassis.dir) - M.GetDrilled() - else - var/turf/simulated/mineral/M1 = target - M1.GetDrilled() - log_message("Drilled through [target]") - if(locate(/obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp) in chassis.equipment) - var/obj/structure/ore_box/ore_box = locate(/obj/structure/ore_box) in chassis:cargo - if(ore_box) - for(var/obj/item/weapon/ore/ore in range(chassis,1)) - if(get_dir(chassis,ore)&chassis.dir) - ore.forceMove(ore_box) - else if(target.loc == C) - log_message("Drilled through [target]") - target.ex_act(2) - return 1 + advanced = 1 /obj/item/mecha_parts/mecha_equipment/tool/drill/bore name = "depth bore" diff --git a/code/game/mecha/equipment/tools/shield.dm b/code/game/mecha/equipment/tools/shield.dm index 453c2ba9da9..ce0c43e7da9 100644 --- a/code/game/mecha/equipment/tools/shield.dm +++ b/code/game/mecha/equipment/tools/shield.dm @@ -7,7 +7,7 @@ energy_drain = 20 range = 0 - step_delay = 1 + step_delay = 0.2 var/obj/item/shield_projector/line/exosuit/my_shield = null var/my_shield_type = /obj/item/shield_projector/line/exosuit diff --git a/code/game/mecha/equipment/tools/shield_omni.dm b/code/game/mecha/equipment/tools/shield_omni.dm index aae68ef4cde..ca61a138e42 100644 --- a/code/game/mecha/equipment/tools/shield_omni.dm +++ b/code/game/mecha/equipment/tools/shield_omni.dm @@ -9,7 +9,7 @@ energy_drain = OMNI_SHIELD_DRAIN range = 0 - step_delay = 1 + step_delay = 0.2 var/obj/item/shield_projector/shields = null var/shield_type = /obj/item/shield_projector/rectangle/mecha @@ -48,7 +48,7 @@ log_message("Activated.") else set_ready_state(1) - step_delay = 1 + step_delay = initial(step_delay) log_message("Deactivated.") /obj/item/mecha_parts/mecha_equipment/omni_shield/Topic(href, href_list) diff --git a/code/game/mecha/equipment/weapons/ballistic/shotgun.dm b/code/game/mecha/equipment/weapons/ballistic/shotgun.dm index e6b12d8ebdf..e698248b7f6 100644 --- a/code/game/mecha/equipment/weapons/ballistic/shotgun.dm +++ b/code/game/mecha/equipment/weapons/ballistic/shotgun.dm @@ -11,7 +11,7 @@ deviation = 0.7 projectile_energy_cost = 25 - step_delay = 2 + step_delay = 0.5 origin_tech = list(TECH_MATERIAL = 3, TECH_COMBAT = 4) diff --git a/code/game/mecha/equipment/weapons/energy/laser.dm b/code/game/mecha/equipment/weapons/energy/laser.dm index 0dfcbd1328d..5a480a96918 100644 --- a/code/game/mecha/equipment/weapons/energy/laser.dm +++ b/code/game/mecha/equipment/weapons/energy/laser.dm @@ -52,7 +52,7 @@ projectile = /obj/item/projectile/beam/heavylaser fire_sound = 'sound/weapons/lasercannonfire.ogg' - step_delay = 2 + step_delay = 1 origin_tech = list(TECH_MATERIAL = 3, TECH_COMBAT = 4, TECH_MAGNET = 4) diff --git a/code/game/mecha/equipment/weapons/explosive/missile.dm b/code/game/mecha/equipment/weapons/explosive/missile.dm index df8cf0c3bb3..9ff28ade8e5 100644 --- a/code/game/mecha/equipment/weapons/explosive/missile.dm +++ b/code/game/mecha/equipment/weapons/explosive/missile.dm @@ -2,7 +2,7 @@ var/missile_speed = 2 var/missile_range = 30 - step_delay = 2 + step_delay = 0.5 /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/Fire(atom/movable/AM, atom/target, turf/aimloc) AM.throw_at(target,missile_range, missile_speed, chassis) diff --git a/code/game/mecha/equipment/weapons/fire/flamethrower.dm b/code/game/mecha/equipment/weapons/fire/flamethrower.dm index 532c35a6b48..5e2d79615c6 100644 --- a/code/game/mecha/equipment/weapons/fire/flamethrower.dm +++ b/code/game/mecha/equipment/weapons/fire/flamethrower.dm @@ -7,7 +7,7 @@ energy_drain = 30 - step_delay = 2 + step_delay = 0.5 projectile = /obj/item/projectile/bullet/incendiary/flamethrower/large fire_sound = 'sound/weapons/towelwipe.ogg' diff --git a/code/game/mecha/equipment/weapons/weapons.dm b/code/game/mecha/equipment/weapons/weapons.dm index 9dccf551c9a..fa7e2005c6b 100644 --- a/code/game/mecha/equipment/weapons/weapons.dm +++ b/code/game/mecha/equipment/weapons/weapons.dm @@ -12,7 +12,7 @@ var/auto_rearm = 0 //Does the weapon reload itself after each shot? required_type = list(/obj/mecha/combat, /obj/mecha/working/hoverpod/combatpod) - step_delay = 1 + step_delay = 0.1 equip_type = EQUIP_WEAPON diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index cb48955d0d3..bfdb4508e94 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -674,7 +674,7 @@ break break - return max(1, round(tally)) + return max(1, round(tally, 0.1)) /obj/mecha/proc/dyndomove(direction) if(!can_move) diff --git a/code/game/objects/effects/decals/Cleanable/humans.dm b/code/game/objects/effects/decals/Cleanable/humans.dm index ee02464c1e7..2a37edf7088 100644 --- a/code/game/objects/effects/decals/Cleanable/humans.dm +++ b/code/game/objects/effects/decals/Cleanable/humans.dm @@ -53,7 +53,11 @@ var/global/list/image/splatter_cache=list() /obj/effect/decal/cleanable/blood/update_icon() if(basecolor == "rainbow") basecolor = "#[get_random_colour(1)]" color = basecolor - if(synthblood) + + if(basecolor == SYNTH_BLOOD_COLOUR) + name = "oil" + desc = "It's quite oily." + else if(synthblood) name = "synthetic blood" desc = "It's quite greasy." else diff --git a/code/game/objects/effects/decals/cleanable.dm b/code/game/objects/effects/decals/cleanable.dm index 2ef6582553f..0df27515c78 100644 --- a/code/game/objects/effects/decals/cleanable.dm +++ b/code/game/objects/effects/decals/cleanable.dm @@ -12,12 +12,13 @@ generic_filth = TRUE means when the decal is saved, it will be switched out for var/age = 0 var/list/random_icon_states = list() -/obj/effect/decal/cleanable/Initialize(var/ml, var/_age) +/obj/effect/decal/cleanable/Initialize(var/mapload, var/_age) if(!isnull(_age)) age = _age if(random_icon_states && length(src.random_icon_states) > 0) src.icon_state = pick(src.random_icon_states) - SSpersistence.track_value(src, /datum/persistent/filth) + if(!mapload || !config.persistence_ignore_mapload) + SSpersistence.track_value(src, /datum/persistent/filth) . = ..() /obj/effect/decal/cleanable/Destroy() diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 1df31e38142..13d9f0ab8fa 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -430,11 +430,16 @@ var/list/global/slot_flags_enumeration = list( return 1 /obj/item/proc/mob_can_unequip(mob/M, slot, disable_warning = 0) - if(!slot) return 0 if(!M) return 0 if(!canremove) return 0 + + if(!slot) + if(issilicon(M)) + return 1 // for stuff in grippers + return 0 + if(!M.slot_is_accessible(slot, src, disable_warning? null : M)) return 0 return 1 diff --git a/code/game/objects/items/devices/gps.dm b/code/game/objects/items/devices/gps.dm index 095f565bd41..e14a4c0edf6 100644 --- a/code/game/objects/items/devices/gps.dm +++ b/code/game/objects/items/devices/gps.dm @@ -11,6 +11,7 @@ var/list/GPS_list = list() matter = list(DEFAULT_WALL_MATERIAL = 500) var/gps_tag = "GEN0" var/emped = FALSE + var/updating = TRUE // Lets users lock the UI so they don't have to deal with constantly shifting signals var/tracking = FALSE // Will not show other signals or emit its own signal if false. var/long_range = FALSE // If true, can see farther, depending on get_map_levels(). var/local_mode = FALSE // If true, only GPS signals of the same Z level are shown. @@ -66,7 +67,11 @@ var/list/GPS_list = list() add_overlay("working") /obj/item/device/gps/attack_self(mob/user) - display(user) + tgui_interact(user) + +/obj/item/device/gps/examine(mob/user) + . = ..() + . += display() // Compiles all the data not available directly from the GPS // Like the positions and directions to all other GPS units @@ -117,12 +122,12 @@ var/list/GPS_list = list() return dat -/obj/item/device/gps/proc/display(mob/user) +/obj/item/device/gps/proc/display() if(!tracking) - to_chat(user, "The device is off. Alt-click it to turn it on.") + . = "The device is off. Alt-click it to turn it on." return if(emped) - to_chat(user, "It's busted!") + . = "It's busted!" return var/list/dat = list() @@ -143,8 +148,7 @@ var/list/GPS_list = list() else dat += "No other signals detected." - var/result = dat.Join("
") - to_chat(user, result) + . = dat /obj/item/device/gps/Topic(var/href, var/list/href_list) if(..()) @@ -168,6 +172,85 @@ var/list/GPS_list = list() hide_signal = !hide_signal to_chat(usr, "You set the device to [hide_signal ? "not " : ""]broadcast a signal while scanning for other signals.") +/obj/item/device/gps/tgui_interact(mob/user, datum/tgui/ui) + if(emped) + to_chat(user, "[src] fizzles weakly.") + return + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "Gps", name) + ui.open() + ui.set_autoupdate(updating) + +/obj/item/device/gps/tgui_data(mob/user) + var/list/data = list() + data["power"] = tracking + data["tag"] = gps_tag + data["updating"] = updating + data["globalmode"] = !local_mode + if(!tracking || emped) //Do not bother scanning if the GPS is off or EMPed + return data + + var/turf/curr = get_turf(src) + data["currentArea"] = "[get_area_name(curr, TRUE)]" + data["currentCoords"] = list(curr.x, curr.y, curr.z) + data["currentCoordsText"] = "[curr.x], [curr.y], [using_map.get_zlevel_name(curr.z)]" + + data["zLevelDetection"] = using_map.get_map_levels(curr.z, long_range) + + var/list/signals = list() + data["signals"] = list() + + for(var/obj/item/device/gps/G in GPS_list - src) + if(!G.tracking || G.emped || G.hide_signal) + continue + + var/turf/T = get_turf(G) + if(!T) + continue + if(local_mode && curr.z != T.z) + continue + if(!(T.z in data["zLevelDetection"])) + continue + + var/list/signal = list() + signal["entrytag"] = G.gps_tag //Name or 'tag' of the GPS + signal["coords"] = list(T.x, T.y, T.z) + signal["coordsText"] = "[T.x], [T.y], [using_map.get_zlevel_name(T.z)]" + if(T.z == curr.z) //Distance/Direction calculations for same z-level only + signal["dist"] = max(get_dist(curr, T), 0) //Distance between the src and remote GPS turfs + signal["degrees"] = round(Get_Angle(curr, T)) //0-360 degree directional bearing, for more precision. + signals += list(signal) //Add this signal to the list of signals + data["signals"] = signals + return data + +/obj/item/device/gps/tgui_act(action, params) + if(..()) + return TRUE + + switch(action) + if("rename") + var/a = stripped_input(usr, "Please enter desired tag.", name, gps_tag, 20) + + if(!a) + return + + gps_tag = a + name = "global positioning system ([gps_tag])" + . = TRUE + + if("power") + toggletracking(usr) + . = TRUE + + if("updating") + updating = !updating + . = TRUE + + if("globalmode") + local_mode = !local_mode + . = TRUE + /obj/item/device/gps/on // Defaults to off to avoid polluting the signal list with a bunch of GPSes without owners. If you need to spawn active ones, use these. tracking = TRUE @@ -291,10 +374,10 @@ var/list/GPS_list = list() /obj/item/device/gps/syndie/display(mob/user) if(!tracking) - to_chat(user, "The device is off. Alt-click it to turn it on.") + . = "The device is off. Alt-click it to turn it on." return if(emped) - to_chat(user, "It's busted!") + . = "It's busted!" return var/list/dat = list() @@ -312,5 +395,4 @@ var/list/GPS_list = list() else dat += "No other signals detected." - var/result = dat.Join("
") - to_chat(user, result) + . = dat diff --git a/code/game/objects/items/balls_vr.dm b/code/game/objects/items/toys/balls_vr.dm similarity index 100% rename from code/game/objects/items/balls_vr.dm rename to code/game/objects/items/toys/balls_vr.dm diff --git a/code/game/objects/items/godfigures.dm b/code/game/objects/items/toys/godfigures.dm similarity index 100% rename from code/game/objects/items/godfigures.dm rename to code/game/objects/items/toys/godfigures.dm diff --git a/code/game/objects/items/toys/mech_toys.dm b/code/game/objects/items/toys/mech_toys.dm new file mode 100644 index 00000000000..cf1b4934893 --- /dev/null +++ b/code/game/objects/items/toys/mech_toys.dm @@ -0,0 +1,642 @@ +/* + * Mech toys (previously labeled prizes, but that's unintuitive) + * Mech toy combat + */ + +// Mech battle special attack types. +#define SPECIAL_ATTACK_HEAL 1 +#define SPECIAL_ATTACK_DAMAGE 2 +#define SPECIAL_ATTACK_UTILITY 3 +#define SPECIAL_ATTACK_OTHER 4 + +// Max length of a mech battle +#define MAX_BATTLE_LENGTH 50 + +/obj/item/toy/mecha + icon = 'icons/obj/toy.dmi' + icon_state = "ripleytoy" + drop_sound = 'sound/mecha/mechstep.ogg' + reach = 2 // So you can battle across the table! + + // Mech Battle Vars + var/timer = 0 // Timer when it'll be off cooldown + var/cooldown = 1.5 SECONDS // Cooldown between play sessions (and interactions) + var/cooldown_multiplier = 20 // Cooldown multiplier after a battle (by default: battle cooldowns are 30 seconds) + var/quiet = FALSE // If it makes noise when played with + var/wants_to_battle = FALSE // TRUE = Offering battle to someone || FALSE = Not offering battle + var/in_combat = FALSE // TRUE = in combat currently || FALSE = Not in combat + var/combat_health = 0 // The mech's health in battle + var/max_combat_health = 0 // The mech's max combat health + var/special_attack_charged = FALSE // TRUE = the special attack is charged || FALSE = not charged + var/special_attack_type = 0 // What type of special attack they use - SPECIAL_ATTACK_DAMAGE, SPECIAL_ATTACK_HEAL, SPECIAL_ATTACK_UTILITY, SPECIAL_ATTACK_OTHER + var/special_attack_type_message = "" // What message their special move gets on examining + var/special_attack_cry = "*flip" // The battlecry when using the special attack + var/special_attack_cooldown = 0 // Current cooldown of their special attack + var/wins = 0 // This mech's win count in combat + var/losses = 0 // ...And their loss count in combat + +/obj/item/toy/mecha/Initialize() + . = ..() + desc = "Mini-Mecha action figure! Collect them all! Attack your friends or another mech with one to initiate epic mech combat! [desc]." + combat_health = max_combat_health + switch(special_attack_type) + if(SPECIAL_ATTACK_DAMAGE) + special_attack_type_message = "an aggressive move, which deals bonus damage." + if(SPECIAL_ATTACK_HEAL) + special_attack_type_message = "a defensive move, which grants bonus healing." + if(SPECIAL_ATTACK_UTILITY) + special_attack_type_message = "a utility move, which heals the user and damages the opponent." + if(SPECIAL_ATTACK_OTHER) + special_attack_type_message = "a special move, which [special_attack_type_message]" + else + special_attack_type_message = "a mystery move, even I don't know." + +/obj/item/toy/mecha/proc/in_range(source, user) // Modify our in_range proc specifically for mech battles! + if(get_dist(source, user) <= 2) + return 1 + + return 0 //not in range and not telekinetic + +/** + * this proc combines "sleep" while also checking for if the battle should continue + * + * this goes through some of the checks - the toys need to be next to each other to fight! + * if it's player vs themself: They need to be able to "control" both mechs (either must be adjacent or using TK). + * if it's player vs player: Both players need to be able to "control" their mechs (either must be adjacent or using TK). + * if it's player vs mech (suicide): the mech needs to be in range of the player. + * if all the checks are TRUE, it does the sleeps, and returns TRUE. Otherwise, it returns FALSE. + * Arguments: + * * delay - the amount of time the sleep at the end of the check will sleep for + * * attacker - the attacking toy in the battle. + * * attacker_controller - the controller of the attacking toy. there should ALWAYS be an attacker_controller + * * opponent - (optional) the defender controller in the battle, for PvP + */ + +/obj/item/toy/mecha/proc/combat_sleep(var/delay, obj/item/toy/mecha/attacker, mob/living/carbon/attacker_controller, mob/living/carbon/opponent) + if(!attacker_controller) // If the attacker for whatever reason is null, don't continue. + return FALSE + + if(!attacker) // If there's no attacker, then attacker_controller IS the attacker. + if(!in_range(src, attacker_controller)) + attacker_controller.visible_message("[attacker_controller] is running from [src]! The coward!") + return FALSE + else // If there's an attacker, we can procede as normal. + if(!in_range(src, attacker)) // The two toys aren't next to each other, the battle ends. + attacker_controller.visible_message(" [attacker] and [src] separate, ending the battle. ", \ + " [attacker] and [src] separate, ending the battle. ") + return FALSE + + // Dead men tell no tales, incapacitated men fight no fights. + if(attacker_controller.incapacitated()) + return FALSE + // If the attacker_controller isn't next to the attacking toy (and doesn't have telekinesis), the battle ends. + if(!in_range(attacker, attacker_controller)) + attacker_controller.visible_message(" [attacker_controller.name] seperates from [attacker], ending the battle.", \ + " You separate from [attacker], ending the battle. ") + return FALSE + + // If it's PVP and the opponent is not next to the defending(src) toy (and doesn't have telekinesis), the battle ends. + if(opponent) + if(opponent.incapacitated()) + return FALSE + if(!in_range(src, opponent)) + opponent.visible_message(" [opponent.name] seperates from [src], ending the battle.", \ + " You separate from [src], ending the battle. ") + return FALSE + // If it's not PVP and the attacker_controller isn't next to the defending toy (and doesn't have telekinesis), the battle ends. + else + if (!in_range(src, attacker_controller)) + attacker_controller.visible_message(" [attacker_controller.name] seperates from [src] and [attacker], ending the battle.", \ + " You separate [attacker] and [src], ending the battle. ") + return FALSE + + // If all that is good, then we can sleep peacefully. + sleep(delay) + return TRUE + +//all credit to skasi for toy mech fun ideas +/obj/item/toy/mecha/attack_self(mob/user) + if(timer < world.time) + to_chat(user, "You play with [src].") + timer = world.time + cooldown + playsound(user, 'sound/mecha/mechstep.ogg', 20, TRUE) + else + . = ..() + +/obj/item/toy/mecha/attack_hand(mob/user) + . = ..() + if(.) + return + if(loc == user) + attack_self(user) + +/** + * If you attack a mech with a mech, initiate combat between them + */ +/obj/item/toy/mecha/attackby(obj/item/user_toy, mob/living/user) + if(istype(user_toy, /obj/item/toy/mecha)) + var/obj/item/toy/mecha/M = user_toy + if(check_battle_start(user, M)) + mecha_brawl(M, user) + ..() + +/** + * Attack is called from the user's toy, aimed at target(another human), checking for target's toy. + */ +/obj/item/toy/mecha/attack(mob/living/carbon/human/target, mob/living/carbon/human/user) + if(target == user) + to_chat(user, "Target another toy mech if you want to start a battle with yourself.") + return + else if(user.a_intent != I_HURT) + if(wants_to_battle) //prevent spamming someone with offers + to_chat(user, "You already are offering battle to someone!") + return + if(!check_battle_start(user)) //if the user's mech isn't ready, don't bother checking + return + + for(var/obj/item/I in target.get_all_held_items()) + if(istype(I, /obj/item/toy/mecha)) //if you attack someone with a mech who's also holding a mech, offer to battle them + var/obj/item/toy/mecha/M = I + if(!M.check_battle_start(target, null, user)) //check if the attacker mech is ready + break + + //slap them with the metaphorical white glove + if(M.wants_to_battle) //if the target mech wants to battle, initiate the battle from their POV + mecha_brawl(M, target, user) //P = defender's mech / SRC = attacker's mech / target = defender / user = attacker + M.wants_to_battle = FALSE + return + + //extend the offer of battle to the other mech + var/datum/gender/T = gender_datums[user.get_visible_gender()] + to_chat(user, "You offer battle to [target.name]!") + to_chat(target, "[user.name] wants to battle with [T.His] [name]! Attack them with a toy mech to initiate combat.") + wants_to_battle = TRUE + addtimer(CALLBACK(src, .proc/withdraw_offer, user), 6 SECONDS) + return + + ..() + +/** + * Overrides attack_tk - Sorry, you have to be face to face to initiate a battle, it's good sportsmanship + */ +/obj/item/toy/mecha/attack_tk(mob/user) + if(timer < world.time) + to_chat(user, "You telekinetically play with [src].") + timer = world.time + cooldown + playsound(user, 'sound/mecha/mechstep.ogg', 20, TRUE) + +/** + * Resets the request for battle. + * + * For use in a timer, this proc resets the wants_to_battle variable after a short period. + * Arguments: + * * user - the user wanting to do battle + */ +/obj/item/toy/mecha/proc/withdraw_offer(mob/living/carbon/user) + if(wants_to_battle) + wants_to_battle = FALSE + to_chat(user, "You get the feeling they don't want to battle.") +/** + * Starts a battle, toy mech vs player. Player... doesn't win. Commented out for now as suicide_act is not physically doable. + */ +/obj/item/toy/mecha/suicide_act(mob/living/carbon/user) + if(in_combat) + to_chat(user, "[src] is in battle, let it finish first.") + return + + var/datum/gender/T = gender_datums[user.get_visible_gender()] + user.visible_message("[user] begins a fight [T.His] can't win with [src]! It looks like [T.His] trying to commit suicide!") + + in_combat = TRUE + sleep(1.5 SECONDS) + for(var/i in 1 to 4) + switch(i) + if(1, 3) + SpinAnimation(5, 0) + playsound(src, 'sound/mecha/mechstep.ogg', 30, TRUE) + user.adjustBruteLoss(25) + if(2) + user.SpinAnimation(5, 0) + playsound(user, 'sound/weapons/smash.ogg', 20, TRUE) + combat_health-- //we scratched it! + if(4) + visible_message(special_attack_cry + "!!") + + if(!combat_sleep(1 SECONDS, null, user)) + visible_message("PATHETIC.") + combat_health = max_combat_health + in_combat = FALSE + return (BRUTELOSS) + + sleep(0.5 SECONDS) + user.adjustBruteLoss(450) + + in_combat = FALSE + visible_message("AN EASY WIN. MY POWER INCREASES.") // steal a soul, become swole + color= "#ff7373" + max_combat_health = round(max_combat_health*1.5 + 0.1) + combat_health = max_combat_health + wins++ + return (BRUTELOSS) + +/obj/item/toy/mecha/examine() + . = ..() + . += "This toy's special attack is [special_attack_cry], [special_attack_type_message] " + if(in_combat) + . += "This toy has a maximum health of [max_combat_health]. Currently, it's [combat_health]." + . += "Its special move light is [special_attack_cooldown? "flashing red." : "green and is ready!"]" + else + . += "This toy has a maximum health of [max_combat_health]." + + if(wins || losses) + . += "This toy has [wins] wins, and [losses] losses." + +/** + * The 'master' proc of the mech battle. Processes the entire battle's events and makes sure it start and finishes correctly. + * + * src is the defending toy, and the battle proc is called on it to begin the battle. + * After going through a few checks at the beginning to ensure the battle can start properly, the battle begins a loop that lasts + * until either toy has no more health. During this loop, it also ensures the mechs stay in combat range of each other. + * It will then randomly decide attacks for each toy, occasionally making one or the other use their special attack. + * When either mech has no more health, the loop ends, and it displays the victor and the loser while updating their stats and resetting them. + * Arguments: + * * attacker - the attacking toy, the toy in the attacker_controller's hands + * * attacker_controller - the user, the one who is holding the toys / controlling the fight + * * opponent - optional arg used in Mech PvP battles: the other person who is taking part in the fight (controls src) + */ +/obj/item/toy/mecha/proc/mecha_brawl(obj/item/toy/mecha/attacker, mob/living/carbon/attacker_controller, mob/living/carbon/opponent) + //A GOOD DAY FOR A SWELL BATTLE! + attacker_controller.visible_message(" [attacker_controller.name] collides [attacker] with [src]! Looks like they're preparing for a brawl! ", \ + " You collide [attacker] into [src], sparking a fierce battle! ", \ + " You hear hard plastic smacking into hard plastic.") + + /// Who's in control of the defender (src)? + var/mob/living/carbon/src_controller = (opponent)? opponent : attacker_controller + /// How long has the battle been going? + var/battle_length = 0 + + in_combat = TRUE + attacker.in_combat = TRUE + + //1.5 second cooldown * 20 = 30 second cooldown after a fight + timer = world.time + cooldown*cooldown_multiplier + attacker.timer = world.time + attacker.cooldown*attacker.cooldown_multiplier + + sleep(1 SECONDS) + //--THE BATTLE BEGINS-- + while(combat_health > 0 && attacker.combat_health > 0 && battle_length < MAX_BATTLE_LENGTH) + if(!combat_sleep(0.5 SECONDS, attacker, attacker_controller, opponent)) //combat_sleep checks everything we need to have checked for combat to continue + break + + //before we do anything - deal with charged attacks + if(special_attack_charged) + src_controller.visible_message(" [src] unleashes its special attack!! ", \ + " You unleash [src]'s special attack! ") + special_attack_move(attacker) + else if(attacker.special_attack_charged) + + attacker_controller.visible_message(" [attacker] unleashes its special attack!! ", \ + " You unleash [attacker]'s special attack! ") + attacker.special_attack_move(src) + else + //process the cooldowns + if(special_attack_cooldown > 0) + special_attack_cooldown-- + if(attacker.special_attack_cooldown > 0) + attacker.special_attack_cooldown-- + + //combat commences + switch(rand(1,8)) + if(1 to 3) //attacker wins + if(attacker.special_attack_cooldown == 0 && attacker.combat_health <= round(attacker.max_combat_health/3)) //if health is less than 1/3 and special off CD, use it + attacker.special_attack_charged = TRUE + attacker_controller.visible_message(" [attacker] begins charging its special attack!! ", \ + " You begin charging [attacker]'s special attack! ") + else //just attack + attacker.SpinAnimation(5, 0) + playsound(attacker, 'sound/mecha/mechstep.ogg', 30, TRUE) + combat_health-- + attacker_controller.visible_message(" [attacker] devastates [src]! ", \ + " You ram [attacker] into [src]! ", \ + " You hear hard plastic smacking hard plastic.") + if(prob(5)) + combat_health-- + playsound(src, 'sound/effects/meteorimpact.ogg', 20, TRUE) + attacker_controller.visible_message(" ...and lands a CRIPPLING BLOW! ", \ + " ...and you land a CRIPPLING blow on [src]! ", null) + + if(4) //both lose + attacker.SpinAnimation(5, 0) + SpinAnimation(5, 0) + combat_health-- + attacker.combat_health-- + // This is sloppy but we don't have do_sparks. + var/datum/effect/effect/system/spark_spread/sparksrc = new(src) + playsound(src, "sparks", 50, 1) + sparksrc.set_up(2, 0, src) + sparksrc.attach(src) + sparksrc.start() + var/datum/effect/effect/system/spark_spread/sparkatk = new(attacker) + playsound(attacker, "sparks", 50, 1) + sparkatk.set_up(2, 0, attacker) + sparkatk.attach(attacker) + sparkatk.start() + if(prob(50)) + attacker_controller.visible_message(" [attacker] and [src] clash dramatically, causing sparks to fly! ", \ + " [attacker] and [src] clash dramatically, causing sparks to fly! ", \ + " You hear hard plastic rubbing against hard plastic.") + else + src_controller.visible_message(" [src] and [attacker] clash dramatically, causing sparks to fly! ", \ + " [src] and [attacker] clash dramatically, causing sparks to fly! ", \ + " You hear hard plastic rubbing against hard plastic.") + if(5) //both win + playsound(attacker, 'sound/weapons/parry.ogg', 20, TRUE) + if(prob(50)) + attacker_controller.visible_message(" [src]'s attack deflects off of [attacker]. ", \ + " [src]'s attack deflects off of [attacker]. ", \ + " You hear hard plastic bouncing off hard plastic.") + else + src_controller.visible_message(" [attacker]'s attack deflects off of [src]. ", \ + " [attacker]'s attack deflects off of [src]. ", \ + " You hear hard plastic bouncing off hard plastic.") + + if(6 to 8) //defender wins + if(special_attack_cooldown == 0 && combat_health <= round(max_combat_health/3)) //if health is less than 1/3 and special off CD, use it + special_attack_charged = TRUE + src_controller.visible_message(" [src] begins charging its special attack!! ", \ + " You begin charging [src]'s special attack! ") + else //just attack + SpinAnimation(5, 0) + playsound(src, 'sound/mecha/mechstep.ogg', 30, TRUE) + attacker.combat_health-- + src_controller.visible_message(" [src] smashes [attacker]! ", \ + " You smash [src] into [attacker]! ", \ + " You hear hard plastic smashing hard plastic.") + if(prob(5)) + attacker.combat_health-- + playsound(attacker, 'sound/effects/meteorimpact.ogg', 20, TRUE) + src_controller.visible_message(" ...and lands a CRIPPLING BLOW! ", \ + " ...and you land a CRIPPLING blow on [attacker]! ", null) + else + attacker_controller.visible_message(" [src] and [attacker] stand around awkwardly.", \ + " You don't know what to do next.") + + battle_length++ + sleep(0.5 SECONDS) + + /// Lines chosen for the winning mech + var/list/winlines = list("YOU'RE NOTHING BUT SCRAP!", "I'LL YIELD TO NONE!", "GLORY IS MINE!", "AN EASY FIGHT.", "YOU SHOULD HAVE NEVER FACED ME.", "ROCKED AND SOCKED.") + + if(attacker.combat_health <= 0 && combat_health <= 0) //both lose + playsound(src, 'sound/machines/warning-buzzer.ogg', 20, TRUE) + attacker_controller.visible_message(" MUTUALLY ASSURED DESTRUCTION!! [src] and [attacker] both end up destroyed!", \ + " Both [src] and [attacker] are destroyed!") + else if(attacker.combat_health <= 0) //src wins + wins++ + attacker.losses++ + playsound(attacker, 'sound/effects/light_flicker.ogg', 20, TRUE) + attacker_controller.visible_message(" [attacker] falls apart!", \ + " [attacker] falls apart!", null) + visible_message("[pick(winlines)]") + src_controller.visible_message(" [src] destroys [attacker] and walks away victorious!", \ + " You raise up [src] victoriously over [attacker]!") + else if (combat_health <= 0) //attacker wins + attacker.wins++ + losses++ + playsound(src, 'sound/effects/light_flicker.ogg', 20, TRUE) + src_controller.visible_message(" [src] collapses!", \ + " [src] collapses!", null) + attacker.visible_message("[pick(winlines)]") + attacker_controller.visible_message(" [attacker] demolishes [src] and walks away victorious!", \ + " You raise up [attacker] proudly over [src]!") + else //both win? + visible_message("NEXT TIME.") + //don't want to make this a one sided conversation + quiet? attacker.visible_message("I WENT EASY ON YOU.") : attacker.visible_message("OF COURSE.") + + in_combat = FALSE + attacker.in_combat = FALSE + + combat_health = max_combat_health + attacker.combat_health = attacker.max_combat_health + + return + +/** + * This proc checks if a battle can be initiated between src and attacker. + * + * Both SRC and attacker (if attacker is included) timers are checked if they're on cooldown, and + * both SRC and attacker (if attacker is included) are checked if they are in combat already. + * If any of the above are true, the proc returns FALSE and sends a message to user (and target, if included) otherwise, it returns TRUE + * Arguments: + * * user: the user who is initiating the battle + * * attacker: optional arg for checking two mechs at once + * * target: optional arg used in Mech PvP battles (if used, attacker is target's toy) + */ +/obj/item/toy/mecha/proc/check_battle_start(mob/living/carbon/user, obj/item/toy/mecha/attacker, mob/living/carbon/target) + var/datum/gender/T + if(target) + T = gender_datums[target.get_visible_gender()] // Doing this because Polaris Code has shitty gender datums and it's clunkier than FUCK. + if(attacker && attacker.in_combat) + to_chat(user, "[target ? T.His : "Your" ] [attacker.name] is in combat.") + if(target) + to_chat(target, "Your [attacker.name] is in combat.") + return FALSE + if(in_combat) + to_chat(user, "Your [name] is in combat.") + if(target) + to_chat(target, "[T.His] [name] is in combat.") + return FALSE + if(attacker && attacker.timer > world.time) + to_chat(user, "[target?T.His : "Your" ] [attacker.name] isn't ready for battle.") + if(target) + to_chat(target, "Your [attacker.name] isn't ready for battle.") + return FALSE + if(timer > world.time) + to_chat(user, "Your [name] isn't ready for battle.") + if(target) + to_chat(target, "[T.His] [name] isn't ready for battle.") + return FALSE + + return TRUE + +/** + * Processes any special attack moves that happen in the battle (called in the mechaBattle proc). + * + * Makes the toy shout their special attack cry and updates its cooldown. Then, does the special attack. + * Arguments: + * * victim - the toy being hit by the special move + */ +/obj/item/toy/mecha/proc/special_attack_move(obj/item/toy/mecha/victim) + visible_message(special_attack_cry + "!!") + + special_attack_charged = FALSE + special_attack_cooldown = 3 + + switch(special_attack_type) + if(SPECIAL_ATTACK_DAMAGE) //+2 damage + victim.combat_health-=2 + playsound(src, 'sound/weapons/marauder.ogg', 20, TRUE) + if(SPECIAL_ATTACK_HEAL) //+2 healing + combat_health+=2 + playsound(src, 'sound/mecha/mech_shield_raise.ogg', 20, TRUE) + if(SPECIAL_ATTACK_UTILITY) //+1 heal, +1 damage + victim.combat_health-- + combat_health++ + playsound(src, 'sound/mecha/mechmove01.ogg', 30, TRUE) + if(SPECIAL_ATTACK_OTHER) //other + super_special_attack(victim) + else + visible_message("I FORGOT MY SPECIAL ATTACK...") + +/** + * Base proc for 'other' special attack moves. + * + * This one is only for inheritance, each mech with an 'other' type move has their procs below. + * Arguments: + * * victim - the toy being hit by the super special move (doesn't necessarily need to be used) + */ +/obj/item/toy/mecha/proc/super_special_attack(obj/item/toy/mecha/victim) + visible_message(" [src] does a cool flip.") + +/obj/random/mech_toy + name = "Random Mech Toy" + desc = "This is a random mech toy." + icon = 'icons/obj/toy.dmi' + icon_state = "ripleytoy" + +/obj/random/mech_toy/item_to_spawn() + return pick(typesof(/obj/item/toy/mecha)) + +/obj/item/toy/mecha/ripley + name = "toy ripley" + desc = "Mini-Mecha action figure! Collect them all! 1/11." + max_combat_health = 4 // 200 integrity + special_attack_type = SPECIAL_ATTACK_DAMAGE + special_attack_cry = "GIGA DRILL BREAK" + +/obj/item/toy/mecha/fireripley + name = "toy firefighting ripley" + desc = "Mini-Mecha action figure! Collect them all! 2/11." + icon_state = "fireripleytoy" + max_combat_health = 5 // 250 integrity? + special_attack_type = SPECIAL_ATTACK_UTILITY + special_attack_cry = "FIRE SHIELD" + +/obj/item/toy/mecha/deathripley + name = "toy deathsquad ripley" + desc = "Mini-Mecha action figure! Collect them all! 3/11." + icon_state = "deathripleytoy" + max_combat_health = 5 // 250 integrity + special_attack_type = SPECIAL_ATTACK_OTHER + special_attack_type_message = "instantly destroys the opposing mech if its health is less than this mech's health." + special_attack_cry = "KILLER CLAMP" + +/obj/item/toy/mecha/deathripley/super_special_attack(obj/item/toy/mecha/victim) + playsound(src, 'sound/weapons/sonic_jackhammer.ogg', 20, TRUE) + if(victim.combat_health < combat_health) // Instantly kills the other mech if it's health is below our's. + visible_message("EXECUTE!!") + victim.combat_health = 0 + else // Otherwise, just deal one damage. + victim.combat_health-- + +/obj/item/toy/mecha/gygax + name = "toy gygax" + desc = "Mini-Mecha action figure! Collect them all! 4/11." + icon_state = "gygaxtoy" + max_combat_health = 5 // 250 integrity + special_attack_type = SPECIAL_ATTACK_UTILITY + special_attack_cry = "SUPER SERVOS" + +/obj/item/toy/mecha/durand + name = "toy durand" + desc = "Mini-Mecha action figure! Collect them all! 5/11." + icon_state = "durandtoy" + max_combat_health = 6 // 400 integrity + special_attack_type = SPECIAL_ATTACK_HEAL + special_attack_cry = "SHIELD OF PROTECTION" + +/obj/item/toy/mecha/honk + name = "toy H.O.N.K." + desc = "Mini-Mecha action figure! Collect them all! 6/11." + icon_state = "honktoy" + max_combat_health = 4 // 140 integrity + special_attack_type = SPECIAL_ATTACK_OTHER + special_attack_type_message = "puts the opposing mech's special move on cooldown and heals this mech." + special_attack_cry = "MEGA HORN" + +/obj/item/toy/mecha/honk/super_special_attack(obj/item/toy/mecha/victim) + playsound(src, 'sound/machines/honkbot_evil_laugh.ogg', 20, TRUE) + victim.special_attack_cooldown += 3 // Adds cooldown to the other mech and gives a minor self heal + combat_health++ + +/obj/item/toy/mecha/marauder + name = "toy marauder" + desc = "Mini-Mecha action figure! Collect them all! 7/11." + icon_state = "maraudertoy" + max_combat_health = 7 // 500 integrity + special_attack_type = SPECIAL_ATTACK_DAMAGE + special_attack_cry = "BEAM BLAST" + +/obj/item/toy/mecha/seraph + name = "toy seraph" + desc = "Mini-Mecha action figure! Collect them all! 8/11." + icon_state = "seraphtoy" + max_combat_health = 8 // 550 integrity + special_attack_type = SPECIAL_ATTACK_DAMAGE + special_attack_cry = "ROCKET BARRAGE" + +/obj/item/toy/mecha/mauler + name = "toy mauler" + desc = "Mini-Mecha action figure! Collect them all! 9/11." + icon_state = "maulertoy" + max_combat_health = 7 // 500 integrity + special_attack_type = SPECIAL_ATTACK_DAMAGE + special_attack_cry = "BULLET STORM" + +/obj/item/toy/mecha/odysseus + name = "toy odysseus" + desc = "Mini-Mecha action figure! Collect them all! 10/11." + icon_state = "odysseustoy" + max_combat_health = 4 // 120 integrity + special_attack_type = SPECIAL_ATTACK_HEAL + special_attack_cry = "MECHA BEAM" + +/obj/item/toy/mecha/phazon + name = "toy phazon" + desc = "Mini-Mecha action figure! Collect them all! 11/11." + icon_state = "phazontoy" + max_combat_health = 6 // 200 integrity + special_attack_type = SPECIAL_ATTACK_UTILITY + special_attack_cry = "NO-CLIP" + +/* // TG-Station Added toys, commenting these out until I port 'em later. +/obj/item/toy/mecha/reticence + name = "toy Reticence" + desc = "12/13" + icon_state = "reticencetoy" + quiet = TRUE + max_combat_health = 4 //100 integrity + special_attack_type = SPECIAL_ATTACK_OTHER + special_attack_type_message = "has a lower cooldown than normal special moves, increases the opponent's cooldown, and deals damage." + special_attack_cry = "*wave" + +/obj/item/toy/mecha/reticence/super_special_attack(obj/item/toy/mecha/victim) + special_attack_cooldown-- //Has a lower cooldown... + victim.special_attack_cooldown++ //and increases the opponent's cooldown by 1... + victim.combat_health-- //and some free damage. + +/obj/item/toy/mecha/clarke + name = "toy Clarke" + desc = "13/13" + icon_state = "clarketoy" + max_combat_health = 4 //200 integrity + special_attack_type = SPECIAL_ATTACK_UTILITY + special_attack_cry = "ROLL OUT" +*/ + +#undef SPECIAL_ATTACK_HEAL +#undef SPECIAL_ATTACK_DAMAGE +#undef SPECIAL_ATTACK_UTILITY +#undef SPECIAL_ATTACK_OTHER +#undef MAX_BATTLE_LENGTH \ No newline at end of file diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys/toys.dm similarity index 92% rename from code/game/objects/items/toys.dm rename to code/game/objects/items/toys/toys.dm index 7873f78a60f..7ce9851c7bf 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys/toys.dm @@ -1,1530 +1,1441 @@ -/* Toys! - * Contains: - * Balloons - * Fake telebeacon - * Fake singularity - * Toy gun - * Toy crossbow - * Toy swords - * Toy bosun's whistle - * Toy mechs - * Snap pops - * Water flower - * Therapy dolls - * Toddler doll - * Inflatable duck - * Action figures - * Plushies - * Toy cult sword - * Bouquets - Stick Horse - */ - - -/obj/item/toy - throwforce = 0 - throw_speed = 4 - throw_range = 20 - force = 0 - drop_sound = 'sound/items/drop/gloves.ogg' - - -/* - * Balloons - */ -/obj/item/toy/balloon - name = "water balloon" - desc = "A translucent balloon. There's nothing in it." - icon = 'icons/obj/toy.dmi' - icon_state = "waterballoon-e" - drop_sound = 'sound/items/drop/rubber.ogg' - -/obj/item/toy/balloon/New() - var/datum/reagents/R = new/datum/reagents(10) - reagents = R - R.my_atom = src - -/obj/item/toy/balloon/attack(mob/living/carbon/human/M as mob, mob/user as mob) - return - -/obj/item/toy/balloon/afterattack(atom/A as mob|obj, mob/user as mob, proximity) - if(!proximity) return - if (istype(A, /obj/structure/reagent_dispensers/watertank) && get_dist(src,A) <= 1) - A.reagents.trans_to_obj(src, 10) - to_chat(user, "You fill the balloon with the contents of [A].") - src.desc = "A translucent balloon with some form of liquid sloshing around in it." - src.update_icon() - return - -/obj/item/toy/balloon/attackby(obj/O as obj, mob/user as mob) - if(istype(O, /obj/item/weapon/reagent_containers/glass)) - if(O.reagents) - if(O.reagents.total_volume < 1) - to_chat(user, "The [O] is empty.") - else if(O.reagents.total_volume >= 1) - if(O.reagents.has_reagent("pacid", 1)) - to_chat(user, "The acid chews through the balloon!") - O.reagents.splash(user, reagents.total_volume) - qdel(src) - else - src.desc = "A translucent balloon with some form of liquid sloshing around in it." - to_chat(user, "You fill the balloon with the contents of [O].") - O.reagents.trans_to_obj(src, 10) - src.update_icon() - return - -/obj/item/toy/balloon/throw_impact(atom/hit_atom) - if(src.reagents.total_volume >= 1) - src.visible_message("\The [src] bursts!","You hear a pop and a splash.") - src.reagents.touch_turf(get_turf(hit_atom)) - for(var/atom/A in get_turf(hit_atom)) - src.reagents.touch(A) - src.icon_state = "burst" - spawn(5) - if(src) - qdel(src) - return - -/obj/item/toy/balloon/update_icon() - if(src.reagents.total_volume >= 1) - icon_state = "waterballoon" - else - icon_state = "waterballoon-e" - -/obj/item/toy/syndicateballoon - name = "criminal balloon" - desc = "There is a tag on the back that reads \"FUK NT!11!\"." - throwforce = 0 - throw_speed = 4 - throw_range = 20 - force = 0 - icon = 'icons/obj/weapons.dmi' - icon_state = "syndballoon" - w_class = ITEMSIZE_LARGE - drop_sound = 'sound/items/drop/rubber.ogg' - -/obj/item/toy/nanotrasenballoon - name = "criminal balloon" - desc = "Across the balloon the following is printed: \"Man, I love NanoTrasen soooo much. I use only NT products. You have NO idea.\"" - throwforce = 0 - throw_speed = 4 - throw_range = 20 - force = 0 - icon = 'icons/obj/weapons.dmi' - icon_state = "ntballoon" - w_class = ITEMSIZE_LARGE - drop_sound = 'sound/items/drop/rubber.ogg' - -/* - * Fake telebeacon - */ -/obj/item/toy/blink - name = "electronic blink toy game" - desc = "Blink. Blink. Blink. Ages 8 and up." - icon = 'icons/obj/radio.dmi' - icon_state = "beacon" - item_state = "signaler" - -/* - * Fake singularity - */ -/obj/item/toy/spinningtoy - name = "gravitational singularity" - desc = "\"Singulo\" brand spinning toy." - icon = 'icons/obj/singularity.dmi' - icon_state = "singularity_s1" - -/* - * Toy crossbow - */ - -/obj/item/toy/crossbow - name = "foam dart crossbow" - desc = "A weapon favored by many overactive children. Ages 8 and up." - icon = 'icons/obj/gun.dmi' - icon_state = "crossbow" - item_icons = list( - icon_l_hand = 'icons/mob/items/lefthand_guns.dmi', - icon_r_hand = 'icons/mob/items/righthand_guns.dmi', - ) - slot_flags = SLOT_HOLSTER - w_class = ITEMSIZE_SMALL - attack_verb = list("attacked", "struck", "hit") - var/bullets = 5 - drop_sound = 'sound/items/drop/gun.ogg' - - examine(mob/user) - . = ..() - if(bullets && get_dist(user, src) <= 2) - . += "It is loaded with [bullets] foam darts!" - - attackby(obj/item/I as obj, mob/user as mob) - if(istype(I, /obj/item/toy/ammo/crossbow)) - if(bullets <= 4) - user.drop_item() - qdel(I) - bullets++ - to_chat(user, "You load the foam dart into the crossbow.") - else - to_chat(usr, "It's already fully loaded.") - - - afterattack(atom/target as mob|obj|turf|area, mob/user as mob, flag) - if(!isturf(target.loc) || target == user) return - if(flag) return - - if (locate (/obj/structure/table, src.loc)) - return - else if (bullets) - var/turf/trg = get_turf(target) - var/obj/effect/foam_dart_dummy/D = new/obj/effect/foam_dart_dummy(get_turf(src)) - bullets-- - D.icon_state = "foamdart" - D.name = "foam dart" - playsound(src, 'sound/items/syringeproj.ogg', 50, 1) - - for(var/i=0, i<6, i++) - if (D) - if(D.loc == trg) break - step_towards(D,trg) - - for(var/mob/living/M in D.loc) - if(!istype(M,/mob/living)) continue - if(M == user) continue - for(var/mob/O in viewers(world.view, D)) - O.show_message(text("\The [] was hit by the foam dart!", M), 1) - new /obj/item/toy/ammo/crossbow(M.loc) - qdel(D) - return - - for(var/atom/A in D.loc) - if(A == user) continue - if(A.density) - new /obj/item/toy/ammo/crossbow(A.loc) - qdel(D) - - sleep(1) - - spawn(10) - if(D) - new /obj/item/toy/ammo/crossbow(D.loc) - qdel(D) - - return - else if (bullets == 0) - user.Weaken(5) - for(var/mob/O in viewers(world.view, user)) - O.show_message(text("\The [] realized they were out of ammo and starting scrounging for some!", user), 1) - - - attack(mob/M as mob, mob/user as mob) - src.add_fingerprint(user) - -// ******* Check - - if (src.bullets > 0 && M.lying) - - for(var/mob/O in viewers(M, null)) - if(O.client) - O.show_message(text("\The [] casually lines up a shot with []'s head and pulls the trigger!", user, M), 1, "You hear the sound of foam against skull", 2) - O.show_message(text("\The [] was hit in the head by the foam dart!", M), 1) - - playsound(src, 'sound/items/syringeproj.ogg', 50, 1) - new /obj/item/toy/ammo/crossbow(M.loc) - src.bullets-- - else if (M.lying && src.bullets == 0) - for(var/mob/O in viewers(M, null)) - if (O.client) O.show_message(text("\The [] casually lines up a shot with []'s head, pulls the trigger, then realizes they are out of ammo and drops to the floor in search of some!", user, M), 1, "You hear someone fall", 2) - user.Weaken(5) - return - -/obj/item/toy/ammo/crossbow - name = "foam dart" - desc = "It's nerf or nothing! Ages 8 and up." - icon = 'icons/obj/toy.dmi' - icon_state = "foamdart" - w_class = ITEMSIZE_TINY - slot_flags = SLOT_EARS - drop_sound = 'sound/items/drop/food.ogg' - -/obj/effect/foam_dart_dummy - name = "" - desc = "" - icon = 'icons/obj/toy.dmi' - icon_state = "null" - anchored = 1 - density = 0 - -/* - * Toy swords - */ -/obj/item/toy/sword - name = "toy sword" - desc = "A cheap, plastic replica of an energy sword. Realistic sounds! Ages 8 and up." - icon = 'icons/obj/weapons.dmi' - icon_state = "esword" - drop_sound = 'sound/items/drop/gun.ogg' - var/lcolor - var/rainbow = FALSE - item_icons = list( - slot_l_hand_str = 'icons/mob/items/lefthand_melee.dmi', - slot_r_hand_str = 'icons/mob/items/righthand_melee.dmi', - ) - var/active = 0 - w_class = ITEMSIZE_SMALL - attack_verb = list("attacked", "struck", "hit") - - attack_self(mob/user as mob) - src.active = !( src.active ) - if (src.active) - to_chat(user, "You extend the plastic blade with a quick flick of your wrist.") - playsound(src, 'sound/weapons/saberon.ogg', 50, 1) - src.item_state = "[icon_state]_blade" - src.w_class = ITEMSIZE_LARGE - else - to_chat(user, "You push the plastic blade back down into the handle.") - playsound(src, 'sound/weapons/saberoff.ogg', 50, 1) - src.item_state = "[icon_state]" - src.w_class = ITEMSIZE_SMALL - update_icon() - src.add_fingerprint(user) - return - -/obj/item/toy/sword/update_icon() - . = ..() - var/mutable_appearance/blade_overlay = mutable_appearance(icon, "[icon_state]_blade") - blade_overlay.color = lcolor - cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other - if(active) - add_overlay(blade_overlay) - if(istype(usr,/mob/living/carbon/human)) - var/mob/living/carbon/human/H = usr - H.update_inv_l_hand() - H.update_inv_r_hand() - -/obj/item/toy/sword/AltClick(mob/living/user) - if(!in_range(src, user)) //Basic checks to prevent abuse - return - if(user.incapacitated() || !istype(user)) - to_chat(user, "You can't do that right now!") - return - - if(alert("Are you sure you want to recolor your blade?", "Confirm Recolor", "Yes", "No") == "Yes") - var/energy_color_input = input(usr,"","Choose Energy Color",lcolor) as color|null - if(energy_color_input) - lcolor = sanitize_hexcolor(energy_color_input) - update_icon() - -/obj/item/toy/sword/examine(mob/user) - . = ..() - . += "Alt-click to recolor it." - -/obj/item/toy/sword/attackby(obj/item/weapon/W, mob/user) - if(istype(W, /obj/item/device/multitool) && !active) - if(!rainbow) - rainbow = TRUE - else - rainbow = FALSE - to_chat(user, "You manipulate the color controller in [src].") - update_icon() -/obj/item/toy/katana - name = "replica katana" - desc = "Woefully underpowered in D20." - icon = 'icons/obj/weapons.dmi' - icon_state = "katana" - item_state = "katana" - item_icons = list( - slot_l_hand_str = 'icons/mob/items/lefthand_material.dmi', - slot_r_hand_str = 'icons/mob/items/righthand_material.dmi', - ) - slot_flags = SLOT_BELT | SLOT_BACK - force = 5 - throwforce = 5 - w_class = ITEMSIZE_NORMAL - attack_verb = list("attacked", "slashed", "stabbed", "sliced") - -/* - * Snap pops - */ -/obj/item/toy/snappop - name = "snap pop" - desc = "Wow!" - icon = 'icons/obj/toy.dmi' - icon_state = "snappop" - w_class = ITEMSIZE_TINY - drop_sound = null - - throw_impact(atom/hit_atom) - ..() - var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread - s.set_up(3, 1, src) - s.start() - new /obj/effect/decal/cleanable/ash(src.loc) - src.visible_message("The [src.name] explodes!","You hear a snap!") - playsound(src, 'sound/effects/snap.ogg', 50, 1) - qdel(src) - -/obj/item/toy/snappop/Crossed(atom/movable/H as mob|obj) - if(H.is_incorporeal()) - return - if((ishuman(H))) //i guess carp and shit shouldn't set them off - var/mob/living/carbon/M = H - if(M.m_intent == "run") - to_chat(M, "You step on the snap pop!") - - var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread - s.set_up(2, 0, src) - s.start() - new /obj/effect/decal/cleanable/ash(src.loc) - src.visible_message("The [src.name] explodes!","You hear a snap!") - playsound(src, 'sound/effects/snap.ogg', 50, 1) - qdel(src) - -/* - * Bosun's whistle - */ - -/obj/item/toy/bosunwhistle - name = "bosun's whistle" - desc = "A genuine Admiral Krush Bosun's Whistle, for the aspiring ship's captain! Suitable for ages 8 and up, do not swallow." - icon = 'icons/obj/toy.dmi' - icon_state = "bosunwhistle" - drop_sound = 'sound/items/drop/card.ogg' - var/cooldown = 0 - w_class = ITEMSIZE_TINY - slot_flags = SLOT_EARS | SLOT_HOLSTER - -/obj/item/toy/bosunwhistle/attack_self(mob/user as mob) - if(cooldown < world.time - 35) - to_chat(user, "You blow on [src], creating an ear-splitting noise!") - playsound(src, 'sound/misc/boatswain.ogg', 20, 1) - cooldown = world.time - -/* - * Mech prizes - */ -/obj/item/toy/prize - icon = 'icons/obj/toy.dmi' - icon_state = "ripleytoy" - var/cooldown = 0 - drop_sound = 'sound/mecha/mechstep.ogg' - -//all credit to skasi for toy mech fun ideas -/obj/item/toy/prize/attack_self(mob/user as mob) - if(cooldown < world.time - 8) - to_chat(user, "You play with [src].") - playsound(src, 'sound/mecha/mechstep.ogg', 20, 1) - cooldown = world.time - -/obj/item/toy/prize/attack_hand(mob/user as mob) - if(loc == user) - if(cooldown < world.time - 8) - to_chat(user, "You play with [src].") - playsound(src, 'sound/mecha/mechturn.ogg', 20, 1) - cooldown = world.time - return - ..() - -/obj/random/mech_toy - name = "Random Mech Toy" - desc = "This is a random mech toy." - icon = 'icons/obj/toy.dmi' - icon_state = "ripleytoy" - -/obj/random/mech_toy/item_to_spawn() - return pick(typesof(/obj/item/toy/prize)) - -/obj/item/toy/prize/ripley - name = "toy ripley" - desc = "Mini-Mecha action figure! Collect them all! 1/11." - -/obj/item/toy/prize/fireripley - name = "toy firefighting ripley" - desc = "Mini-Mecha action figure! Collect them all! 2/11." - icon_state = "fireripleytoy" - -/obj/item/toy/prize/deathripley - name = "toy deathsquad ripley" - desc = "Mini-Mecha action figure! Collect them all! 3/11." - icon_state = "deathripleytoy" - -/obj/item/toy/prize/gygax - name = "toy gygax" - desc = "Mini-Mecha action figure! Collect them all! 4/11." - icon_state = "gygaxtoy" - -/obj/item/toy/prize/durand - name = "toy durand" - desc = "Mini-Mecha action figure! Collect them all! 5/11." - icon_state = "durandprize" - -/obj/item/toy/prize/honk - name = "toy H.O.N.K." - desc = "Mini-Mecha action figure! Collect them all! 6/11." - icon_state = "honkprize" - -/obj/item/toy/prize/marauder - name = "toy marauder" - desc = "Mini-Mecha action figure! Collect them all! 7/11." - icon_state = "marauderprize" - -/obj/item/toy/prize/seraph - name = "toy seraph" - desc = "Mini-Mecha action figure! Collect them all! 8/11." - icon_state = "seraphprize" - -/obj/item/toy/prize/mauler - name = "toy mauler" - desc = "Mini-Mecha action figure! Collect them all! 9/11." - icon_state = "maulerprize" - -/obj/item/toy/prize/odysseus - name = "toy odysseus" - desc = "Mini-Mecha action figure! Collect them all! 10/11." - icon_state = "odysseusprize" - -/obj/item/toy/prize/phazon - name = "toy phazon" - desc = "Mini-Mecha action figure! Collect them all! 11/11." - icon_state = "phazonprize" - -/* - * Action figures - */ -/obj/item/toy/figure - name = "Non-Specific Action Figure action figure" - desc = "A \"Space Life\" brand... wait, what the hell is this thing?" - icon = 'icons/obj/toy.dmi' - icon_state = "nuketoy" - var/cooldown = 0 - var/toysay = "What the fuck did you do?" - drop_sound = 'sound/items/drop/accessory.ogg' - -/obj/item/toy/figure/New() - ..() - desc = "A \"Space Life\" brand [name]" - -/obj/item/toy/figure/attack_self(mob/user as mob) - if(cooldown < world.time) - cooldown = (world.time + 30) //3 second cooldown - user.visible_message("The [src] says \"[toysay]\".") - playsound(src, 'sound/machines/click.ogg', 20, 1) - -/obj/item/toy/figure/cmo - name = "Chief Medical Officer action figure" - desc = "A \"Space Life\" brand Chief Medical Officer action figure." - icon_state = "cmo" - toysay = "Suit sensors!" - -/obj/item/toy/figure/assistant - name = "Assistant action figure" - desc = "A \"Space Life\" brand Assistant action figure." - icon_state = "assistant" - toysay = "Grey tide station wide!" - -/obj/item/toy/figure/atmos - name = "Atmospheric Technician action figure" - desc = "A \"Space Life\" brand Atmospheric Technician action figure." - icon_state = "atmos" - toysay = "Glory to Atmosia!" - -/obj/item/toy/figure/bartender - name = "Bartender action figure" - desc = "A \"Space Life\" brand Bartender action figure." - icon_state = "bartender" - toysay = "Where's my monkey?" - -/obj/item/toy/figure/borg - name = "Drone action figure" - desc = "A \"Space Life\" brand Drone action figure." - icon_state = "borg" - toysay = "I. LIVE. AGAIN." - -/obj/item/toy/figure/gardener - name = "Gardener action figure" - desc = "A \"Space Life\" brand Gardener action figure." - icon_state = "botanist" - toysay = "Dude, I see colors..." - -/obj/item/toy/figure/captain - name = "Colony Director action figure" - desc = "A \"Space Life\" brand Colony Director action figure." - icon_state = "captain" - toysay = "How do I open this display case?" - -/obj/item/toy/figure/cargotech - name = "Cargo Technician action figure" - desc = "A \"Space Life\" brand Cargo Technician action figure." - icon_state = "cargotech" - toysay = "For Cargonia!" - -/obj/item/toy/figure/ce - name = "Chief Engineer action figure" - desc = "A \"Space Life\" brand Chief Engineer action figure." - icon_state = "ce" - toysay = "Wire the solars!" - -/obj/item/toy/figure/chaplain - name = "Chaplain action figure" - desc = "A \"Space Life\" brand Chaplain action figure." - icon_state = "chaplain" - toysay = "Gods make me a killing machine please!" - -/obj/item/toy/figure/chef - name = "Chef action figure" - desc = "A \"Space Life\" brand Chef action figure." - icon_state = "chef" - toysay = "I swear it's not human meat." - -/obj/item/toy/figure/chemist - name = "Chemist action figure" - desc = "A \"Space Life\" brand Chemist action figure." - icon_state = "chemist" - toysay = "Get your pills!" - -/obj/item/toy/figure/clown - name = "Clown action figure" - desc = "A \"Space Life\" brand Clown action figure." - icon_state = "clown" - toysay = "Honk!" - -/obj/item/toy/figure/corgi - name = "Corgi action figure" - desc = "A \"Space Life\" brand Corgi action figure." - icon_state = "ian" - toysay = "Arf!" - -/obj/item/toy/figure/detective - name = "Detective action figure" - desc = "A \"Space Life\" brand Detective action figure." - icon_state = "detective" - toysay = "This airlock has grey jumpsuit and insulated glove fibers on it." - -/obj/item/toy/figure/dsquad - name = "Space Commando action figure" - desc = "A \"Space Life\" brand Space Commando action figure." - icon_state = "dsquad" - toysay = "Eliminate all threats!" - -/obj/item/toy/figure/engineer - name = "Engineer action figure" - desc = "A \"Space Life\" brand Engineer action figure." - icon_state = "engineer" - toysay = "Oh god, the engine is gonna go!" - -/obj/item/toy/figure/geneticist - name = "Geneticist action figure" - desc = "A \"Space Life\" brand Geneticist action figure, which was recently dicontinued." - icon_state = "geneticist" - toysay = "I'm not qualified for this job." - -/obj/item/toy/figure/hop - name = "Head of Personnel action figure" - desc = "A \"Space Life\" brand Head of Personnel action figure." - icon_state = "hop" - toysay = "Giving out all access!" - -/obj/item/toy/figure/hos - name = "Head of Security action figure" - desc = "A \"Space Life\" brand Head of Security action figure." - icon_state = "hos" - toysay = "I'm here to win, anything else is secondary." - -/obj/item/toy/figure/qm - name = "Quartermaster action figure" - desc = "A \"Space Life\" brand Quartermaster action figure." - icon_state = "qm" - toysay = "Hail Cargonia!" - -/obj/item/toy/figure/janitor - name = "Janitor action figure" - desc = "A \"Space Life\" brand Janitor action figure." - icon_state = "janitor" - toysay = "Look at the signs, you idiot." - -/obj/item/toy/figure/agent - name = "Internal Affairs Agent action figure" - desc = "A \"Space Life\" brand Internal Affairs Agent action figure." - icon_state = "agent" - toysay = "Standard Operating Procedure says they're guilty! Hacking is proof they're an Enemy of the Corporation!" - -/obj/item/toy/figure/librarian - name = "Librarian action figure" - desc = "A \"Space Life\" brand Librarian action figure." - icon_state = "librarian" - toysay = "One day while..." - -/obj/item/toy/figure/md - name = "Medical Doctor action figure" - desc = "A \"Space Life\" brand Medical Doctor action figure." - icon_state = "md" - toysay = "The patient is already dead!" - -/obj/item/toy/figure/mime - name = "Mime action figure" - desc = "A \"Space Life\" brand Mime action figure." - icon_state = "mime" - toysay = "..." - -/obj/item/toy/figure/miner - name = "Shaft Miner action figure" - desc = "A \"Space Life\" brand Shaft Miner action figure." - icon_state = "miner" - toysay = "Oh god, it's eating my intestines!" - -/obj/item/toy/figure/ninja - name = "Space Ninja action figure" - desc = "A \"Space Life\" brand Space Ninja action figure." - icon_state = "ninja" - toysay = "Oh god! Stop shooting, I'm friendly!" - -/obj/item/toy/figure/wizard - name = "Wizard action figure" - desc = "A \"Space Life\" brand Wizard action figure." - icon_state = "wizard" - toysay = "Ei Nath!" - -/obj/item/toy/figure/rd - name = "Research Director action figure" - desc = "A \"Space Life\" brand Research Director action figure." - icon_state = "rd" - toysay = "Blowing all of the borgs!" - -/obj/item/toy/figure/roboticist - name = "Roboticist action figure" - desc = "A \"Space Life\" brand Roboticist action figure." - icon_state = "roboticist" - toysay = "He asked to be borged!" - -/obj/item/toy/figure/scientist - name = "Scientist action figure" - desc = "A \"Space Life\" brand Scientist action figure." - icon_state = "scientist" - toysay = "Someone else must have made those bombs!" - -/obj/item/toy/figure/syndie - name = "Doom Operative action figure" - desc = "A \"Space Life\" brand Doom Operative action figure." - icon_state = "syndie" - toysay = "Get that fucking disk!" - -/obj/item/toy/figure/secofficer - name = "Security Officer action figure" - desc = "A \"Space Life\" brand Security Officer action figure." - icon_state = "secofficer" - toysay = "I am the law!" - -/obj/item/toy/figure/virologist - name = "Virologist action figure" - desc = "A \"Space Life\" brand Virologist action figure." - icon_state = "virologist" - toysay = "The cure is potassium!" - -/obj/item/toy/figure/warden - name = "Warden action figure" - desc = "A \"Space Life\" brand Warden action figure." - icon_state = "warden" - toysay = "Execute him for breaking in!" - -/obj/item/toy/figure/psychologist - name = "Psychologist action figure" - desc = "A \"Space Life\" brand Psychologist action figure." - icon_state = "psychologist" - toysay = "The analyzer says you're fine!" - -/obj/item/toy/figure/paramedic - name = "Paramedic action figure" - desc = "A \"Space Life\" brand Paramedic action figure." - icon_state = "paramedic" - toysay = "WHERE ARE YOU??" - -/obj/item/toy/figure/ert - name = "Emergency Response Team Commander action figure" - desc = "A \"Space Life\" brand Emergency Response Team Commander action figure." - icon_state = "ert" - toysay = "We're probably the good guys!" - -/* - * Plushies - */ - -/* - * Carp plushie - */ - -/obj/item/toy/plushie/carp - name = "space carp plushie" - desc = "An adorable stuffed toy that resembles a space carp." - icon = 'icons/obj/toy.dmi' - icon_state = "basecarp" - attack_verb = list("bitten", "eaten", "fin slapped") - var/bitesound = 'sound/weapons/bite.ogg' - -// Attack mob -/obj/item/toy/plushie/carp/attack(mob/M as mob, mob/user as mob) - playsound(src, bitesound, 20, 1) // Play bite sound in local area - return ..() - -// Attack self -/obj/item/toy/plushie/carp/attack_self(mob/user as mob) - playsound(src, bitesound, 20, 1) - return ..() - - -/obj/random/carp_plushie - name = "Random Carp Plushie" - desc = "This is a random plushie" - icon = 'icons/obj/toy.dmi' - icon_state = "basecarp" - -/obj/random/carp_plushie/item_to_spawn() - return pick(typesof(/obj/item/toy/plushie/carp)) //can pick any carp plushie, even the original. - -/obj/item/toy/plushie/carp/ice - name = "ice carp plushie" - icon_state = "icecarp" - -/obj/item/toy/plushie/carp/silent - name = "monochrome carp plushie" - icon_state = "silentcarp" - -/obj/item/toy/plushie/carp/electric - name = "electric carp plushie" - icon_state = "electriccarp" - -/obj/item/toy/plushie/carp/gold - name = "golden carp plushie" - icon_state = "goldcarp" - -/obj/item/toy/plushie/carp/toxin - name = "toxic carp plushie" - icon_state = "toxincarp" - -/obj/item/toy/plushie/carp/dragon - name = "dragon carp plushie" - icon_state = "dragoncarp" - -/obj/item/toy/plushie/carp/pink - name = "pink carp plushie" - icon_state = "pinkcarp" - -/obj/item/toy/plushie/carp/candy - name = "candy carp plushie" - icon_state = "candycarp" - -/obj/item/toy/plushie/carp/nebula - name = "nebula carp plushie" - icon_state = "nebulacarp" - -/obj/item/toy/plushie/carp/void - name = "void carp plushie" - icon_state = "voidcarp" - -//Large plushies. -/obj/structure/plushie - name = "generic plush" - desc = "A very generic plushie. It seems to not want to exist." - icon = 'icons/obj/toy.dmi' - icon_state = "ianplushie" - anchored = 0 - density = 1 - var/phrase = "I don't want to exist anymore!" - var/searching = FALSE - var/opened = FALSE // has this been slit open? this will allow you to store an object in a plushie. - var/obj/item/stored_item // Note: Stored items can't be bigger than the plushie itself. - -/obj/structure/plushie/examine(mob/user) - . = ..() - if(opened) - . += "You notice an incision has been made on [src]." - if(in_range(user, src) && stored_item) - . += "You can see something in there..." - -/obj/structure/plushie/attack_hand(mob/user) - user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) - - if(stored_item && opened && !searching) - searching = TRUE - if(do_after(user, 10)) - to_chat(user, "You find \icon[stored_item] [stored_item] in [src]!") - stored_item.forceMove(get_turf(src)) - stored_item = null - searching = FALSE - return - else - searching = FALSE - - if(user.a_intent == I_HELP) - user.visible_message("\The [user] hugs [src]!","You hug [src]!") - else if (user.a_intent == I_HURT) - user.visible_message("\The [user] punches [src]!","You punch [src]!") - else if (user.a_intent == I_GRAB) - user.visible_message("\The [user] attempts to strangle [src]!","You attempt to strangle [src]!") - else - user.visible_message("\The [user] pokes the [src].","You poke the [src].") - visible_message("[src] says, \"[phrase]\"") - - -/obj/structure/plushie/attackby(obj/item/I as obj, mob/user as mob) - if(istype(I, /obj/item/device/threadneedle) && opened) - to_chat(user, "You sew the hole in [src].") - opened = FALSE - return - - if(is_sharp(I) && !opened) - to_chat(user, "You open a small incision in [src]. You can place tiny items inside.") - opened = TRUE - return - - if(opened) - if(stored_item) - to_chat(user, "There is already something in here.") - return - - if(!(I.w_class > w_class)) - to_chat(user, "You place [I] inside [src].") - user.drop_from_inventory(I, src) - I.forceMove(src) - stored_item = I - return - else - to_chat(user, "You open a small incision in [src]. You can place tiny items inside.") - - - ..() - -/obj/structure/plushie/ian - name = "plush corgi" - desc = "A plushie of an adorable corgi! Don't you just want to hug it and squeeze it and call it \"Ian\"?" - icon_state = "ianplushie" - phrase = "Arf!" - -/obj/structure/plushie/drone - name = "plush drone" - desc = "A plushie of a happy drone! It appears to be smiling." - icon_state = "droneplushie" - phrase = "Beep boop!" - -/obj/structure/plushie/carp - name = "plush carp" - desc = "A plushie of an elated carp! Straight from the wilds of the Vir frontier, now right here in your hands." - icon_state = "carpplushie" - phrase = "Glorf!" - -/obj/structure/plushie/beepsky - name = "plush Officer Sweepsky" - desc = "A plushie of a popular industrious cleaning robot! If it could feel emotions, it would love you." - icon_state = "beepskyplushie" - phrase = "Ping!" - -//Small plushies. -/obj/item/toy/plushie - name = "generic small plush" - desc = "A small toy plushie. It's very cute." - icon = 'icons/obj/toy.dmi' - icon_state = "nymphplushie" - drop_sound = 'sound/items/drop/plushie.ogg' - w_class = ITEMSIZE_TINY - var/last_message = 0 - var/pokephrase = "Uww!" - var/searching = FALSE - var/opened = FALSE // has this been slit open? this will allow you to store an object in a plushie. - var/obj/item/stored_item // Note: Stored items can't be bigger than the plushie itself. - - -/obj/item/toy/plushie/examine(mob/user) - . = ..() - if(opened) - . += "You notice an incision has been made on [src]." - if(in_range(user, src) && stored_item) - . += "You can see something in there..." - -/obj/item/toy/plushie/attack_self(mob/user as mob) - if(stored_item && opened && !searching) - searching = TRUE - if(do_after(user, 10)) - to_chat(user, "You find \icon[stored_item] [stored_item] in [src]!") - stored_item.forceMove(get_turf(src)) - stored_item = null - searching = FALSE - return - else - searching = FALSE - - if(world.time - last_message <= 1 SECOND) - return - if(user.a_intent == I_HELP) - user.visible_message("\The [user] hugs [src]!","You hug [src]!") - else if (user.a_intent == I_HURT) - user.visible_message("\The [user] punches [src]!","You punch [src]!") - else if (user.a_intent == I_GRAB) - user.visible_message("\The [user] attempts to strangle [src]!","You attempt to strangle [src]!") - else - user.visible_message("\The [user] pokes [src].","You poke [src].") - playsound(src, 'sound/items/drop/plushie.ogg', 25, 0) - visible_message("[src] says, \"[pokephrase]\"") - last_message = world.time - -/obj/item/toy/plushie/verb/rename_plushie() - set name = "Name Plushie" - set category = "Object" - set desc = "Give your plushie a cute name!" - var/mob/M = usr - if(!M.mind) - return 0 - - var/input = sanitizeSafe(input("What do you want to name the plushie?", ,""), MAX_NAME_LEN) - - if(src && input && !M.stat && in_range(M,src)) - name = input - to_chat(M, "You name the plushie [input], giving it a hug for good luck.") - return 1 - -/obj/item/toy/plushie/attackby(obj/item/I as obj, mob/user as mob) - if(istype(I, /obj/item/toy/plushie) || istype(I, /obj/item/organ/external/head)) - user.visible_message("[user] makes \the [I] kiss \the [src]!.", \ - "You make \the [I] kiss \the [src]!.") - return - - - if(istype(I, /obj/item/device/threadneedle) && opened) - to_chat(user, "You sew the hole underneath [src].") - opened = FALSE - return - - if(is_sharp(I) && !opened) - to_chat(user, "You open a small incision in [src]. You can place tiny items inside.") - opened = TRUE - return - - if( (!(I.w_class > w_class)) && opened) - if(stored_item) - to_chat(user, "There is already something in here.") - return - - to_chat(user, "You place [I] inside [src].") - user.drop_from_inventory(I, src) - I.forceMove(src) - stored_item = I - to_chat(user, "You placed [I] into [src].") - return - - return ..() - -/obj/item/toy/plushie/nymph - name = "diona nymph plush" - desc = "A plushie of an adorable diona nymph! While its level of self-awareness is still being debated, its level of cuteness is not." - icon_state = "nymphplushie" - pokephrase = "Chirp!" - -/obj/item/toy/plushie/teshari - name = "teshari plush" - desc = "This is a plush teshari. Very soft, with a pompom on the tail. The toy is made well, as if alive. Looks like she is sleeping. Shhh!" - icon_state = "teshariplushie" - pokephrase = "Rya!" - -/obj/item/toy/plushie/mouse - name = "mouse plush" - desc = "A plushie of a delightful mouse! What was once considered a vile rodent is now your very best friend." - icon_state = "mouseplushie" //TFF 12/11/19 - updated icon to show a sprite that doesn't replicate a dead mouse. Heck you for that! >:C - pokephrase = "Squeak!" - -/obj/item/toy/plushie/kitten - name = "kitten plush" - desc = "A plushie of a cute kitten! Watch as it purrs its way right into your heart." - icon_state = "kittenplushie" - pokephrase = "Mrow!" - -/obj/item/toy/plushie/lizard - name = "lizard plush" - desc = "A plushie of a scaly lizard! Very controversial, after being accused as \"racist\" by some Unathi." - icon_state = "lizardplushie" - pokephrase = "Hiss!" - -/obj/item/toy/plushie/spider - name = "spider plush" - desc = "A plushie of a fuzzy spider! It has eight legs - all the better to hug you with." - icon_state = "spiderplushie" - pokephrase = "Sksksk!" - -/obj/item/toy/plushie/farwa - name = "farwa plush" - desc = "A farwa plush doll. It's soft and comforting!" - icon_state = "farwaplushie" - pokephrase = "Squaw!" - -/obj/item/toy/plushie/corgi - name = "corgi plushie" - icon_state = "corgi" - pokephrase = "Woof!" - -/obj/item/toy/plushie/girly_corgi - name = "corgi plushie" - icon_state = "girlycorgi" - pokephrase = "Arf!" - -/obj/item/toy/plushie/robo_corgi - name = "borgi plushie" - icon_state = "robotcorgi" - pokephrase = "Bark." - -/obj/item/toy/plushie/octopus - name = "octopus plushie" - icon_state = "loveable" - pokephrase = "Squish!" - -/obj/item/toy/plushie/face_hugger - name = "facehugger plushie" - icon_state = "huggable" - pokephrase = "Hug!" - -//foxes are basically the best - -/obj/item/toy/plushie/red_fox - name = "red fox plushie" - icon_state = "redfox" - pokephrase = "Gecker!" - -/obj/item/toy/plushie/black_fox - name = "black fox plushie" - icon_state = "blackfox" - pokephrase = "Ack!" - -/obj/item/toy/plushie/marble_fox - name = "marble fox plushie" - icon_state = "marblefox" - pokephrase = "Awoo!" - -/obj/item/toy/plushie/blue_fox - name = "blue fox plushie" - icon_state = "bluefox" - pokephrase = "Yoww!" - -/obj/item/toy/plushie/orange_fox - name = "orange fox plushie" - icon_state = "orangefox" - pokephrase = "Yagh!" - -/obj/item/toy/plushie/coffee_fox - name = "coffee fox plushie" - icon_state = "coffeefox" - pokephrase = "Gerr!" - -/obj/item/toy/plushie/pink_fox - name = "pink fox plushie" - icon_state = "pinkfox" - pokephrase = "Yack!" - -/obj/item/toy/plushie/purple_fox - name = "purple fox plushie" - icon_state = "purplefox" - pokephrase = "Whine!" - -/obj/item/toy/plushie/crimson_fox - name = "crimson fox plushie" - icon_state = "crimsonfox" - pokephrase = "Auuu!" - -/obj/item/toy/plushie/deer - name = "deer plushie" - icon_state = "deer" - pokephrase = "Bleat!" - -/obj/item/toy/plushie/black_cat - name = "black cat plushie" - icon_state = "blackcat" - pokephrase = "Mlem!" - -/obj/item/toy/plushie/grey_cat - name = "grey cat plushie" - icon_state = "greycat" - pokephrase = "Mraw!" - -/obj/item/toy/plushie/white_cat - name = "white cat plushie" - icon_state = "whitecat" - pokephrase = "Mew!" - -/obj/item/toy/plushie/orange_cat - name = "orange cat plushie" - icon_state = "orangecat" - pokephrase = "Meow!" - -/obj/item/toy/plushie/siamese_cat - name = "siamese cat plushie" - icon_state = "siamesecat" - pokephrase = "Mrew?" - -/obj/item/toy/plushie/tabby_cat - name = "tabby cat plushie" - icon_state = "tabbycat" - pokephrase = "Purr!" - -/obj/item/toy/plushie/tuxedo_cat - name = "tuxedo cat plushie" - icon_state = "tuxedocat" - pokephrase = "Mrowww!!" - -// nah, squids are better than foxes :> - -/obj/item/toy/plushie/squid/green - name = "green squid plushie" - desc = "A small, cute and loveable squid friend. This one is green." - icon = 'icons/obj/toy.dmi' - icon_state = "greensquid" - slot_flags = SLOT_HEAD - pokephrase = "Squrr!" - -/obj/item/toy/plushie/squid/mint - name = "mint squid plushie" - desc = "A small, cute and loveable squid friend. This one is mint coloured." - icon = 'icons/obj/toy.dmi' - icon_state = "mintsquid" - slot_flags = SLOT_HEAD - pokephrase = "Blurble!" - -/obj/item/toy/plushie/squid/blue - name = "blue squid plushie" - desc = "A small, cute and loveable squid friend. This one is blue." - icon = 'icons/obj/toy.dmi' - icon_state = "bluesquid" - slot_flags = SLOT_HEAD - pokephrase = "Blob!" - -/obj/item/toy/plushie/squid/orange - name = "orange squid plushie" - desc = "A small, cute and loveable squid friend. This one is orange." - icon = 'icons/obj/toy.dmi' - icon_state = "orangesquid" - slot_flags = SLOT_HEAD - pokephrase = "Squash!" - -/obj/item/toy/plushie/squid/yellow - name = "yellow squid plushie" - desc = "A small, cute and loveable squid friend. This one is yellow." - icon = 'icons/obj/toy.dmi' - icon_state = "yellowsquid" - slot_flags = SLOT_HEAD - pokephrase = "Glorble!" - -/obj/item/toy/plushie/squid/pink - name = "pink squid plushie" - desc = "A small, cute and loveable squid friend. This one is pink." - icon = 'icons/obj/toy.dmi' - icon_state = "pinksquid" - slot_flags = SLOT_HEAD - pokephrase = "Wobble!" - -/obj/item/toy/plushie/therapy/red - name = "red therapy doll" - desc = "A toy for therapeutic and recreational purposes. This one is red." - icon = 'icons/obj/toy.dmi' - icon_state = "therapyred" - item_state = "egg4" // It's the red egg in items_left/righthand - -/obj/item/toy/plushie/therapy/purple - name = "purple therapy doll" - desc = "A toy for therapeutic and recreational purposes. This one is purple." - icon = 'icons/obj/toy.dmi' - icon_state = "therapypurple" - item_state = "egg1" // It's the magenta egg in items_left/righthand - -/obj/item/toy/plushie/therapy/blue - name = "blue therapy doll" - desc = "A toy for therapeutic and recreational purposes. This one is blue." - icon = 'icons/obj/toy.dmi' - icon_state = "therapyblue" - item_state = "egg2" // It's the blue egg in items_left/righthand - -/obj/item/toy/plushie/therapy/yellow - name = "yellow therapy doll" - desc = "A toy for therapeutic and recreational purposes. This one is yellow." - icon = 'icons/obj/toy.dmi' - icon_state = "therapyyellow" - item_state = "egg5" // It's the yellow egg in items_left/righthand - -/obj/item/toy/plushie/therapy/orange - name = "orange therapy doll" - desc = "A toy for therapeutic and recreational purposes. This one is orange." - icon = 'icons/obj/toy.dmi' - icon_state = "therapyorange" - item_state = "egg4" // It's the red one again, lacking an orange item_state and making a new one is pointless - -/obj/item/toy/plushie/therapy/green - name = "green therapy doll" - desc = "A toy for therapeutic and recreational purposes. This one is green." - icon = 'icons/obj/toy.dmi' - icon_state = "therapygreen" - item_state = "egg3" // It's the green egg in items_left/righthand - - -//Toy cult sword -/obj/item/toy/cultsword - name = "foam sword" - desc = "An arcane weapon (made of foam) wielded by the followers of the hit Saturday morning cartoon \"King Nursee and the Acolytes of Heroism\"." - icon = 'icons/obj/weapons.dmi' - icon_state = "cultblade" - item_icons = list( - slot_l_hand_str = 'icons/mob/items/lefthand_melee.dmi', - slot_r_hand_str = 'icons/mob/items/righthand_melee.dmi', - ) - w_class = ITEMSIZE_LARGE - attack_verb = list("attacked", "slashed", "stabbed", "poked") - -//Flowers fake & real - -/obj/item/toy/bouquet - name = "bouquet" - desc = "A lovely bouquet of flowers. Smells nice!" - icon = 'icons/obj/items.dmi' - icon_state = "bouquet" - w_class = ITEMSIZE_SMALL - -/obj/item/toy/bouquet/fake - name = "plastic bouquet" - desc = "A cheap plastic bouquet of flowers. Smells like cheap, toxic plastic." - -/obj/item/toy/stickhorse - name = "stick horse" - desc = "A pretend horse on a stick for any aspiring little cowboy to ride." - icon = 'icons/obj/toy.dmi' - icon_state = "stickhorse" - w_class = ITEMSIZE_LARGE - -////////////////////////////////////////////////////// -// Magic 8-Ball / Conch // -////////////////////////////////////////////////////// - -/obj/item/toy/eight_ball - name = "\improper Magic 8-Ball" - desc = "Mystical! Magical! Ages 8+!" - icon = 'icons/obj/toy.dmi' - icon_state = "eight-ball" - var/use_action = "shakes the ball" - var/cooldown = 0 - var/list/possible_answers = list("Definitely.", "All signs point to yes.", "Most likely.", "Yes.", "Ask again later.", "Better not tell you now.", "Future unclear.", "Maybe.", "Doubtful.", "No.", "Don't count on it.", "Never.") - -/obj/item/toy/eight_ball/attack_self(mob/user as mob) - if(!cooldown) - var/answer = pick(possible_answers) - user.visible_message("[user] focuses on their question and [use_action]...") - user.visible_message("The [src] says \"[answer]\"") - spawn(30) - cooldown = 0 - return - -/obj/item/toy/eight_ball/conch - name = "Magic Conch shell" - desc = "All hail the Magic Conch!" - icon_state = "conch" - use_action = "pulls the string" - possible_answers = list("Yes.", "No.", "Try asking again.", "Nothing.", "I don't think so.", "Neither.", "Maybe someday.") - -// DND Character minis. Use the naming convention (type)character for the icon states. -/obj/item/toy/character - icon = 'icons/obj/toy.dmi' - w_class = ITEMSIZE_SMALL - pixel_z = 5 - -/obj/item/toy/character/alien - name = "xenomorph xiniature" - desc = "A miniature xenomorph. Scary!" - icon_state = "aliencharacter" -/obj/item/toy/character/cleric - name = "cleric miniature" - desc = "A wee little cleric, with his wee little staff." - icon_state = "clericcharacter" -/obj/item/toy/character/warrior - name = "warrior miniature" - desc = "That sword would make a decent toothpick." - icon_state = "warriorcharacter" -/obj/item/toy/character/thief - name = "thief miniature" - desc = "Hey, where did my wallet go!?" - icon_state = "thiefcharacter" -/obj/item/toy/character/wizard - name = "wizard miniature" - desc = "MAGIC!" - icon_state = "wizardcharacter" -/obj/item/toy/character/voidone - name = "void one miniature" - desc = "The dark lord has risen!" - icon_state = "darkmastercharacter" -/obj/item/toy/character/lich - name = "lich miniature" - desc = "Murderboner extraordinaire." - icon_state = "lichcharacter" -/obj/item/weapon/storage/box/characters - name = "box of miniatures" - desc = "The nerd's best friends." - icon_state = "box" -/obj/item/weapon/storage/box/characters/starts_with = list( -// /obj/item/toy/character/alien, - /obj/item/toy/character/cleric, - /obj/item/toy/character/warrior, - /obj/item/toy/character/thief, - /obj/item/toy/character/wizard, - /obj/item/toy/character/voidone, - /obj/item/toy/character/lich - ) - -/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. - icon = 'icons/obj/toy.dmi' - 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() - to_chat(user, "You press the button on [src].") - playsound(src, 'sound/machines/click.ogg', 20, 1) - visible_message("[message]") - cooldown = 1 - spawn(30) cooldown = 0 - return - ..() -*/ -/obj/item/toy/owl - name = "owl action figure" - desc = "An action figure modeled after 'The Owl', defender of justice." - icon = 'icons/obj/toy.dmi' - icon_state = "owlprize" - w_class = ITEMSIZE_SMALL - var/cooldown = 0 - -/obj/item/toy/owl/attack_self(mob/user) - if(!cooldown) //for the sanity of everyone - var/message = pick("You won't get away this time, Griffin!", "Stop right there, criminal!", "Hoot! Hoot!", "I am the night!") - to_chat(user, "You pull the string on the [src].") - //playsound(src, 'sound/misc/hoot.ogg', 25, 1) - visible_message("[message]") - cooldown = 1 - spawn(30) cooldown = 0 - return - ..() - -/obj/item/toy/griffin - name = "griffin action figure" - desc = "An action figure modeled after 'The Griffin', criminal mastermind." - icon = 'icons/obj/toy.dmi' - icon_state = "griffinprize" - w_class = ITEMSIZE_SMALL - var/cooldown = 0 - -/obj/item/toy/griffin/attack_self(mob/user) - if(!cooldown) //for the sanity of everyone - var/message = pick("You can't stop me, Owl!", "My plan is flawless! The vault is mine!", "Caaaawwww!", "You will never catch me!") - to_chat(user, "You pull the string on the [src].") - //playsound(src, 'sound/misc/caw.ogg', 25, 1) - visible_message("[message]") - cooldown = 1 - spawn(30) cooldown = 0 - return - ..() - -/* NYET. -/obj/item/weapon/toddler - icon_state = "toddler" - name = "toddler" - desc = "This baby looks almost real. Wait, did it just burp?" - force = 5 - w_class = ITEMSIZE_LARGE - slot_flags = SLOT_BACK -*/ - -//This should really be somewhere else but I don't know where. w/e - -/obj/item/weapon/inflatable_duck - name = "inflatable duck" - desc = "No bother to sink or swim when you can just float!" - icon_state = "inflatable" - icon = 'icons/obj/clothing/belts.dmi' - slot_flags = SLOT_BELT - drop_sound = 'sound/items/drop/rubber.ogg' - -/obj/item/toy/xmastree - name = "Miniature Christmas tree" - desc = "Tiny cute Christmas tree." - icon = 'icons/obj/toy.dmi' - icon_state = "tinyxmastree" - w_class = ITEMSIZE_TINY - force = 1 - throwforce = 1 - drop_sound = 'sound/items/drop/box.ogg' - -////////////////////////////////////////////////////// -// Chess Pieces // -////////////////////////////////////////////////////// - -/obj/item/toy/chess - name = "chess piece" - desc = "This should never display." - icon = 'icons/obj/chess.dmi' - w_class = ITEMSIZE_SMALL - force = 1 - throwforce = 1 - drop_sound = 'sound/items/drop/glass.ogg' - -/obj/item/toy/chess/pawn_white - name = "blue pawn" - desc = "A large pawn piece for playing chess. It's made of a blue-colored glass." - description_info = "Pawns can move forward one square, if that square is unoccupied. If the pawn has not yet moved, it has the option of moving two squares forward provided both squares in front of the pawn are unoccupied. A pawn cannot move backward. They can only capture an enemy piece on either of the two tiles diagonally in front of them, but not the tile directly in front of them." - icon_state = "w-pawn" -/obj/item/toy/chess/pawn_black - name = "purple pawn" - desc = "A large pawn piece for playing chess. It's made of a purple-colored glass." - description_info = "Pawns can move forward one square, if that square is unoccupied. If the pawn has not yet moved, it has the option of moving two squares forward provided both squares in front of the pawn are unoccupied. A pawn cannot move backward. They can only capture an enemy piece on either of the two tiles diagonally in front of them, but not the tile directly in front of them." - icon_state = "b-pawn" -/obj/item/toy/chess/rook_white - name = "blue rook" - desc = "A large rook piece for playing chess. It's made of a blue-colored glass." - description_info = "The Rook can move any number of vacant squares vertically or horizontally." - icon_state = "w-rook" -/obj/item/toy/chess/rook_black - name = "purple rook" - desc = "A large rook piece for playing chess. It's made of a purple-colored glass." - description_info = "The Rook can move any number of vacant squares vertically or horizontally." - icon_state = "b-rook" -/obj/item/toy/chess/knight_white - name = "blue knight" - desc = "A large knight piece for playing chess. It's made of a blue-colored glass. Sadly, you can't ride it." - description_info = "The Knight can either move two squares horizontally and one square vertically or two squares vertically and one square horizontally. The knight's movement can also be viewed as an 'L' laid out at any horizontal or vertical angle." - icon_state = "w-knight" -/obj/item/toy/chess/knight_black - name = "purple knight" - desc = "A large knight piece for playing chess. It's made of a purple-colored glass. 'Just a flesh wound.'" - description_info = "The Knight can either move two squares horizontally and one square vertically or two squares vertically and one square horizontally. The knight's movement can also be viewed as an 'L' laid out at any horizontal or vertical angle." - icon_state = "b-knight" -/obj/item/toy/chess/bishop_white - name = "blue bishop" - desc = "A large bishop piece for playing chess. It's made of a blue-colored glass." - description_info = "The Bishop can move any number of vacant squares in any diagonal direction." - icon_state = "w-bishop" -/obj/item/toy/chess/bishop_black - name = "purple bishop" - desc = "A large bishop piece for playing chess. It's made of a purple-colored glass." - description_info = "The Bishop can move any number of vacant squares in any diagonal direction." - icon_state = "b-bishop" -/obj/item/toy/chess/queen_white - name = "blue queen" - desc = "A large queen piece for playing chess. It's made of a blue-colored glass." - description_info = "The Queen can move any number of vacant squares diagonally, horizontally, or vertically." - icon_state = "w-queen" -/obj/item/toy/chess/queen_black - name = "purple queen" - desc = "A large queen piece for playing chess. It's made of a purple-colored glass." - description_info = "The Queen can move any number of vacant squares diagonally, horizontally, or vertically." - icon_state = "b-queen" -/obj/item/toy/chess/king_white - name = "blue king" - desc = "A large king piece for playing chess. It's made of a blue-colored glass." - description_info = "The King can move exactly one square horizontally, vertically, or diagonally. If your opponent captures this piece, you lose." - icon_state = "w-king" -/obj/item/toy/chess/king_black - name = "purple king" - desc = "A large king piece for playing chess. It's made of a purple-colored glass." - description_info = "The King can move exactly one square horizontally, vertically, or diagonally. If your opponent captures this piece, you lose." +/* Toys! + * Contains: + * Balloons + * Fake telebeacon + * Fake singularity + * Toy gun + * Toy crossbow + * Toy swords + * Toy bosun's whistle + * Snap pops + * Water flower + * Therapy dolls + * Toddler doll + * Inflatable duck + * Action figures + * Plushies + * Toy cult sword + * Bouquets + Stick Horse + */ + + +/obj/item/toy + throwforce = 0 + throw_speed = 4 + throw_range = 20 + force = 0 + drop_sound = 'sound/items/drop/gloves.ogg' + + +/* + * Balloons + */ +/obj/item/toy/balloon + name = "water balloon" + desc = "A translucent balloon. There's nothing in it." + icon = 'icons/obj/toy.dmi' + icon_state = "waterballoon-e" + drop_sound = 'sound/items/drop/rubber.ogg' + +/obj/item/toy/balloon/New() + var/datum/reagents/R = new/datum/reagents(10) + reagents = R + R.my_atom = src + +/obj/item/toy/balloon/attack(mob/living/carbon/human/M as mob, mob/user as mob) + return + +/obj/item/toy/balloon/afterattack(atom/A as mob|obj, mob/user as mob, proximity) + if(!proximity) return + if (istype(A, /obj/structure/reagent_dispensers/watertank) && get_dist(src,A) <= 1) + A.reagents.trans_to_obj(src, 10) + to_chat(user, "You fill the balloon with the contents of [A].") + src.desc = "A translucent balloon with some form of liquid sloshing around in it." + src.update_icon() + return + +/obj/item/toy/balloon/attackby(obj/O as obj, mob/user as mob) + if(istype(O, /obj/item/weapon/reagent_containers/glass)) + if(O.reagents) + if(O.reagents.total_volume < 1) + to_chat(user, "The [O] is empty.") + else if(O.reagents.total_volume >= 1) + if(O.reagents.has_reagent("pacid", 1)) + to_chat(user, "The acid chews through the balloon!") + O.reagents.splash(user, reagents.total_volume) + qdel(src) + else + src.desc = "A translucent balloon with some form of liquid sloshing around in it." + to_chat(user, "You fill the balloon with the contents of [O].") + O.reagents.trans_to_obj(src, 10) + src.update_icon() + return + +/obj/item/toy/balloon/throw_impact(atom/hit_atom) + if(src.reagents.total_volume >= 1) + src.visible_message("\The [src] bursts!","You hear a pop and a splash.") + src.reagents.touch_turf(get_turf(hit_atom)) + for(var/atom/A in get_turf(hit_atom)) + src.reagents.touch(A) + src.icon_state = "burst" + spawn(5) + if(src) + qdel(src) + return + +/obj/item/toy/balloon/update_icon() + if(src.reagents.total_volume >= 1) + icon_state = "waterballoon" + else + icon_state = "waterballoon-e" + +/obj/item/toy/syndicateballoon + name = "criminal balloon" + desc = "There is a tag on the back that reads \"FUK NT!11!\"." + throwforce = 0 + throw_speed = 4 + throw_range = 20 + force = 0 + icon = 'icons/obj/weapons.dmi' + icon_state = "syndballoon" + w_class = ITEMSIZE_LARGE + drop_sound = 'sound/items/drop/rubber.ogg' + +/obj/item/toy/nanotrasenballoon + name = "criminal balloon" + desc = "Across the balloon the following is printed: \"Man, I love NanoTrasen soooo much. I use only NT products. You have NO idea.\"" + throwforce = 0 + throw_speed = 4 + throw_range = 20 + force = 0 + icon = 'icons/obj/weapons.dmi' + icon_state = "ntballoon" + w_class = ITEMSIZE_LARGE + drop_sound = 'sound/items/drop/rubber.ogg' + +/* + * Fake telebeacon + */ +/obj/item/toy/blink + name = "electronic blink toy game" + desc = "Blink. Blink. Blink. Ages 8 and up." + icon = 'icons/obj/radio.dmi' + icon_state = "beacon" + item_state = "signaler" + +/* + * Fake singularity + */ +/obj/item/toy/spinningtoy + name = "gravitational singularity" + desc = "\"Singulo\" brand spinning toy." + icon = 'icons/obj/singularity.dmi' + icon_state = "singularity_s1" + +/* + * Toy crossbow + */ + +/obj/item/toy/crossbow + name = "foam dart crossbow" + desc = "A weapon favored by many overactive children. Ages 8 and up." + icon = 'icons/obj/gun.dmi' + icon_state = "crossbow" + item_icons = list( + icon_l_hand = 'icons/mob/items/lefthand_guns.dmi', + icon_r_hand = 'icons/mob/items/righthand_guns.dmi', + ) + slot_flags = SLOT_HOLSTER + w_class = ITEMSIZE_SMALL + attack_verb = list("attacked", "struck", "hit") + var/bullets = 5 + drop_sound = 'sound/items/drop/gun.ogg' + + examine(mob/user) + . = ..() + if(bullets && get_dist(user, src) <= 2) + . += "It is loaded with [bullets] foam darts!" + + attackby(obj/item/I as obj, mob/user as mob) + if(istype(I, /obj/item/toy/ammo/crossbow)) + if(bullets <= 4) + user.drop_item() + qdel(I) + bullets++ + to_chat(user, "You load the foam dart into the crossbow.") + else + to_chat(usr, "It's already fully loaded.") + + + afterattack(atom/target as mob|obj|turf|area, mob/user as mob, flag) + if(!isturf(target.loc) || target == user) return + if(flag) return + + if (locate (/obj/structure/table, src.loc)) + return + else if (bullets) + var/turf/trg = get_turf(target) + var/obj/effect/foam_dart_dummy/D = new/obj/effect/foam_dart_dummy(get_turf(src)) + bullets-- + D.icon_state = "foamdart" + D.name = "foam dart" + playsound(src, 'sound/items/syringeproj.ogg', 50, 1) + + for(var/i=0, i<6, i++) + if (D) + if(D.loc == trg) break + step_towards(D,trg) + + for(var/mob/living/M in D.loc) + if(!istype(M,/mob/living)) continue + if(M == user) continue + for(var/mob/O in viewers(world.view, D)) + O.show_message(text("\The [] was hit by the foam dart!", M), 1) + new /obj/item/toy/ammo/crossbow(M.loc) + qdel(D) + return + + for(var/atom/A in D.loc) + if(A == user) continue + if(A.density) + new /obj/item/toy/ammo/crossbow(A.loc) + qdel(D) + + sleep(1) + + spawn(10) + if(D) + new /obj/item/toy/ammo/crossbow(D.loc) + qdel(D) + + return + else if (bullets == 0) + user.Weaken(5) + for(var/mob/O in viewers(world.view, user)) + O.show_message(text("\The [] realized they were out of ammo and starting scrounging for some!", user), 1) + + + attack(mob/M as mob, mob/user as mob) + src.add_fingerprint(user) + +// ******* Check + + if (src.bullets > 0 && M.lying) + + for(var/mob/O in viewers(M, null)) + if(O.client) + O.show_message(text("\The [] casually lines up a shot with []'s head and pulls the trigger!", user, M), 1, "You hear the sound of foam against skull", 2) + O.show_message(text("\The [] was hit in the head by the foam dart!", M), 1) + + playsound(src, 'sound/items/syringeproj.ogg', 50, 1) + new /obj/item/toy/ammo/crossbow(M.loc) + src.bullets-- + else if (M.lying && src.bullets == 0) + for(var/mob/O in viewers(M, null)) + if (O.client) O.show_message(text("\The [] casually lines up a shot with []'s head, pulls the trigger, then realizes they are out of ammo and drops to the floor in search of some!", user, M), 1, "You hear someone fall", 2) + user.Weaken(5) + return + +/obj/item/toy/ammo/crossbow + name = "foam dart" + desc = "It's nerf or nothing! Ages 8 and up." + icon = 'icons/obj/toy.dmi' + icon_state = "foamdart" + w_class = ITEMSIZE_TINY + slot_flags = SLOT_EARS + drop_sound = 'sound/items/drop/food.ogg' + +/obj/effect/foam_dart_dummy + name = "" + desc = "" + icon = 'icons/obj/toy.dmi' + icon_state = "null" + anchored = 1 + density = 0 + +/* + * Toy swords + */ +/obj/item/toy/sword + name = "toy sword" + desc = "A cheap, plastic replica of an energy sword. Realistic sounds! Ages 8 and up." + icon = 'icons/obj/weapons.dmi' + icon_state = "esword" + drop_sound = 'sound/items/drop/gun.ogg' + var/lcolor + var/rainbow = FALSE + item_icons = list( + slot_l_hand_str = 'icons/mob/items/lefthand_melee.dmi', + slot_r_hand_str = 'icons/mob/items/righthand_melee.dmi', + ) + var/active = 0 + w_class = ITEMSIZE_SMALL + attack_verb = list("attacked", "struck", "hit") + + attack_self(mob/user as mob) + src.active = !( src.active ) + if (src.active) + to_chat(user, "You extend the plastic blade with a quick flick of your wrist.") + playsound(src, 'sound/weapons/saberon.ogg', 50, 1) + src.item_state = "[icon_state]_blade" + src.w_class = ITEMSIZE_LARGE + else + to_chat(user, "You push the plastic blade back down into the handle.") + playsound(src, 'sound/weapons/saberoff.ogg', 50, 1) + src.item_state = "[icon_state]" + src.w_class = ITEMSIZE_SMALL + update_icon() + src.add_fingerprint(user) + return + +/obj/item/toy/sword/update_icon() + . = ..() + var/mutable_appearance/blade_overlay = mutable_appearance(icon, "[icon_state]_blade") + blade_overlay.color = lcolor + cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other + if(active) + add_overlay(blade_overlay) + if(istype(usr,/mob/living/carbon/human)) + var/mob/living/carbon/human/H = usr + H.update_inv_l_hand() + H.update_inv_r_hand() + +/obj/item/toy/sword/AltClick(mob/living/user) + if(!in_range(src, user)) //Basic checks to prevent abuse + return + if(user.incapacitated() || !istype(user)) + to_chat(user, "You can't do that right now!") + return + + if(alert("Are you sure you want to recolor your blade?", "Confirm Recolor", "Yes", "No") == "Yes") + var/energy_color_input = input(usr,"","Choose Energy Color",lcolor) as color|null + if(energy_color_input) + lcolor = sanitize_hexcolor(energy_color_input) + update_icon() + +/obj/item/toy/sword/examine(mob/user) + . = ..() + . += "Alt-click to recolor it." + +/obj/item/toy/sword/attackby(obj/item/weapon/W, mob/user) + if(istype(W, /obj/item/device/multitool) && !active) + if(!rainbow) + rainbow = TRUE + else + rainbow = FALSE + to_chat(user, "You manipulate the color controller in [src].") + update_icon() +/obj/item/toy/katana + name = "replica katana" + desc = "Woefully underpowered in D20." + icon = 'icons/obj/weapons.dmi' + icon_state = "katana" + item_state = "katana" + item_icons = list( + slot_l_hand_str = 'icons/mob/items/lefthand_material.dmi', + slot_r_hand_str = 'icons/mob/items/righthand_material.dmi', + ) + slot_flags = SLOT_BELT | SLOT_BACK + force = 5 + throwforce = 5 + w_class = ITEMSIZE_NORMAL + attack_verb = list("attacked", "slashed", "stabbed", "sliced") + +/* + * Snap pops + */ +/obj/item/toy/snappop + name = "snap pop" + desc = "Wow!" + icon = 'icons/obj/toy.dmi' + icon_state = "snappop" + w_class = ITEMSIZE_TINY + drop_sound = null + + throw_impact(atom/hit_atom) + ..() + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread + s.set_up(3, 1, src) + s.start() + new /obj/effect/decal/cleanable/ash(src.loc) + src.visible_message("The [src.name] explodes!","You hear a snap!") + playsound(src, 'sound/effects/snap.ogg', 50, 1) + qdel(src) + +/obj/item/toy/snappop/Crossed(atom/movable/H as mob|obj) + if(H.is_incorporeal()) + return + if((ishuman(H))) //i guess carp and shit shouldn't set them off + var/mob/living/carbon/M = H + if(M.m_intent == "run") + to_chat(M, "You step on the snap pop!") + + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread + s.set_up(2, 0, src) + s.start() + new /obj/effect/decal/cleanable/ash(src.loc) + src.visible_message("The [src.name] explodes!","You hear a snap!") + playsound(src, 'sound/effects/snap.ogg', 50, 1) + qdel(src) + +/* + * Bosun's whistle + */ + +/obj/item/toy/bosunwhistle + name = "bosun's whistle" + desc = "A genuine Admiral Krush Bosun's Whistle, for the aspiring ship's captain! Suitable for ages 8 and up, do not swallow." + icon = 'icons/obj/toy.dmi' + icon_state = "bosunwhistle" + drop_sound = 'sound/items/drop/card.ogg' + var/cooldown = 0 + w_class = ITEMSIZE_TINY + slot_flags = SLOT_EARS | SLOT_HOLSTER + +/obj/item/toy/bosunwhistle/attack_self(mob/user as mob) + if(cooldown < world.time - 35) + to_chat(user, "You blow on [src], creating an ear-splitting noise!") + playsound(src, 'sound/misc/boatswain.ogg', 20, 1) + cooldown = world.time + +/* + * Action figures + */ +/obj/item/toy/figure + name = "Non-Specific Action Figure action figure" + desc = "A \"Space Life\" brand... wait, what the hell is this thing?" + icon = 'icons/obj/toy.dmi' + icon_state = "nuketoy" + var/cooldown = 0 + var/toysay = "What the fuck did you do?" + drop_sound = 'sound/items/drop/accessory.ogg' + +/obj/item/toy/figure/New() + ..() + desc = "A \"Space Life\" brand [name]" + +/obj/item/toy/figure/attack_self(mob/user as mob) + if(cooldown < world.time) + cooldown = (world.time + 30) //3 second cooldown + user.visible_message("The [src] says \"[toysay]\".") + playsound(src, 'sound/machines/click.ogg', 20, 1) + +/obj/item/toy/figure/cmo + name = "Chief Medical Officer action figure" + desc = "A \"Space Life\" brand Chief Medical Officer action figure." + icon_state = "cmo" + toysay = "Suit sensors!" + +/obj/item/toy/figure/assistant + name = "Assistant action figure" + desc = "A \"Space Life\" brand Assistant action figure." + icon_state = "assistant" + toysay = "Grey tide station wide!" + +/obj/item/toy/figure/atmos + name = "Atmospheric Technician action figure" + desc = "A \"Space Life\" brand Atmospheric Technician action figure." + icon_state = "atmos" + toysay = "Glory to Atmosia!" + +/obj/item/toy/figure/bartender + name = "Bartender action figure" + desc = "A \"Space Life\" brand Bartender action figure." + icon_state = "bartender" + toysay = "Where's my monkey?" + +/obj/item/toy/figure/borg + name = "Drone action figure" + desc = "A \"Space Life\" brand Drone action figure." + icon_state = "borg" + toysay = "I. LIVE. AGAIN." + +/obj/item/toy/figure/gardener + name = "Gardener action figure" + desc = "A \"Space Life\" brand Gardener action figure." + icon_state = "botanist" + toysay = "Dude, I see colors..." + +/obj/item/toy/figure/captain + name = "Colony Director action figure" + desc = "A \"Space Life\" brand Colony Director action figure." + icon_state = "captain" + toysay = "How do I open this display case?" + +/obj/item/toy/figure/cargotech + name = "Cargo Technician action figure" + desc = "A \"Space Life\" brand Cargo Technician action figure." + icon_state = "cargotech" + toysay = "For Cargonia!" + +/obj/item/toy/figure/ce + name = "Chief Engineer action figure" + desc = "A \"Space Life\" brand Chief Engineer action figure." + icon_state = "ce" + toysay = "Wire the solars!" + +/obj/item/toy/figure/chaplain + name = "Chaplain action figure" + desc = "A \"Space Life\" brand Chaplain action figure." + icon_state = "chaplain" + toysay = "Gods make me a killing machine please!" + +/obj/item/toy/figure/chef + name = "Chef action figure" + desc = "A \"Space Life\" brand Chef action figure." + icon_state = "chef" + toysay = "I swear it's not human meat." + +/obj/item/toy/figure/chemist + name = "Chemist action figure" + desc = "A \"Space Life\" brand Chemist action figure." + icon_state = "chemist" + toysay = "Get your pills!" + +/obj/item/toy/figure/clown + name = "Clown action figure" + desc = "A \"Space Life\" brand Clown action figure." + icon_state = "clown" + toysay = "Honk!" + +/obj/item/toy/figure/corgi + name = "Corgi action figure" + desc = "A \"Space Life\" brand Corgi action figure." + icon_state = "ian" + toysay = "Arf!" + +/obj/item/toy/figure/detective + name = "Detective action figure" + desc = "A \"Space Life\" brand Detective action figure." + icon_state = "detective" + toysay = "This airlock has grey jumpsuit and insulated glove fibers on it." + +/obj/item/toy/figure/dsquad + name = "Space Commando action figure" + desc = "A \"Space Life\" brand Space Commando action figure." + icon_state = "dsquad" + toysay = "Eliminate all threats!" + +/obj/item/toy/figure/engineer + name = "Engineer action figure" + desc = "A \"Space Life\" brand Engineer action figure." + icon_state = "engineer" + toysay = "Oh god, the engine is gonna go!" + +/obj/item/toy/figure/geneticist + name = "Geneticist action figure" + desc = "A \"Space Life\" brand Geneticist action figure, which was recently dicontinued." + icon_state = "geneticist" + toysay = "I'm not qualified for this job." + +/obj/item/toy/figure/hop + name = "Head of Personnel action figure" + desc = "A \"Space Life\" brand Head of Personnel action figure." + icon_state = "hop" + toysay = "Giving out all access!" + +/obj/item/toy/figure/hos + name = "Head of Security action figure" + desc = "A \"Space Life\" brand Head of Security action figure." + icon_state = "hos" + toysay = "I'm here to win, anything else is secondary." + +/obj/item/toy/figure/qm + name = "Quartermaster action figure" + desc = "A \"Space Life\" brand Quartermaster action figure." + icon_state = "qm" + toysay = "Hail Cargonia!" + +/obj/item/toy/figure/janitor + name = "Janitor action figure" + desc = "A \"Space Life\" brand Janitor action figure." + icon_state = "janitor" + toysay = "Look at the signs, you idiot." + +/obj/item/toy/figure/agent + name = "Internal Affairs Agent action figure" + desc = "A \"Space Life\" brand Internal Affairs Agent action figure." + icon_state = "agent" + toysay = "Standard Operating Procedure says they're guilty! Hacking is proof they're an Enemy of the Corporation!" + +/obj/item/toy/figure/librarian + name = "Librarian action figure" + desc = "A \"Space Life\" brand Librarian action figure." + icon_state = "librarian" + toysay = "One day while..." + +/obj/item/toy/figure/md + name = "Medical Doctor action figure" + desc = "A \"Space Life\" brand Medical Doctor action figure." + icon_state = "md" + toysay = "The patient is already dead!" + +/obj/item/toy/figure/mime + name = "Mime action figure" + desc = "A \"Space Life\" brand Mime action figure." + icon_state = "mime" + toysay = "..." + +/obj/item/toy/figure/miner + name = "Shaft Miner action figure" + desc = "A \"Space Life\" brand Shaft Miner action figure." + icon_state = "miner" + toysay = "Oh god, it's eating my intestines!" + +/obj/item/toy/figure/ninja + name = "Space Ninja action figure" + desc = "A \"Space Life\" brand Space Ninja action figure." + icon_state = "ninja" + toysay = "Oh god! Stop shooting, I'm friendly!" + +/obj/item/toy/figure/wizard + name = "Wizard action figure" + desc = "A \"Space Life\" brand Wizard action figure." + icon_state = "wizard" + toysay = "Ei Nath!" + +/obj/item/toy/figure/rd + name = "Research Director action figure" + desc = "A \"Space Life\" brand Research Director action figure." + icon_state = "rd" + toysay = "Blowing all of the borgs!" + +/obj/item/toy/figure/roboticist + name = "Roboticist action figure" + desc = "A \"Space Life\" brand Roboticist action figure." + icon_state = "roboticist" + toysay = "He asked to be borged!" + +/obj/item/toy/figure/scientist + name = "Scientist action figure" + desc = "A \"Space Life\" brand Scientist action figure." + icon_state = "scientist" + toysay = "Someone else must have made those bombs!" + +/obj/item/toy/figure/syndie + name = "Doom Operative action figure" + desc = "A \"Space Life\" brand Doom Operative action figure." + icon_state = "syndie" + toysay = "Get that fucking disk!" + +/obj/item/toy/figure/secofficer + name = "Security Officer action figure" + desc = "A \"Space Life\" brand Security Officer action figure." + icon_state = "secofficer" + toysay = "I am the law!" + +/obj/item/toy/figure/virologist + name = "Virologist action figure" + desc = "A \"Space Life\" brand Virologist action figure." + icon_state = "virologist" + toysay = "The cure is potassium!" + +/obj/item/toy/figure/warden + name = "Warden action figure" + desc = "A \"Space Life\" brand Warden action figure." + icon_state = "warden" + toysay = "Execute him for breaking in!" + +/obj/item/toy/figure/psychologist + name = "Psychologist action figure" + desc = "A \"Space Life\" brand Psychologist action figure." + icon_state = "psychologist" + toysay = "The analyzer says you're fine!" + +/obj/item/toy/figure/paramedic + name = "Paramedic action figure" + desc = "A \"Space Life\" brand Paramedic action figure." + icon_state = "paramedic" + toysay = "WHERE ARE YOU??" + +/obj/item/toy/figure/ert + name = "Emergency Response Team Commander action figure" + desc = "A \"Space Life\" brand Emergency Response Team Commander action figure." + icon_state = "ert" + toysay = "We're probably the good guys!" + +/* + * Plushies + */ + +/* + * Carp plushie + */ + +/obj/item/toy/plushie/carp + name = "space carp plushie" + desc = "An adorable stuffed toy that resembles a space carp." + icon = 'icons/obj/toy.dmi' + icon_state = "basecarp" + attack_verb = list("bitten", "eaten", "fin slapped") + var/bitesound = 'sound/weapons/bite.ogg' + +// Attack mob +/obj/item/toy/plushie/carp/attack(mob/M as mob, mob/user as mob) + playsound(src, bitesound, 20, 1) // Play bite sound in local area + return ..() + +// Attack self +/obj/item/toy/plushie/carp/attack_self(mob/user as mob) + playsound(src, bitesound, 20, 1) + return ..() + + +/obj/random/carp_plushie + name = "Random Carp Plushie" + desc = "This is a random plushie" + icon = 'icons/obj/toy.dmi' + icon_state = "basecarp" + +/obj/random/carp_plushie/item_to_spawn() + return pick(typesof(/obj/item/toy/plushie/carp)) //can pick any carp plushie, even the original. + +/obj/item/toy/plushie/carp/ice + name = "ice carp plushie" + icon_state = "icecarp" + +/obj/item/toy/plushie/carp/silent + name = "monochrome carp plushie" + icon_state = "silentcarp" + +/obj/item/toy/plushie/carp/electric + name = "electric carp plushie" + icon_state = "electriccarp" + +/obj/item/toy/plushie/carp/gold + name = "golden carp plushie" + icon_state = "goldcarp" + +/obj/item/toy/plushie/carp/toxin + name = "toxic carp plushie" + icon_state = "toxincarp" + +/obj/item/toy/plushie/carp/dragon + name = "dragon carp plushie" + icon_state = "dragoncarp" + +/obj/item/toy/plushie/carp/pink + name = "pink carp plushie" + icon_state = "pinkcarp" + +/obj/item/toy/plushie/carp/candy + name = "candy carp plushie" + icon_state = "candycarp" + +/obj/item/toy/plushie/carp/nebula + name = "nebula carp plushie" + icon_state = "nebulacarp" + +/obj/item/toy/plushie/carp/void + name = "void carp plushie" + icon_state = "voidcarp" + +//Large plushies. +/obj/structure/plushie + name = "generic plush" + desc = "A very generic plushie. It seems to not want to exist." + icon = 'icons/obj/toy.dmi' + icon_state = "ianplushie" + anchored = 0 + density = 1 + var/phrase = "I don't want to exist anymore!" + var/searching = FALSE + var/opened = FALSE // has this been slit open? this will allow you to store an object in a plushie. + var/obj/item/stored_item // Note: Stored items can't be bigger than the plushie itself. + +/obj/structure/plushie/examine(mob/user) + . = ..() + if(opened) + . += "You notice an incision has been made on [src]." + if(in_range(user, src) && stored_item) + . += "You can see something in there..." + +/obj/structure/plushie/attack_hand(mob/user) + user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) + + if(stored_item && opened && !searching) + searching = TRUE + if(do_after(user, 10)) + to_chat(user, "You find \icon[stored_item] [stored_item] in [src]!") + stored_item.forceMove(get_turf(src)) + stored_item = null + searching = FALSE + return + else + searching = FALSE + + if(user.a_intent == I_HELP) + user.visible_message("\The [user] hugs [src]!","You hug [src]!") + else if (user.a_intent == I_HURT) + user.visible_message("\The [user] punches [src]!","You punch [src]!") + else if (user.a_intent == I_GRAB) + user.visible_message("\The [user] attempts to strangle [src]!","You attempt to strangle [src]!") + else + user.visible_message("\The [user] pokes the [src].","You poke the [src].") + visible_message("[src] says, \"[phrase]\"") + + +/obj/structure/plushie/attackby(obj/item/I as obj, mob/user as mob) + if(istype(I, /obj/item/device/threadneedle) && opened) + to_chat(user, "You sew the hole in [src].") + opened = FALSE + return + + if(is_sharp(I) && !opened) + to_chat(user, "You open a small incision in [src]. You can place tiny items inside.") + opened = TRUE + return + + if(opened) + if(stored_item) + to_chat(user, "There is already something in here.") + return + + if(!(I.w_class > w_class)) + to_chat(user, "You place [I] inside [src].") + user.drop_from_inventory(I, src) + I.forceMove(src) + stored_item = I + return + else + to_chat(user, "You open a small incision in [src]. You can place tiny items inside.") + + + ..() + +/obj/structure/plushie/ian + name = "plush corgi" + desc = "A plushie of an adorable corgi! Don't you just want to hug it and squeeze it and call it \"Ian\"?" + icon_state = "ianplushie" + phrase = "Arf!" + +/obj/structure/plushie/drone + name = "plush drone" + desc = "A plushie of a happy drone! It appears to be smiling." + icon_state = "droneplushie" + phrase = "Beep boop!" + +/obj/structure/plushie/carp + name = "plush carp" + desc = "A plushie of an elated carp! Straight from the wilds of the Vir frontier, now right here in your hands." + icon_state = "carpplushie" + phrase = "Glorf!" + +/obj/structure/plushie/beepsky + name = "plush Officer Sweepsky" + desc = "A plushie of a popular industrious cleaning robot! If it could feel emotions, it would love you." + icon_state = "beepskyplushie" + phrase = "Ping!" + +//Small plushies. +/obj/item/toy/plushie + name = "generic small plush" + desc = "A small toy plushie. It's very cute." + icon = 'icons/obj/toy.dmi' + icon_state = "nymphplushie" + drop_sound = 'sound/items/drop/plushie.ogg' + w_class = ITEMSIZE_TINY + var/last_message = 0 + var/pokephrase = "Uww!" + var/searching = FALSE + var/opened = FALSE // has this been slit open? this will allow you to store an object in a plushie. + var/obj/item/stored_item // Note: Stored items can't be bigger than the plushie itself. + + +/obj/item/toy/plushie/examine(mob/user) + . = ..() + if(opened) + . += "You notice an incision has been made on [src]." + if(in_range(user, src) && stored_item) + . += "You can see something in there..." + +/obj/item/toy/plushie/attack_self(mob/user as mob) + if(stored_item && opened && !searching) + searching = TRUE + if(do_after(user, 10)) + to_chat(user, "You find \icon[stored_item] [stored_item] in [src]!") + stored_item.forceMove(get_turf(src)) + stored_item = null + searching = FALSE + return + else + searching = FALSE + + if(world.time - last_message <= 1 SECOND) + return + if(user.a_intent == I_HELP) + user.visible_message("\The [user] hugs [src]!","You hug [src]!") + else if (user.a_intent == I_HURT) + user.visible_message("\The [user] punches [src]!","You punch [src]!") + else if (user.a_intent == I_GRAB) + user.visible_message("\The [user] attempts to strangle [src]!","You attempt to strangle [src]!") + else + user.visible_message("\The [user] pokes [src].","You poke [src].") + playsound(src, 'sound/items/drop/plushie.ogg', 25, 0) + visible_message("[src] says, \"[pokephrase]\"") + last_message = world.time + +/obj/item/toy/plushie/verb/rename_plushie() + set name = "Name Plushie" + set category = "Object" + set desc = "Give your plushie a cute name!" + var/mob/M = usr + if(!M.mind) + return 0 + + var/input = sanitizeSafe(input("What do you want to name the plushie?", ,""), MAX_NAME_LEN) + + if(src && input && !M.stat && in_range(M,src)) + name = input + to_chat(M, "You name the plushie [input], giving it a hug for good luck.") + return 1 + +/obj/item/toy/plushie/attackby(obj/item/I as obj, mob/user as mob) + if(istype(I, /obj/item/toy/plushie) || istype(I, /obj/item/organ/external/head)) + user.visible_message("[user] makes \the [I] kiss \the [src]!.", \ + "You make \the [I] kiss \the [src]!.") + return + + + if(istype(I, /obj/item/device/threadneedle) && opened) + to_chat(user, "You sew the hole underneath [src].") + opened = FALSE + return + + if(is_sharp(I) && !opened) + to_chat(user, "You open a small incision in [src]. You can place tiny items inside.") + opened = TRUE + return + + if( (!(I.w_class > w_class)) && opened) + if(stored_item) + to_chat(user, "There is already something in here.") + return + + to_chat(user, "You place [I] inside [src].") + user.drop_from_inventory(I, src) + I.forceMove(src) + stored_item = I + to_chat(user, "You placed [I] into [src].") + return + + return ..() + +/obj/item/toy/plushie/nymph + name = "diona nymph plush" + desc = "A plushie of an adorable diona nymph! While its level of self-awareness is still being debated, its level of cuteness is not." + icon_state = "nymphplushie" + pokephrase = "Chirp!" + +/obj/item/toy/plushie/teshari + name = "teshari plush" + desc = "This is a plush teshari. Very soft, with a pompom on the tail. The toy is made well, as if alive. Looks like she is sleeping. Shhh!" + icon_state = "teshariplushie" + pokephrase = "Rya!" + +/obj/item/toy/plushie/mouse + name = "mouse plush" + desc = "A plushie of a delightful mouse! What was once considered a vile rodent is now your very best friend." + icon_state = "mouseplushie" //TFF 12/11/19 - updated icon to show a sprite that doesn't replicate a dead mouse. Heck you for that! >:C + pokephrase = "Squeak!" + +/obj/item/toy/plushie/kitten + name = "kitten plush" + desc = "A plushie of a cute kitten! Watch as it purrs its way right into your heart." + icon_state = "kittenplushie" + pokephrase = "Mrow!" + +/obj/item/toy/plushie/lizard + name = "lizard plush" + desc = "A plushie of a scaly lizard! Very controversial, after being accused as \"racist\" by some Unathi." + icon_state = "lizardplushie" + pokephrase = "Hiss!" + +/obj/item/toy/plushie/spider + name = "spider plush" + desc = "A plushie of a fuzzy spider! It has eight legs - all the better to hug you with." + icon_state = "spiderplushie" + pokephrase = "Sksksk!" + +/obj/item/toy/plushie/farwa + name = "farwa plush" + desc = "A farwa plush doll. It's soft and comforting!" + icon_state = "farwaplushie" + pokephrase = "Squaw!" + +/obj/item/toy/plushie/corgi + name = "corgi plushie" + icon_state = "corgi" + pokephrase = "Woof!" + +/obj/item/toy/plushie/girly_corgi + name = "corgi plushie" + icon_state = "girlycorgi" + pokephrase = "Arf!" + +/obj/item/toy/plushie/robo_corgi + name = "borgi plushie" + icon_state = "robotcorgi" + pokephrase = "Bark." + +/obj/item/toy/plushie/octopus + name = "octopus plushie" + icon_state = "loveable" + pokephrase = "Squish!" + +/obj/item/toy/plushie/face_hugger + name = "facehugger plushie" + icon_state = "huggable" + pokephrase = "Hug!" + +//foxes are basically the best + +/obj/item/toy/plushie/red_fox + name = "red fox plushie" + icon_state = "redfox" + pokephrase = "Gecker!" + +/obj/item/toy/plushie/black_fox + name = "black fox plushie" + icon_state = "blackfox" + pokephrase = "Ack!" + +/obj/item/toy/plushie/marble_fox + name = "marble fox plushie" + icon_state = "marblefox" + pokephrase = "Awoo!" + +/obj/item/toy/plushie/blue_fox + name = "blue fox plushie" + icon_state = "bluefox" + pokephrase = "Yoww!" + +/obj/item/toy/plushie/orange_fox + name = "orange fox plushie" + icon_state = "orangefox" + pokephrase = "Yagh!" + +/obj/item/toy/plushie/coffee_fox + name = "coffee fox plushie" + icon_state = "coffeefox" + pokephrase = "Gerr!" + +/obj/item/toy/plushie/pink_fox + name = "pink fox plushie" + icon_state = "pinkfox" + pokephrase = "Yack!" + +/obj/item/toy/plushie/purple_fox + name = "purple fox plushie" + icon_state = "purplefox" + pokephrase = "Whine!" + +/obj/item/toy/plushie/crimson_fox + name = "crimson fox plushie" + icon_state = "crimsonfox" + pokephrase = "Auuu!" + +/obj/item/toy/plushie/deer + name = "deer plushie" + icon_state = "deer" + pokephrase = "Bleat!" + +/obj/item/toy/plushie/black_cat + name = "black cat plushie" + icon_state = "blackcat" + pokephrase = "Mlem!" + +/obj/item/toy/plushie/grey_cat + name = "grey cat plushie" + icon_state = "greycat" + pokephrase = "Mraw!" + +/obj/item/toy/plushie/white_cat + name = "white cat plushie" + icon_state = "whitecat" + pokephrase = "Mew!" + +/obj/item/toy/plushie/orange_cat + name = "orange cat plushie" + icon_state = "orangecat" + pokephrase = "Meow!" + +/obj/item/toy/plushie/siamese_cat + name = "siamese cat plushie" + icon_state = "siamesecat" + pokephrase = "Mrew?" + +/obj/item/toy/plushie/tabby_cat + name = "tabby cat plushie" + icon_state = "tabbycat" + pokephrase = "Purr!" + +/obj/item/toy/plushie/tuxedo_cat + name = "tuxedo cat plushie" + icon_state = "tuxedocat" + pokephrase = "Mrowww!!" + +// nah, squids are better than foxes :> + +/obj/item/toy/plushie/squid/green + name = "green squid plushie" + desc = "A small, cute and loveable squid friend. This one is green." + icon = 'icons/obj/toy.dmi' + icon_state = "greensquid" + slot_flags = SLOT_HEAD + pokephrase = "Squrr!" + +/obj/item/toy/plushie/squid/mint + name = "mint squid plushie" + desc = "A small, cute and loveable squid friend. This one is mint coloured." + icon = 'icons/obj/toy.dmi' + icon_state = "mintsquid" + slot_flags = SLOT_HEAD + pokephrase = "Blurble!" + +/obj/item/toy/plushie/squid/blue + name = "blue squid plushie" + desc = "A small, cute and loveable squid friend. This one is blue." + icon = 'icons/obj/toy.dmi' + icon_state = "bluesquid" + slot_flags = SLOT_HEAD + pokephrase = "Blob!" + +/obj/item/toy/plushie/squid/orange + name = "orange squid plushie" + desc = "A small, cute and loveable squid friend. This one is orange." + icon = 'icons/obj/toy.dmi' + icon_state = "orangesquid" + slot_flags = SLOT_HEAD + pokephrase = "Squash!" + +/obj/item/toy/plushie/squid/yellow + name = "yellow squid plushie" + desc = "A small, cute and loveable squid friend. This one is yellow." + icon = 'icons/obj/toy.dmi' + icon_state = "yellowsquid" + slot_flags = SLOT_HEAD + pokephrase = "Glorble!" + +/obj/item/toy/plushie/squid/pink + name = "pink squid plushie" + desc = "A small, cute and loveable squid friend. This one is pink." + icon = 'icons/obj/toy.dmi' + icon_state = "pinksquid" + slot_flags = SLOT_HEAD + pokephrase = "Wobble!" + +/obj/item/toy/plushie/therapy/red + name = "red therapy doll" + desc = "A toy for therapeutic and recreational purposes. This one is red." + icon = 'icons/obj/toy.dmi' + icon_state = "therapyred" + item_state = "egg4" // It's the red egg in items_left/righthand + +/obj/item/toy/plushie/therapy/purple + name = "purple therapy doll" + desc = "A toy for therapeutic and recreational purposes. This one is purple." + icon = 'icons/obj/toy.dmi' + icon_state = "therapypurple" + item_state = "egg1" // It's the magenta egg in items_left/righthand + +/obj/item/toy/plushie/therapy/blue + name = "blue therapy doll" + desc = "A toy for therapeutic and recreational purposes. This one is blue." + icon = 'icons/obj/toy.dmi' + icon_state = "therapyblue" + item_state = "egg2" // It's the blue egg in items_left/righthand + +/obj/item/toy/plushie/therapy/yellow + name = "yellow therapy doll" + desc = "A toy for therapeutic and recreational purposes. This one is yellow." + icon = 'icons/obj/toy.dmi' + icon_state = "therapyyellow" + item_state = "egg5" // It's the yellow egg in items_left/righthand + +/obj/item/toy/plushie/therapy/orange + name = "orange therapy doll" + desc = "A toy for therapeutic and recreational purposes. This one is orange." + icon = 'icons/obj/toy.dmi' + icon_state = "therapyorange" + item_state = "egg4" // It's the red one again, lacking an orange item_state and making a new one is pointless + +/obj/item/toy/plushie/therapy/green + name = "green therapy doll" + desc = "A toy for therapeutic and recreational purposes. This one is green." + icon = 'icons/obj/toy.dmi' + icon_state = "therapygreen" + item_state = "egg3" // It's the green egg in items_left/righthand + + +//Toy cult sword +/obj/item/toy/cultsword + name = "foam sword" + desc = "An arcane weapon (made of foam) wielded by the followers of the hit Saturday morning cartoon \"King Nursee and the Acolytes of Heroism\"." + icon = 'icons/obj/weapons.dmi' + icon_state = "cultblade" + item_icons = list( + slot_l_hand_str = 'icons/mob/items/lefthand_melee.dmi', + slot_r_hand_str = 'icons/mob/items/righthand_melee.dmi', + ) + w_class = ITEMSIZE_LARGE + attack_verb = list("attacked", "slashed", "stabbed", "poked") + +//Flowers fake & real + +/obj/item/toy/bouquet + name = "bouquet" + desc = "A lovely bouquet of flowers. Smells nice!" + icon = 'icons/obj/items.dmi' + icon_state = "bouquet" + w_class = ITEMSIZE_SMALL + +/obj/item/toy/bouquet/fake + name = "plastic bouquet" + desc = "A cheap plastic bouquet of flowers. Smells like cheap, toxic plastic." + +/obj/item/toy/stickhorse + name = "stick horse" + desc = "A pretend horse on a stick for any aspiring little cowboy to ride." + icon = 'icons/obj/toy.dmi' + icon_state = "stickhorse" + w_class = ITEMSIZE_LARGE + +////////////////////////////////////////////////////// +// Magic 8-Ball / Conch // +////////////////////////////////////////////////////// + +/obj/item/toy/eight_ball + name = "\improper Magic 8-Ball" + desc = "Mystical! Magical! Ages 8+!" + icon = 'icons/obj/toy.dmi' + icon_state = "eight-ball" + var/use_action = "shakes the ball" + var/cooldown = 0 + var/list/possible_answers = list("Definitely.", "All signs point to yes.", "Most likely.", "Yes.", "Ask again later.", "Better not tell you now.", "Future unclear.", "Maybe.", "Doubtful.", "No.", "Don't count on it.", "Never.") + +/obj/item/toy/eight_ball/attack_self(mob/user as mob) + if(!cooldown) + var/answer = pick(possible_answers) + user.visible_message("[user] focuses on their question and [use_action]...") + user.visible_message("The [src] says \"[answer]\"") + spawn(30) + cooldown = 0 + return + +/obj/item/toy/eight_ball/conch + name = "Magic Conch shell" + desc = "All hail the Magic Conch!" + icon_state = "conch" + use_action = "pulls the string" + possible_answers = list("Yes.", "No.", "Try asking again.", "Nothing.", "I don't think so.", "Neither.", "Maybe someday.") + +// DND Character minis. Use the naming convention (type)character for the icon states. +/obj/item/toy/character + icon = 'icons/obj/toy.dmi' + w_class = ITEMSIZE_SMALL + pixel_z = 5 + +/obj/item/toy/character/alien + name = "xenomorph xiniature" + desc = "A miniature xenomorph. Scary!" + icon_state = "aliencharacter" +/obj/item/toy/character/cleric + name = "cleric miniature" + desc = "A wee little cleric, with his wee little staff." + icon_state = "clericcharacter" +/obj/item/toy/character/warrior + name = "warrior miniature" + desc = "That sword would make a decent toothpick." + icon_state = "warriorcharacter" +/obj/item/toy/character/thief + name = "thief miniature" + desc = "Hey, where did my wallet go!?" + icon_state = "thiefcharacter" +/obj/item/toy/character/wizard + name = "wizard miniature" + desc = "MAGIC!" + icon_state = "wizardcharacter" +/obj/item/toy/character/voidone + name = "void one miniature" + desc = "The dark lord has risen!" + icon_state = "darkmastercharacter" +/obj/item/toy/character/lich + name = "lich miniature" + desc = "Murderboner extraordinaire." + icon_state = "lichcharacter" +/obj/item/weapon/storage/box/characters + name = "box of miniatures" + desc = "The nerd's best friends." + icon_state = "box" +/obj/item/weapon/storage/box/characters/starts_with = list( +// /obj/item/toy/character/alien, + /obj/item/toy/character/cleric, + /obj/item/toy/character/warrior, + /obj/item/toy/character/thief, + /obj/item/toy/character/wizard, + /obj/item/toy/character/voidone, + /obj/item/toy/character/lich + ) + +/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. + icon = 'icons/obj/toy.dmi' + 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() + to_chat(user, "You press the button on [src].") + playsound(src, 'sound/machines/click.ogg', 20, 1) + visible_message("[message]") + cooldown = 1 + spawn(30) cooldown = 0 + return + ..() +*/ +/obj/item/toy/owl + name = "owl action figure" + desc = "An action figure modeled after 'The Owl', defender of justice." + icon = 'icons/obj/toy.dmi' + icon_state = "owlprize" + w_class = ITEMSIZE_SMALL + var/cooldown = 0 + +/obj/item/toy/owl/attack_self(mob/user) + if(!cooldown) //for the sanity of everyone + var/message = pick("You won't get away this time, Griffin!", "Stop right there, criminal!", "Hoot! Hoot!", "I am the night!") + to_chat(user, "You pull the string on the [src].") + //playsound(src, 'sound/misc/hoot.ogg', 25, 1) + visible_message("[message]") + cooldown = 1 + spawn(30) cooldown = 0 + return + ..() + +/obj/item/toy/griffin + name = "griffin action figure" + desc = "An action figure modeled after 'The Griffin', criminal mastermind." + icon = 'icons/obj/toy.dmi' + icon_state = "griffinprize" + w_class = ITEMSIZE_SMALL + var/cooldown = 0 + +/obj/item/toy/griffin/attack_self(mob/user) + if(!cooldown) //for the sanity of everyone + var/message = pick("You can't stop me, Owl!", "My plan is flawless! The vault is mine!", "Caaaawwww!", "You will never catch me!") + to_chat(user, "You pull the string on the [src].") + //playsound(src, 'sound/misc/caw.ogg', 25, 1) + visible_message("[message]") + cooldown = 1 + spawn(30) cooldown = 0 + return + ..() + +/* NYET. +/obj/item/weapon/toddler + icon_state = "toddler" + name = "toddler" + desc = "This baby looks almost real. Wait, did it just burp?" + force = 5 + w_class = ITEMSIZE_LARGE + slot_flags = SLOT_BACK +*/ + +//This should really be somewhere else but I don't know where. w/e + +/obj/item/weapon/inflatable_duck + name = "inflatable duck" + desc = "No bother to sink or swim when you can just float!" + icon_state = "inflatable" + icon = 'icons/obj/clothing/belts.dmi' + slot_flags = SLOT_BELT + drop_sound = 'sound/items/drop/rubber.ogg' + +/obj/item/toy/xmastree + name = "Miniature Christmas tree" + desc = "Tiny cute Christmas tree." + icon = 'icons/obj/toy.dmi' + icon_state = "tinyxmastree" + w_class = ITEMSIZE_TINY + force = 1 + throwforce = 1 + drop_sound = 'sound/items/drop/box.ogg' + +////////////////////////////////////////////////////// +// Chess Pieces // +////////////////////////////////////////////////////// + +/obj/item/toy/chess + name = "chess piece" + desc = "This should never display." + icon = 'icons/obj/chess.dmi' + w_class = ITEMSIZE_SMALL + force = 1 + throwforce = 1 + drop_sound = 'sound/items/drop/glass.ogg' + +/obj/item/toy/chess/pawn_white + name = "blue pawn" + desc = "A large pawn piece for playing chess. It's made of a blue-colored glass." + description_info = "Pawns can move forward one square, if that square is unoccupied. If the pawn has not yet moved, it has the option of moving two squares forward provided both squares in front of the pawn are unoccupied. A pawn cannot move backward. They can only capture an enemy piece on either of the two tiles diagonally in front of them, but not the tile directly in front of them." + icon_state = "w-pawn" +/obj/item/toy/chess/pawn_black + name = "purple pawn" + desc = "A large pawn piece for playing chess. It's made of a purple-colored glass." + description_info = "Pawns can move forward one square, if that square is unoccupied. If the pawn has not yet moved, it has the option of moving two squares forward provided both squares in front of the pawn are unoccupied. A pawn cannot move backward. They can only capture an enemy piece on either of the two tiles diagonally in front of them, but not the tile directly in front of them." + icon_state = "b-pawn" +/obj/item/toy/chess/rook_white + name = "blue rook" + desc = "A large rook piece for playing chess. It's made of a blue-colored glass." + description_info = "The Rook can move any number of vacant squares vertically or horizontally." + icon_state = "w-rook" +/obj/item/toy/chess/rook_black + name = "purple rook" + desc = "A large rook piece for playing chess. It's made of a purple-colored glass." + description_info = "The Rook can move any number of vacant squares vertically or horizontally." + icon_state = "b-rook" +/obj/item/toy/chess/knight_white + name = "blue knight" + desc = "A large knight piece for playing chess. It's made of a blue-colored glass. Sadly, you can't ride it." + description_info = "The Knight can either move two squares horizontally and one square vertically or two squares vertically and one square horizontally. The knight's movement can also be viewed as an 'L' laid out at any horizontal or vertical angle." + icon_state = "w-knight" +/obj/item/toy/chess/knight_black + name = "purple knight" + desc = "A large knight piece for playing chess. It's made of a purple-colored glass. 'Just a flesh wound.'" + description_info = "The Knight can either move two squares horizontally and one square vertically or two squares vertically and one square horizontally. The knight's movement can also be viewed as an 'L' laid out at any horizontal or vertical angle." + icon_state = "b-knight" +/obj/item/toy/chess/bishop_white + name = "blue bishop" + desc = "A large bishop piece for playing chess. It's made of a blue-colored glass." + description_info = "The Bishop can move any number of vacant squares in any diagonal direction." + icon_state = "w-bishop" +/obj/item/toy/chess/bishop_black + name = "purple bishop" + desc = "A large bishop piece for playing chess. It's made of a purple-colored glass." + description_info = "The Bishop can move any number of vacant squares in any diagonal direction." + icon_state = "b-bishop" +/obj/item/toy/chess/queen_white + name = "blue queen" + desc = "A large queen piece for playing chess. It's made of a blue-colored glass." + description_info = "The Queen can move any number of vacant squares diagonally, horizontally, or vertically." + icon_state = "w-queen" +/obj/item/toy/chess/queen_black + name = "purple queen" + desc = "A large queen piece for playing chess. It's made of a purple-colored glass." + description_info = "The Queen can move any number of vacant squares diagonally, horizontally, or vertically." + icon_state = "b-queen" +/obj/item/toy/chess/king_white + name = "blue king" + desc = "A large king piece for playing chess. It's made of a blue-colored glass." + description_info = "The King can move exactly one square horizontally, vertically, or diagonally. If your opponent captures this piece, you lose." + icon_state = "w-king" +/obj/item/toy/chess/king_black + name = "purple king" + desc = "A large king piece for playing chess. It's made of a purple-colored glass." + description_info = "The King can move exactly one square horizontally, vertically, or diagonally. If your opponent captures this piece, you lose." icon_state = "b-king" \ No newline at end of file diff --git a/code/game/objects/items/toys_vr.dm b/code/game/objects/items/toys/toys_vr.dm similarity index 100% rename from code/game/objects/items/toys_vr.dm rename to code/game/objects/items/toys/toys_vr.dm diff --git a/code/game/objects/items/trash.dm b/code/game/objects/items/trash.dm index aa4b02b2840..4b18001e459 100644 --- a/code/game/objects/items/trash.dm +++ b/code/game/objects/items/trash.dm @@ -14,8 +14,9 @@ if(!isnull(_age)) age = _age -/obj/item/trash/Initialize() - SSpersistence.track_value(src, /datum/persistent/filth/trash) +/obj/item/trash/Initialize(mapload) + if(!mapload || !config.persistence_ignore_mapload) + SSpersistence.track_value(src, /datum/persistent/filth/trash) . = ..() /obj/item/trash/Destroy() @@ -27,40 +28,60 @@ icon_state = "4no_raisins" /obj/item/trash/candy - name = "candy" + name = "hard candy wrapper" icon_state = "candy" +/obj/item/trash/candy/gums + name = "gummy candy bag" + icon_state = "candy_gums" + /obj/item/trash/candy/proteinbar - name = "protein bar" + name = "protein bar wrapper" icon_state = "proteinbar" +/obj/item/trash/candy/fruitbar + name = "fruit bar wrapper" + icon_state = "fruitbar" + /obj/item/trash/cheesie - name = "\improper Cheesie Honkers" + name = "\improper Cheesie Honkers bag" icon_state = "cheesie_honkers" /obj/item/trash/chips - name = "chips" + name = "chips bag" icon_state = "chips" +/obj/item/trash/chips/bbq + name = "bbq chips bag" + icon_state = "chips_bbq" + +/obj/item/trash/cookiesnack + name = "\improper Carps Ahoy! miniature cookies packet" + icon_state = "cookiesnack" + /obj/item/trash/popcorn - name = "popcorn" + name = "popcorn bag" icon_state = "popcorn" +/obj/item/trash/tuna + name = "tuna can" + icon_state = "tuna" + /obj/item/trash/sosjerky - name = "Scaredy's Private Reserve Beef Jerky" + name = "Scaredy's Private Reserve Beef Jerky wrapper" icon_state = "sosjerky" /obj/item/trash/unajerky - name = "Moghes Imported Sissalik Jerky" + name = "Moghes Imported Sissalik Jerky tin" icon_state = "unathitinred" drop_sound = 'sound/items/drop/soda.ogg' /obj/item/trash/syndi_cakes - name = "syndi cakes" + name = "syndi cakes box" icon_state = "syndi_cakes" /obj/item/trash/waffles - name = "waffles" + name = "waffles tray" icon_state = "waffles" /obj/item/trash/plate @@ -72,13 +93,39 @@ icon_state = "snack_bowl" /obj/item/trash/pistachios - name = "pistachios pack" + name = "pistachios packet" icon_state = "pistachios_pack" /obj/item/trash/semki - name = "semki pack" + name = "semki packet" icon_state = "semki_pack" +/obj/item/trash/koisbar + name = "candy wrapper" + icon_state = "koisbar" + +/obj/item/trash/kokobar + name = "candy wrapper" + icon_state = "kokobar" + +/obj/item/trash/gumpack + name = "gum packet" + icon_state = "gum_pack" + +/obj/item/trash/admints + name = "mint wrapper" + icon_state = "admint_pack" + +/obj/item/trash/coffee + name = "empty cup" + icon_state = "coffee_vended" + drop_sound = 'sound/items/drop/papercup.ogg' + +/obj/item/trash/ramen + name = "cup ramen" + icon_state = "ramen" + drop_sound = 'sound/items/drop/papercup.ogg' + /obj/item/trash/tray name = "tray" icon_state = "tray" @@ -90,19 +137,19 @@ icon_state = "candle4" /obj/item/trash/liquidfood - name = "\improper \"LiquidFood\" ration" + name = "\improper \"LiquidFood\" ration packet" icon_state = "liquidfood" /obj/item/trash/liquidprotein - name = "\improper \"LiquidProtein\" ration" + name = "\improper \"LiquidProtein\" ration packet" icon_state = "liquidprotein" /obj/item/trash/liquidvitamin - name = "\improper \"VitaPaste\" ration" + name = "\improper \"VitaPaste\" ration packet" icon_state = "liquidvitamin" /obj/item/trash/tastybread - name = "bread tube" + name = "bread tube wrapper" icon_state = "tastybread" // Aurora Food Port @@ -120,7 +167,28 @@ /obj/item/trash/chipbasket name = "empty basket" - icon_state = "chipbasket_empty" + icon_state = "chipbasket_empty" + +/obj/item/trash/spitgum + name = "old gum" + desc = "A disgusting chewed up wad of gum." + icon = 'icons/obj/clothing/masks.dmi' + icon_state = "spit-gum" + drop_sound = 'sound/items/drop/flesh.ogg' + +/obj/item/trash/lollibutt + name = "lollipop stick" + desc = "A lollipop stick devoid of pop." + icon = 'icons/obj/clothing/masks.dmi' + icon_state = "pop-stick" + +/obj/item/trash/spitwad + name = "spit wad" + desc = "A disgusting spitwad." + icon = 'icons/obj/clothing/masks.dmi' + icon_state = "spit-chew" + drop_sound = 'sound/items/drop/flesh.ogg' + slot_flags = SLOT_EARS | SLOT_MASK /obj/item/trash/attack(mob/M as mob, mob/living/user as mob) return diff --git a/code/game/objects/items/weapons/RSF.dm b/code/game/objects/items/weapons/RSF.dm index d7ced2bc7a9..5d983e596a1 100644 --- a/code/game/objects/items/weapons/RSF.dm +++ b/code/game/objects/items/weapons/RSF.dm @@ -19,6 +19,7 @@ RSF var/list/container_types = list( "metamorphic glass" = /obj/item/weapon/reagent_containers/food/drinks/metaglass, + "metamorphic pint glass" = /obj/item/weapon/reagent_containers/food/drinks/metaglass/metapint, "half-pint glass" = /obj/item/weapon/reagent_containers/food/drinks/glass2/square, "rocks glass" = /obj/item/weapon/reagent_containers/food/drinks/glass2/rocks, "milkshake glass" = /obj/item/weapon/reagent_containers/food/drinks/glass2/shake, diff --git a/code/game/objects/items/weapons/chewables.dm b/code/game/objects/items/weapons/chewables.dm new file mode 100644 index 00000000000..e6d7dbcf99e --- /dev/null +++ b/code/game/objects/items/weapons/chewables.dm @@ -0,0 +1,233 @@ +/obj/item/clothing/mask/chewable + name = "chewable item master" + desc = "If you are seeing this, ahelp it." + icon = 'icons/obj/clothing/masks.dmi' + drop_sound = 'sound/items/drop/food.ogg' + body_parts_covered = 0 + + var/type_butt = null + var/chem_volume = 0 + var/chewtime = 0 + var/brand + var/list/filling = list() + var/wrapped = FALSE + +/obj/item/clothing/mask/chewable/attack_self(mob/user) + if(wrapped) + wrapped = FALSE + to_chat(user, span("notice", "You unwrap \the [name].")) + playsound(src.loc, 'sound/items/drop/wrapper.ogg', 50, 1) + slot_flags = SLOT_EARS | SLOT_MASK + update_icon() + +/obj/item/clothing/mask/chewable/update_icon() + cut_overlays() + if(wrapped) + add_overlay("[initial(icon_state)]_wrapper") + +obj/item/clothing/mask/chewable/Initialize() + . = ..() + flags |= NOREACT // so it doesn't react until you light it + create_reagents(chem_volume) // making the cigarrete a chemical holder with a maximum volume of 15 + for(var/R in filling) + reagents.add_reagent(R, filling[R]) + if(wrapped) + slot_flags = null + +/obj/item/clothing/mask/chewable/equipped(var/mob/living/user, var/slot) + ..() + if(slot == slot_wear_mask) + var/mob/living/carbon/human/C = user + if(C.check_has_mouth()) + START_PROCESSING(SSprocessing, src) + else + to_chat(user, span("notice", "You don't have a mouth, and can't make much use of \the [src].")) + +/obj/item/clothing/mask/chewable/dropped() + STOP_PROCESSING(SSprocessing, src) + ..() + +obj/item/clothing/mask/chewable/Destroy() + . = ..() + STOP_PROCESSING(SSprocessing, src) + +/obj/item/clothing/mask/chewable/proc/chew() + chewtime-- + if(reagents && reagents.total_volume) + if(ishuman(loc)) + var/mob/living/carbon/human/C = loc + if (src == C.wear_mask && C.check_has_mouth()) + reagents.trans_to_mob(C, REM, CHEM_INGEST, 0.2) + else + STOP_PROCESSING(SSprocessing, src) + +/obj/item/clothing/mask/chewable/process() + chew() + if(chewtime < 1) + spitout() + +/obj/item/clothing/mask/chewable/tobacco + name = "wad" + desc = "A chewy wad of tobacco. Cut in long strands and treated with syrup so it doesn't taste like an ash-tray when you stuff it into your face." + throw_speed = 0.5 + icon_state = "chew" + type_butt = /obj/item/trash/spitwad + w_class = 1 + slot_flags = SLOT_EARS | SLOT_MASK + chem_volume = 50 + chewtime = 300 + brand = "tobacco" + + +/obj/item/clothing/mask/chewable/proc/spitout(var/transfer_color = 1, var/no_message = 0) + if(type_butt) + var/obj/item/butt = new type_butt(src.loc) + transfer_fingerprints_to(butt) + if(transfer_color) + butt.color = color + if(brand) + butt.desc += " This one is \a [brand]." + if(ismob(loc)) + var/mob/living/M = loc + if(!no_message) + to_chat(M, SPAN_NOTICE("The [name] runs out of flavor.")) + if(M.wear_mask) + M.remove_from_mob(src) //un-equip it so the overlays can update + M.update_inv_wear_mask(0) + if(!M.equip_to_slot_if_possible(butt, slot_wear_mask)) + M.update_inv_l_hand(0) + M.update_inv_r_hand(1) + M.put_in_hands(butt) + STOP_PROCESSING(SSprocessing, src) + qdel(src) + +/obj/item/clothing/mask/chewable/tobacco/cheap + name = "chewing tobacco" + desc = "A chewy wad of tobacco. Cut in long strands and treated with syrup so it tastes less like an ash-tray when you stuff it into your face." + filling = list("nicotine" = 2) + +/obj/item/clothing/mask/chewable/tobacco/fine + name = "deluxe chewing tobacco" + desc = "A chewy wad of fine tobacco. Cut in long strands and treated with syrup so it doesn't taste like an ash-tray when you stuff it into your face." + filling = list("nicotine" = 3) + +/obj/item/clothing/mask/chewable/tobacco/nico + name = "nicotine gum" + desc = "A chewy wad of synthetic rubber, laced with nicotine. Possibly the least disgusting method of nicotine delivery." + icon_state = "nic_gum" + type_butt = /obj/item/trash/spitgum + wrapped = TRUE + +/obj/item/clothing/mask/chewable/tobacco/nico/Initialize() + . = ..() + reagents.add_reagent("nicotine", 2) + color = reagents.get_color() + +/obj/item/weapon/storage/chewables + name = "box of chewing wads master" + desc = "A generic brand of Waffle Co Wads, unflavored chews. Why do these exist?" + icon = 'icons/obj/cigarettes.dmi' + icon_state = "cigpacket" + item_state = "cigpacket" + drop_sound = 'sound/items/drop/shovel.ogg' + use_sound = 'sound/items/storage/pillbottle.ogg' + w_class = 2 + throwforce = 2 + slot_flags = SLOT_BELT + starts_with = list(/obj/item/clothing/mask/chewable/tobacco = 6) + make_exact_fit() + +//Tobacco Tins + +/obj/item/weapon/storage/chewables/tobacco + name = "tin of Al Mamun Smooth chewing tobacco" + desc = "Packaged and shipped straight from Kishar, popularised by the biosphere farmers of Kanondaga." + icon_state = "chew_generic" + item_state = "cigpacket" + starts_with = list(/obj/item/clothing/mask/chewable/tobacco/cheap = 6) + storage_slots = 6 + +/obj/item/weapon/storage/chewables/tobacco/fine + name = "tin of Suamalie chewing tobacco" + desc = "Once reserved for the first-class tourists of Oasis, this premium blend has been released for the public to enjoy." + icon_state = "chew_fine" + item_state = "Dpacket" + starts_with = list(/obj/item/clothing/mask/chewable/tobacco/fine = 6) + +/obj/item/weapon/storage/box/fancy/chewables/tobacco/nico + name = "box of Nico-Tine gum" + desc = "A government doctor approved brand of nicotine gum. Cut out the middleman for your addiction fix." + icon = 'icons/obj/cigarettes.dmi' + icon_state = "chew_nico" + item_state = "Epacket" + starts_with = list(/obj/item/clothing/mask/chewable/tobacco/nico = 6) + storage_slots = 6 + drop_sound = 'sound/items/drop/box.ogg' + use_sound = 'sound/items/storage/box.ogg' + +/obj/item/weapon/storage/box/fancy/chewables/tobacco/update_icon() + icon_state = "[initial(icon_state)][contents.len]" + + +/obj/item/clothing/mask/chewable/candy + name = "wad" + desc = "A chewy wad of wadding material." + throw_speed = 0.5 + icon_state = "chew" + type_butt = /obj/item/trash/spitgum + w_class = 1 + slot_flags = SLOT_EARS | SLOT_MASK + chem_volume = 50 + chewtime = 300 + filling = list("sugar" = 2) + +/obj/item/clothing/mask/chewable/candy/gum + name = "chewing gum" + desc = "A chewy wad of fine synthetic rubber and artificial flavoring. Be sure to unwrap it, genius." + icon_state = "gum" + item_state = "gum" + wrapped = TRUE + +/obj/item/clothing/mask/chewable/candy/gum/Initialize() + . = ..() + reagents.add_reagent(pick("banana","berryjuice","grapejuice","lemonjuice","limejuice","orangejuice","watermelonjuice"),10) + color = reagents.get_color() + update_icon() + +/obj/item/weapon/storage/box/gum + name = "\improper Frooty-Choos flavored gum" + desc = "A small pack of chewing gum in various flavors." + description_fluff = "Frooty-Choos is NanoTrasen's top-selling brand of artificially flavoured fruit-adjacent non-swallowable chew-product. This extremely specific definition places sales figures safely away from competing 'gum' brands." + icon = 'icons/obj/food_snacks.dmi' + icon_state = "gum_pack" + item_state = "candy" + slot_flags = SLOT_EARS + w_class = 1 + starts_with = list(/obj/item/clothing/mask/chewable/candy/gum = 5) + can_hold = list(/obj/item/clothing/mask/chewable/candy/gum, + /obj/item/trash/spitgum) + use_sound = 'sound/items/drop/paper.ogg' + drop_sound = 'sound/items/drop/wrapper.ogg' + max_storage_space = 5 + foldable = null + trash = /obj/item/trash/gumpack + +/obj/item/clothing/mask/chewable/candy/lolli + name = "lollipop" + desc = "A simple artificially flavored sphere of sugar on a handle, colloquially known as a sucker. Allegedly one is born every minute. Make sure to unwrap it, genius." + type_butt = /obj/item/trash/lollibutt + icon_state = "lollipop" + item_state = "lollipop" + wrapped = TRUE + +/obj/item/clothing/mask/chewable/candy/lolli/process() + chew() + if(chewtime < 1) + spitout(0) + +/obj/item/clothing/mask/chewable/candy/lolli/Initialize() + . = ..() + reagents.add_reagent(pick("banana","berryjuice","grapejuice","lemonjuice","limejuice","orangejuice","watermelonjuice"),20) + color = reagents.get_color() + update_icon() + diff --git a/code/game/objects/items/weapons/cigs_lighters.dm b/code/game/objects/items/weapons/cigs_lighters.dm index 1bd2a4eac8d..1f7149e893e 100644 --- a/code/game/objects/items/weapons/cigs_lighters.dm +++ b/code/game/objects/items/weapons/cigs_lighters.dm @@ -488,6 +488,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM /obj/item/weapon/rollingpaper name = "rolling paper" desc = "A small, thin piece of easily flammable paper, commonly used for rolling and smoking various dried plants." + description_fluff = "The legalization of certain substances propelled the sale of rolling papers through the roof. Now almost every Trans-stellar produces a variety, often of questionable quality." icon = 'icons/obj/cigarettes.dmi' icon_state = "cig paper" @@ -513,6 +514,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM /obj/item/weapon/flame/lighter name = "cheap lighter" desc = "A cheap-as-free lighter." + description_fluff = "The 'hand-made in Altair' sticker underneath is a charming way of saying 'Made with prison labour'. It's no wonder the company can sell these things so cheap." icon = 'icons/obj/items.dmi' icon_state = "lighter-g" item_state = "lighter-g" @@ -527,6 +529,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM /obj/item/weapon/flame/lighter/zippo name = "\improper Zippo lighter" desc = "The zippo." + description_fluff = "Still going after all these years." icon = 'icons/obj/zippo.dmi' icon_state = "zippo" item_state = "zippo" diff --git a/code/game/objects/items/weapons/circuitboards/machinery/fluidpump.dm b/code/game/objects/items/weapons/circuitboards/machinery/fluidpump.dm new file mode 100644 index 00000000000..3646d7311a0 --- /dev/null +++ b/code/game/objects/items/weapons/circuitboards/machinery/fluidpump.dm @@ -0,0 +1,14 @@ + +#ifndef T_BOARD +#error T_BOARD macro is not defined but we need it! +#endif + +/obj/item/weapon/circuitboard/fluidpump + name = T_BOARD("fluid pump") + build_path = /obj/machinery/pump + board_type = new /datum/frame/frame_types/machine + origin_tech = list(TECH_DATA = 1) + req_components = list( + /obj/item/weapon/stock_parts/matter_bin = 2, + /obj/item/weapon/stock_parts/motor = 2, + /obj/item/weapon/stock_parts/manipulator = 1) diff --git a/code/game/objects/items/weapons/ecigs.dm b/code/game/objects/items/weapons/ecigs.dm index 29ae810f9f5..18e6062dbaa 100644 --- a/code/game/objects/items/weapons/ecigs.dm +++ b/code/game/objects/items/weapons/ecigs.dm @@ -1,6 +1,6 @@ /obj/item/clothing/mask/smokable/ecig name = "electronic cigarette" - desc = "Device with modern approach to smoking." + desc = "For the modern approach to smoking." icon = 'icons/obj/ecig.dmi' var/active = 0 //var/obj/item/weapon/cell/ec_cell = /obj/item/weapon/cell/device @@ -24,6 +24,7 @@ /obj/item/clothing/mask/smokable/ecig/simple name = "simple electronic cigarette" desc = "A cheap Lucky 1337 electronic cigarette, styled like a traditional cigarette." + description_fluff = "Produced by the Ward-Takahashi Corporation on behalf of the Lucky Stars cigarette brand, the 1337 is the e-cig of choice for teenage wastrels across the core worlds. Due to a total lack of safety features, this model is banned on most interstellar flights." icon_state = "ccigoff" icon_off = "ccigoff" icon_empty = "ccigoff" @@ -32,6 +33,7 @@ /obj/item/clothing/mask/smokable/ecig/util name = "electronic cigarette" desc = "A popular utilitarian model electronic cigarette, the ONI-55. Comes in a variety of colors." + description_fluff = "Ward-Takahashi's flagship brand of e-cig is a popular fashion accessory in certain circles where open flames are prohibited. Custom casings are sold for almost as much as the device itself, and are practically impossible to DIY." icon_state = "ecigoff1" icon_off = "ecigoff1" icon_empty = "ecigoff1" @@ -43,6 +45,7 @@ /obj/item/clothing/mask/smokable/ecig/deluxe name = "deluxe electronic cigarette" desc = "A premium model eGavana MK3 electronic cigarette, shaped like a cigar." + description_fluff = "The eGavana is a product of Morpheus Cyberkinetics, and comes standard with additional jacks that allow cyborgs and positronics to experience a simulation of soothing artificial oil residues entering their lungs. It's a pretty good cig for meatbags, too." icon_state = "pcigoff1" icon_off = "pcigoff1" icon_empty = "pcigoff2" diff --git a/code/game/objects/items/weapons/gift_wrappaper.dm b/code/game/objects/items/weapons/gift_wrappaper.dm index 88d9b0ff5df..22abe36ab48 100644 --- a/code/game/objects/items/weapons/gift_wrappaper.dm +++ b/code/game/objects/items/weapons/gift_wrappaper.dm @@ -87,17 +87,17 @@ /obj/item/toy/crossbow, /obj/item/weapon/gun/projectile/revolver/capgun, /obj/item/toy/katana, - /obj/item/toy/prize/deathripley, - /obj/item/toy/prize/durand, - /obj/item/toy/prize/fireripley, - /obj/item/toy/prize/gygax, - /obj/item/toy/prize/honk, - /obj/item/toy/prize/marauder, - /obj/item/toy/prize/mauler, - /obj/item/toy/prize/odysseus, - /obj/item/toy/prize/phazon, - /obj/item/toy/prize/ripley, - /obj/item/toy/prize/seraph, + /obj/item/toy/mecha/deathripley, + /obj/item/toy/mecha/durand, + /obj/item/toy/mecha/fireripley, + /obj/item/toy/mecha/gygax, + /obj/item/toy/mecha/honk, + /obj/item/toy/mecha/marauder, + /obj/item/toy/mecha/mauler, + /obj/item/toy/mecha/odysseus, + /obj/item/toy/mecha/phazon, + /obj/item/toy/mecha/ripley, + /obj/item/toy/mecha/seraph, /obj/item/toy/spinningtoy, /obj/item/toy/sword, /obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiadeus, diff --git a/code/game/objects/items/weapons/storage/boxes.dm b/code/game/objects/items/weapons/storage/boxes.dm index 96e4c87da31..5f5d87959f0 100644 --- a/code/game/objects/items/weapons/storage/boxes.dm +++ b/code/game/objects/items/weapons/storage/boxes.dm @@ -26,6 +26,7 @@ item_state = "syringe_kit" center_of_mass = list("x" = 13,"y" = 10) var/foldable = /obj/item/stack/material/cardboard // BubbleWrap - if set, can be folded (when empty) into a sheet of cardboard + var/trash = null // if set, can be crushed into a trash item when empty max_w_class = ITEMSIZE_SMALL max_storage_space = INVENTORY_BOX_SPACE use_sound = 'sound/items/storage/box.ogg' @@ -35,26 +36,37 @@ /obj/item/weapon/storage/box/attack_self(mob/user as mob) if(..()) return - //try to fold it. - if ( contents.len ) - return + //try to fold it + if(ispath(foldable)) + if (contents.len) + return + var/found = 0 + // Close any open UI windows first + for(var/mob/M in range(1)) + if (M.s_active == src) + close(M) + if (M == user) + found = 1 + if (!found) // User is too far away + return + // Now make the cardboard + to_chat(user, "You fold [src] flat.") + playsound(src, 'sound/items/storage/boxfold.ogg', 30, 1) + new foldable(get_turf(src)) + qdel(src) + + //try to crush it + if(ispath(trash)) + if(contents.len && user.a_intent == I_HURT) // only crumple with things inside on harmintent. + user.visible_message(SPAN_DANGER("You crush \the [src], spilling its contents everywhere!"), SPAN_DANGER("[user] crushes \the [src], spilling its contents everywhere!")) + spill() + else + to_chat(user, SPAN_NOTICE("You crumple up \the [src].")) //make trash + playsound(src.loc, 'sound/items/drop/wrapper.ogg', 30, 1) + var/obj/item/trash = new src.trash() + qdel(src) + user.put_in_hands(trash) - if ( !ispath(foldable) ) - return - var/found = 0 - // Close any open UI windows first - for(var/mob/M in range(1)) - if (M.s_active == src) - close(M) - if ( M == user ) - found = 1 - if ( !found ) // User is too far away - return - // Now make the cardboard - to_chat(user, "You fold [src] flat.") - playsound(src, 'sound/items/storage/boxfold.ogg', 30, 1) - new foldable(get_turf(src)) - qdel(src) /obj/item/weapon/storage/box/survival name = "emergency supply box" diff --git a/code/game/objects/items/weapons/storage/fancy.dm b/code/game/objects/items/weapons/storage/fancy.dm index f1003c451bf..8f60a9f706c 100644 --- a/code/game/objects/items/weapons/storage/fancy.dm +++ b/code/game/objects/items/weapons/storage/fancy.dm @@ -265,14 +265,16 @@ /obj/item/weapon/storage/fancy/cigarettes/dromedaryco name = "\improper DromedaryCo packet" - desc = "A packet of six imported DromedaryCo cancer sticks. A label on the packaging reads, \"Wouldn't a slow death make a change?\"" + desc = "A packet of six Earth-export DromedaryCo cancer sticks. A label on the packaging reads, \"Wouldn't a slow death make a change?\"" + description_fluff = "DromedaryCo is one of Sol's oldest cigarette brands, and takes pride in having sourced tobcacco from the same Indian plantations since 2044. Popular with those willing to pay extra for a little nostalgia." icon_state = "Dpacket" brand = "\improper Dromedary Co. cigarette" /obj/item/weapon/storage/fancy/cigarettes/killthroat name = "\improper AcmeCo packet" - desc = "A packet of six AcmeCo cigarettes. For those who somehow want to obtain the record for the most amount of cancerous tumors." - icon_state = "Bpacket" + desc = "A packet of six AcmeCo cigarettes. For those who want to obtain a record for the most cancerous tumors on a budget." + description_fluff = "Available anywhere people breathe and want to breathe less, AcmeCo is the cheapest, most widespread cigarette brand in the galaxy. They taste like trash, but when you're keeping them inside your jumpsuit on a 16 hour shift, you're probably not too concerned with flavour." + icon_state = "Apacket" brand = "\improper Acme Co. cigarette" // New exciting ways to kill your lungs! - Earthcrusher // @@ -280,36 +282,41 @@ /obj/item/weapon/storage/fancy/cigarettes/luckystars name = "\improper pack of Lucky Stars" desc = "A mellow blend made from synthetic, pod-grown tobacco. The commercial jingle is guaranteed to get stuck in your head." + description_fluff = "Lucky Stars are some of the most prolific advertisers in the business, with Gilthari Exports plastering the name and slogan on everything from workplace safety videos to racing bikes. 'Feel the gentle warmth of your Lucky Star'." icon_state = "LSpacket" brand = "\improper Lucky Star" /obj/item/weapon/storage/fancy/cigarettes/jerichos name = "\improper pack of Jerichos" - desc = "Typically seen dangling from the lips of Martian soldiers and border world hustlers. Tastes like hickory smoke, feels like warm liquid death down your lungs." + desc = "Typically seen dangling from the lips of Fleet veterans and border world hustlers. Tastes like hickory smoke, feels like warm liquid death down your lungs." + description_fluff = "The Jericho brand has carefully cultivated its 'rugged' image ever since its completely accidental association with the SolGov-Hegemony war due to their sizable corporate presence in the region. Prior to the war, Jerichos were considered the realm of drunks and sad divorcees." icon_state = "Jpacket" brand = "\improper Jericho" /obj/item/weapon/storage/fancy/cigarettes/menthols name = "\improper pack of Temperamento Menthols" - desc = "With a sharp and natural organic menthol flavor, these Temperamentos are a favorite of NDV crews. Hardly anyone knows they make 'em in non-menthol!" + desc = "With a sharp and natural organic menthol flavor, these Temperamentos are a favorite of science vessel crews. Hardly anyone knows they make 'em in non-menthol!" + description_fluff = "Temperamento Menthols are a product of the Aether Atmospherics and Recycling company, and the 'smooth' menthol taste is rumoured to be the chemical by-product of some far more profitable industrial synthesis." icon_state = "TMpacket" brand = "\improper Temperamento Menthol" /obj/item/weapon/storage/fancy/cigarettes/carcinomas name = "\improper pack of Carcinoma Angels" - desc = "This unknown brand was slated for the chopping block, until they were publicly endorsed by an old Earthling gonzo journalist. The rest is history. They sell a variety for cats, too." - icon_state = "CApacket" + desc = "This previously unknown brand was slated for the chopping block, until they were publicly endorsed by an old Earthling gonzo journalist. The rest is history. They sell a variety for cats, too." + description_fluff = "The bitter taste of a Carcinoma Angel is considered desirable by many equally bitter wash-ups who consider themselves to be 'hard-boiled'. The smell is practically inseparable from urban security offices, and old men with exonet radio shows." brand = "\improper Carcinoma Angel" /obj/item/weapon/storage/fancy/cigarettes/professionals name = "\improper pack of Professional 120s" desc = "Let's face it - if you're smoking these, you're either trying to look upper-class or you're 80 years old. That's the only excuse. They are, however, very good quality." + description_fluff = "Grown and rolled in a meticulously maintained biosphere orbitting Love, P120 tobacco is marketed as 'probably the best in the galaxy'. The premium price point, and the fact that the vast majority of consumers couldn't really tell the difference between this and the next leading brand." icon_state = "P100packet" brand = "\improper Professional 120" /obj/item/weapon/storage/fancy/cigar name = "cigar case" desc = "A case for holding your cigars when you are not smoking them." + description_fluff = "The tastefully engraved palm tree tells you that these 'Corona Grande' premium cigars are only sold on the luxury cruises and resorts of Oasis, though ten separate companies produce them for that purpose galaxy-wide. The standard is however very high." icon_state = "cigarcase" icon = 'icons/obj/cigarettes.dmi' w_class = ITEMSIZE_TINY diff --git a/code/game/objects/items/weapons/tape.dm b/code/game/objects/items/weapons/tape.dm index 90b62ed07b7..b24f24d2feb 100644 --- a/code/game/objects/items/weapons/tape.dm +++ b/code/game/objects/items/weapons/tape.dm @@ -8,19 +8,21 @@ toolspeed = 2 //It is now used in surgery as a not awful, but probably dangerous option, due to speed. +/obj/item/weapon/tape_roll/proc/can_place(var/mob/living/carbon/human/H, var/mob/user) + if(istype(user, /mob/living/silicon/robot) || user == H) + return TRUE + + for (var/obj/item/weapon/grab/G in H.grabbed_by) + if (G.loc == user && G.state >= GRAB_AGGRESSIVE) + return TRUE + + return FALSE + /obj/item/weapon/tape_roll/attack(var/mob/living/carbon/human/H, var/mob/user) if(istype(H)) if(user.a_intent == I_HELP) return - var/can_place = 0 - if(istype(user, /mob/living/silicon/robot)) - can_place = 1 - else - for (var/obj/item/weapon/grab/G in H.grabbed_by) - if (G.loc == user && G.state >= GRAB_AGGRESSIVE) - can_place = 1 - break - if(!can_place) + if(!can_place(H, user)) to_chat(user, "You need to have a firm grip on [H] before you can use \the [src]!") return else @@ -43,16 +45,7 @@ if(!do_after(user, 30)) return - can_place = 0 - - if(istype(user, /mob/living/silicon/robot)) - can_place = 1 - else - for (var/obj/item/weapon/grab/G in H.grabbed_by) - if (G.loc == user && G.state >= GRAB_AGGRESSIVE) - can_place = 1 - - if(!can_place) + if(!can_place(H, user)) return if(!H || !src || !H.organs_by_name[BP_HEAD] || !H.has_eyes() || H.glasses || (H.head && (H.head.body_parts_covered & FACE))) @@ -81,16 +74,7 @@ if(!do_after(user, 30)) return - can_place = 0 - - if(istype(user, /mob/living/silicon/robot)) - can_place = 1 - else - for (var/obj/item/weapon/grab/G in H.grabbed_by) - if (G.loc == user && G.state >= GRAB_AGGRESSIVE) - can_place = 1 - - if(!can_place) + if(!can_place(H, user)) return if(!H || !src || !H.organs_by_name[BP_HEAD] || !H.check_has_mouth() || (H.head && (H.head.body_parts_covered & FACE))) @@ -103,16 +87,7 @@ playsound(src, 'sound/effects/tape.ogg',25) else if(user.zone_sel.selecting == "r_hand" || user.zone_sel.selecting == "l_hand") - can_place = 0 - - if(istype(user, /mob/living/silicon/robot)) - can_place = 1 - else - for (var/obj/item/weapon/grab/G in H.grabbed_by) - if (G.loc == user && G.state >= GRAB_AGGRESSIVE) - can_place = 1 - - if(!can_place) + if(!can_place(H, user)) return var/obj/item/weapon/handcuffs/cable/tape/T = new(user) diff --git a/code/game/objects/random/maintenance.dm b/code/game/objects/random/maintenance.dm index 37dcca83197..155a9abad09 100644 --- a/code/game/objects/random/maintenance.dm +++ b/code/game/objects/random/maintenance.dm @@ -101,8 +101,8 @@ something, make sure it's not in one of the other lists.*/ prob(1);/obj/item/clothing/under/tactical, prob(3);/obj/item/clothing/accessory/storage/webbing, prob(3);/obj/item/weapon/camera_assembly, - prob(4);/obj/item/weapon/caution, - prob(3);/obj/item/weapon/caution/cone, + prob(4);/obj/item/clothing/suit/caution, + prob(3);/obj/item/clothing/head/cone, prob(1);/obj/item/weapon/card/emag_broken, prob(2);/obj/item/device/camera, prob(3);/obj/item/device/pda, diff --git a/code/game/objects/random/misc.dm b/code/game/objects/random/misc.dm index 73796038e1b..df8ffc645c0 100644 --- a/code/game/objects/random/misc.dm +++ b/code/game/objects/random/misc.dm @@ -520,17 +520,17 @@ /obj/item/weapon/reagent_containers/spray/waterflower, /obj/item/toy/eight_ball, /obj/item/toy/eight_ball/conch, - /obj/item/toy/prize/ripley, - /obj/item/toy/prize/fireripley, - /obj/item/toy/prize/deathripley, - /obj/item/toy/prize/gygax, - /obj/item/toy/prize/durand, - /obj/item/toy/prize/honk, - /obj/item/toy/prize/marauder, - /obj/item/toy/prize/seraph, - /obj/item/toy/prize/mauler, - /obj/item/toy/prize/odysseus, - /obj/item/toy/prize/phazon) + /obj/item/toy/mecha/ripley, + /obj/item/toy/mecha/fireripley, + /obj/item/toy/mecha/deathripley, + /obj/item/toy/mecha/gygax, + /obj/item/toy/mecha/durand, + /obj/item/toy/mecha/honk, + /obj/item/toy/mecha/marauder, + /obj/item/toy/mecha/seraph, + /obj/item/toy/mecha/mauler, + /obj/item/toy/mecha/odysseus, + /obj/item/toy/mecha/phazon) /obj/random/mouseremains name = "random mouseremains" diff --git a/code/game/objects/structures/crates_lockers/closets/job_closets.dm b/code/game/objects/structures/crates_lockers/closets/job_closets.dm index 72a3d29a07f..4f73d4151cd 100644 --- a/code/game/objects/structures/crates_lockers/closets/job_closets.dm +++ b/code/game/objects/structures/crates_lockers/closets/job_closets.dm @@ -64,7 +64,7 @@ /obj/item/clothing/head/soft/purple, /obj/item/clothing/head/beret/purple, /obj/item/device/flashlight, - /obj/item/weapon/caution = 4, + /obj/item/clothing/suit/caution = 4, /obj/item/device/lightreplacer, /obj/item/weapon/storage/bag/trash, /obj/item/weapon/storage/belt/janitor, diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm index 6223061ed88..c17085bec1c 100644 --- a/code/game/objects/structures/crates_lockers/crates.dm +++ b/code/game/objects/structures/crates_lockers/crates.dm @@ -401,8 +401,8 @@ desc = "A crate emblazoned with the NanoThreads Garments livery, a subsidary of the NanoTrasen Corporation." closet_appearance = /decl/closet_appearance/crate/nanotrasenclothing -/obj/structure/closet/crate/nanocare - desc = "A crate emblazoned with the NanoCare Medical livery, a subsidary of the NanoTrasen Corporation." +/obj/structure/closet/crate/nanomed + desc = "A crate emblazoned with the NanoMed Medical livery, a subsidary of the NanoTrasen Corporation." closet_appearance = /decl/closet_appearance/crate/nanotrasenmedical /obj/structure/closet/crate/oculum @@ -516,8 +516,8 @@ desc = "A secure crate emblazoned with the standard NanoTrasen livery." closet_appearance = /decl/closet_appearance/crate/secure/nanotrasen -/obj/structure/closet/crate/secure/nanocare - desc = "A secure crate emblazoned with the NanoCare Medical livery, a subsidary of the NanoTrasen Corporation." +/obj/structure/closet/crate/secure/nanomed + desc = "A secure crate emblazoned with the NanoMed Medical livery, a subsidary of the NanoTrasen Corporation." closet_appearance = /decl/closet_appearance/crate/secure/nanotrasenmedical /obj/structure/closet/crate/secure/scg diff --git a/code/game/objects/structures/janicart.dm b/code/game/objects/structures/janicart.dm index d14efeea5b5..de07aa8de8f 100644 --- a/code/game/objects/structures/janicart.dm +++ b/code/game/objects/structures/janicart.dm @@ -93,7 +93,7 @@ GLOBAL_LIST_BOILERPLATE(all_janitorial_carts, /obj/structure/janitorialcart) to_chat(user, "You put [I] into [src].") return 1 - else if(istype(I, /obj/item/weapon/caution)) + else if(istype(I, /obj/item/clothing/suit/caution)) if(signs < 4) user.unEquip(I, 0, src) signs++ @@ -192,7 +192,7 @@ GLOBAL_LIST_BOILERPLATE(all_janitorial_carts, /obj/structure/janitorialcart) myreplacer = null if("sign") if(signs) - var/obj/item/weapon/caution/Sign = locate() in src + var/obj/item/clothing/suit/caution/Sign = locate() in src if(Sign) user.put_in_hands(Sign) to_chat(user, "You take \a [Sign] from [src].") @@ -258,7 +258,7 @@ GLOBAL_LIST_BOILERPLATE(all_janitorial_carts, /obj/structure/janitorialcart) mybucket = null if (signs) - for (var/obj/item/weapon/caution/Sign in src) + for (var/obj/item/clothing/suit/caution/Sign in src) if (prob(min((chance*2),100))) signs-- Sign.forceMove(dropspot) diff --git a/code/game/objects/structures/loot_piles.dm b/code/game/objects/structures/loot_piles.dm index b11f7aa36c4..ac43fa112cc 100644 --- a/code/game/objects/structures/loot_piles.dm +++ b/code/game/objects/structures/loot_piles.dm @@ -192,8 +192,8 @@ Loot piles can be depleted, if loot_depleted is turned on. Note that players wh /obj/item/weapon/spacecash/c10, /obj/item/weapon/spacecash/c20, /obj/item/weapon/camera_assembly, - /obj/item/weapon/caution, - /obj/item/weapon/caution/cone, + /obj/item/clothing/suit/caution, + /obj/item/clothing/head/cone, /obj/item/weapon/card/emag_broken, /obj/item/device/camera, /obj/item/device/pda, @@ -227,8 +227,10 @@ Loot piles can be depleted, if loot_depleted is turned on. Note that players wh /obj/item/trash/candle, /obj/item/trash/candy, /obj/item/trash/candy/proteinbar, + /obj/item/trash/candy/gums, /obj/item/trash/cheesie, /obj/item/trash/chips, + /obj/item/trash/chips/bbq, /obj/item/trash/liquidfood, /obj/item/trash/pistachios, /obj/item/trash/plate, @@ -239,6 +241,7 @@ Loot piles can be depleted, if loot_depleted is turned on. Note that players wh /obj/item/trash/sosjerky, /obj/item/trash/syndi_cakes, /obj/item/trash/tastybread, + /obj/item/trash/coffee, /obj/item/trash/tray, /obj/item/trash/unajerky, /obj/item/trash/waffles, diff --git a/code/game/objects/structures/trash_pile_vr.dm b/code/game/objects/structures/trash_pile_vr.dm index 8dcf567962e..f6c11bb51cb 100644 --- a/code/game/objects/structures/trash_pile_vr.dm +++ b/code/game/objects/structures/trash_pile_vr.dm @@ -141,7 +141,7 @@ prob(4);/obj/item/clothing/shoes/leather, prob(4);/obj/item/clothing/suit/storage/hazardvest, prob(4);/obj/item/clothing/under/color/grey, - prob(4);/obj/item/weapon/caution, + prob(4);/obj/item/clothing/suit/caution, prob(4);/obj/item/weapon/cell, prob(4);/obj/item/weapon/cell/device, prob(4);/obj/item/weapon/reagent_containers/food/snacks/liquidfood, @@ -164,7 +164,7 @@ prob(3);/obj/item/device/pda, prob(3);/obj/item/device/radio/headset, prob(3);/obj/item/weapon/camera_assembly, - prob(3);/obj/item/weapon/caution/cone, + prob(3);/obj/item/clothing/head/cone, prob(3);/obj/item/weapon/cell/high, prob(3);/obj/item/weapon/spacecash/c10, prob(3);/obj/item/weapon/spacecash/c20, diff --git a/code/game/sound.dm b/code/game/sound.dm index c5846c39eb6..903534547db 100644 --- a/code/game/sound.dm +++ b/code/game/sound.dm @@ -1,4 +1,4 @@ -/proc/playsound(atom/source, soundin, vol as num, vary, extrarange as num, falloff, is_global, frequency = null, channel = 0, pressure_affected = TRUE, ignore_walls = TRUE, preference = null) +/proc/playsound(atom/source, soundin, vol as num, vary, extrarange as num, falloff, is_global, frequency = null, channel = 0, pressure_affected = TRUE, ignore_walls = TRUE, preference = null, volume_channel = null) if(isarea(source)) throw EXCEPTION("playsound(): source is an area") return @@ -23,9 +23,9 @@ if(distance <= maxdistance) if(T && T.z == turf_source.z) - M.playsound_local(turf_source, soundin, vol, vary, frequency, falloff, is_global, channel, pressure_affected, S, preference) + M.playsound_local(turf_source, soundin, vol, vary, frequency, falloff, is_global, channel, pressure_affected, S, preference, volume_channel) -/mob/proc/playsound_local(turf/turf_source, soundin, vol as num, vary, frequency, falloff, is_global, channel = 0, pressure_affected = TRUE, sound/S, preference) +/mob/proc/playsound_local(turf/turf_source, soundin, vol as num, vary, frequency, falloff, is_global, channel = 0, pressure_affected = TRUE, sound/S, preference, volume_channel = null) if(!client || ear_deaf > 0) return if(preference && !client.is_preference_enabled(preference)) @@ -36,6 +36,11 @@ S.wait = 0 //No queue S.channel = channel || open_sound_channel() + + // I'm not sure if you can modify S.volume, but I'd rather not try to find out what + // horrible things lurk in BYOND's internals, so we're just gonna do vol *= + vol *= client.get_preference_volume_channel(volume_channel) + vol *= client.get_preference_volume_channel(VOLUME_CHANNEL_MASTER) S.volume = vol if(vary) diff --git a/code/game/turfs/simulated/outdoors/outdoors_attackby.dm b/code/game/turfs/simulated/outdoors/outdoors_attackby.dm index e38f601b8b6..a59676834ff 100644 --- a/code/game/turfs/simulated/outdoors/outdoors_attackby.dm +++ b/code/game/turfs/simulated/outdoors/outdoors_attackby.dm @@ -8,5 +8,8 @@ new /obj/item/weapon/reagent_containers/food/snacks/worm(src) else to_chat(user, "You decide to not finish digging in \the [src].") + else if(istype(S, /obj/item/stack/tile/floor)) + ChangeTurf(/turf/simulated/floor, preserve_outdoors = TRUE) + return else ..() \ No newline at end of file diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 626ee68c71f..4bc205c9339 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -49,6 +49,7 @@ /turf/Destroy() . = QDEL_HINT_IWILLGC + cleanbot_reserved_turfs -= src ..() /turf/ex_act(severity) diff --git a/code/game/world.dm b/code/game/world.dm index 628a12f2e59..931e0fe516b 100644 --- a/code/game/world.dm +++ b/code/game/world.dm @@ -108,7 +108,7 @@ var/world_topic_spam_protect_time = world.timeofday s["version"] = game_version s["mode"] = master_mode s["respawn"] = config.abandon_allowed - s["persistance"] = config.persistence_enabled + s["persistance"] = config.persistence_disabled s["enter"] = config.enter_allowed s["vote"] = config.allow_vote_mode s["ai"] = config.allow_ai @@ -529,7 +529,9 @@ var/world_topic_spam_protect_time = world.timeofday features += config.abandon_allowed ? "respawn" : "no respawn" - features += config.persistence_enabled ? "persistence enabled" : "persistence disabled" + features += config.persistence_disabled ? "persistence disabled" : "persistence enabled" + + features += config.persistence_ignore_mapload ? "persistence mapload disabled" : "persistence mapload enabled" if (config && config.allow_vote_mode) features += "vote" diff --git a/code/global.dm b/code/global.dm index 9e6b6c555bb..48628c5e020 100644 --- a/code/global.dm +++ b/code/global.dm @@ -130,9 +130,6 @@ var/custom_event_msg = null var/DBConnection/dbcon = new() // Feedback database (New database) var/DBConnection/dbcon_old = new() // /tg/station database (Old database) -- see the files in the SQL folder for information on what goes where. -// Reference list for disposal sort junctions. Filled up by sorting junction's New() -/var/list/tagger_locations = list() - // Added for Xenoarchaeology, might be useful for other stuff. var/global/list/alphabet_uppercase = list("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z") diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index b8abe8619eb..c0bcd0f1011 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -937,15 +937,29 @@ var/datum/announcement/minor/admin_min_announcer = new set category = "Server" set desc="Whether persistent data will be saved from now on." set name="Toggle Persistent Data" - config.persistence_enabled = !(config.persistence_enabled) - if(config.persistence_enabled) + config.persistence_disabled = !(config.persistence_disabled) + if(!config.persistence_disabled) to_world("Persistence is now enabled..") else to_world("Persistence is no longer enabled.") - message_admins("[key_name_admin(usr)] toggled persistence to [config.persistence_enabled ? "On" : "Off"].", 1) - log_admin("[key_name(usr)] toggled persistence to [config.persistence_enabled ? "On" : "Off"].") + message_admins("[key_name_admin(usr)] toggled persistence to [config.persistence_disabled ? "Off" : "On"].", 1) + log_admin("[key_name(usr)] toggled persistence to [config.persistence_disabled ? "Off" : "On"].") world.update_status() feedback_add_details("admin_verb","TPD") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + +/datum/admins/proc/togglemaploadpersistence() + set category = "Server" + set desc="Whether mapload persistent data will be saved from now on." + set name="Toggle Mapload Persistent Data" + config.persistence_ignore_mapload = !(config.persistence_ignore_mapload) + if(!config.persistence_ignore_mapload) + to_world("Persistence is now enabled..") + else + to_world("Persistence is no longer enabled.") + message_admins("[key_name_admin(usr)] toggled persistence to [config.persistence_ignore_mapload ? "Off" : "On"].", 1) + log_admin("[key_name(usr)] toggled persistence to [config.persistence_ignore_mapload ? "Off" : "On"].") + world.update_status() + feedback_add_details("admin_verb","TMPD") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /datum/admins/proc/toggle_aliens() set category = "Server" diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm index 0262e643e42..e294514b914 100644 --- a/code/modules/admin/verbs/adminhelp.dm +++ b/code/modules/admin/verbs/adminhelp.dm @@ -183,7 +183,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new) var/admin_number_present = send2irc_adminless_only(initiator_ckey, name) log_admin("Ticket #[id]: [key_name(initiator)]: [name] - heard by [admin_number_present] non-AFK admins who have +BAN.") if(admin_number_present <= 0) - to_chat(C, "No active admins are online, your adminhelp was sent to the admin irc.") + to_chat(C, "No active admins are online, your adminhelp was sent to the admin discord.") //VOREStation Edit GLOB.ahelp_tickets.active_tickets += src /datum/admin_help/Destroy() diff --git a/code/modules/admin/verbs/adminpm.dm b/code/modules/admin/verbs/adminpm.dm index 7f7ecff2ac8..706e5a4274a 100644 --- a/code/modules/admin/verbs/adminpm.dm +++ b/code/modules/admin/verbs/adminpm.dm @@ -32,6 +32,8 @@ else targets["(No Mob) - [T]"] = T var/target = input(src,"To whom shall we send a message?","Admin PM",null) as null|anything in sortList(targets) + if(!target) //Admin canceled + return cmd_admin_pm(targets[target],null) feedback_add_details("admin_verb","Admin PM") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! diff --git a/code/modules/asset_cache/asset_cache_client.dm b/code/modules/asset_cache/asset_cache_client.dm index 0f51520f13a..e25b9969863 100644 --- a/code/modules/asset_cache/asset_cache_client.dm +++ b/code/modules/asset_cache/asset_cache_client.dm @@ -17,6 +17,10 @@ CRASH("invalid asset_cache_preload_data, no jsonendmarker")*/ //var/json = html_decode(copytext(data, 1, jsonend)) var/json = data + + // This is a stupid workaround to BYOND injecting this pngfix mess into IE7 clients browse() + json = replacetext(json, "", "") + var/list/preloaded_assets = json_decode(json) for (var/preloaded_asset in preloaded_assets) diff --git a/code/modules/client/client defines.dm b/code/modules/client/client defines.dm index e11ff9e4f7a..dfa181ee910 100644 --- a/code/modules/client/client defines.dm +++ b/code/modules/client/client defines.dm @@ -24,6 +24,7 @@ var/time_died_as_mouse = null //when the client last died as a mouse var/datum/tooltip/tooltips = null var/datum/chatOutput/chatOutput + var/datum/volume_panel/volume_panel = null // Initialized by /client/verb/volume_panel() var/chatOutputLoadedAt var/adminhelped = 0 diff --git a/code/modules/client/preference_setup/global/01_ui.dm b/code/modules/client/preference_setup/global/01_ui.dm index 9b93f13c5a4..fc1c0a52f96 100644 --- a/code/modules/client/preference_setup/global/01_ui.dm +++ b/code/modules/client/preference_setup/global/01_ui.dm @@ -35,8 +35,8 @@ pref.client_fps = sanitize_integer(pref.client_fps, 0, MAX_CLIENT_FPS, initial(pref.client_fps)) pref.ambience_freq = sanitize_integer(pref.ambience_freq, 0, 60, initial(pref.ambience_freq)) // No more than once per hour. pref.ambience_chance = sanitize_integer(pref.ambience_chance, 0, 100, initial(pref.ambience_chance)) // 0-100 range. - pref.tgui_fancy = sanitize_integer(pref.tgui_fancy, 0, 1, initial(pref.tgui_fancy)) - pref.tgui_lock = sanitize_integer(pref.tgui_lock, 0, 1, initial(pref.tgui_lock)) + pref.tgui_fancy = sanitize_integer(pref.tgui_fancy, 0, 1, initial(pref.tgui_fancy)) + pref.tgui_lock = sanitize_integer(pref.tgui_lock, 0, 1, initial(pref.tgui_lock)) /datum/category_item/player_setup_item/player_global/ui/content(var/mob/user) . = "UI Style: [pref.UI_style]
" diff --git a/code/modules/client/preference_setup/loadout/loadout_eyes_vr.dm b/code/modules/client/preference_setup/loadout/loadout_eyes_vr.dm index 276554554f9..baa19d0aeca 100644 --- a/code/modules/client/preference_setup/loadout/loadout_eyes_vr.dm +++ b/code/modules/client/preference_setup/loadout/loadout_eyes_vr.dm @@ -17,6 +17,11 @@ display_name = "AR-S glasses (Sec)" path = /obj/item/clothing/glasses/omnihud/sec allowed_roles = list("Security Officer","Head of Security","Warden","Detective") + +/datum/gear/eyes/arglasses/sci + display_name = "AR-R glasses (Sci)" + path = /obj/item/clothing/glasses/omnihud/rnd + allowed_roles = list("Research Director","Scientist","Xenobiologist","Roboticist") /datum/gear/eyes/arglasses/eng display_name = "AR-E glasses (Eng)" @@ -42,6 +47,10 @@ display_name = "science goggles (no overlay)" path = /obj/item/clothing/glasses/fluff/science_proper +/datum/gear/eyes/meson/retinal + display_name = "retinal projector, meson (Eng, Sci, Mining)" + path = /obj/item/clothing/glasses/omnihud/eng/meson + /datum/gear/eyes/security/secpatch display_name = "Security HUDpatch" path = /obj/item/clothing/glasses/hud/security/eyepatch 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 f8bffbbd90d..6cbe17bce3b 100644 --- a/code/modules/client/preference_setup/loadout/loadout_fluffitems_vr.dm +++ b/code/modules/client/preference_setup/loadout/loadout_fluffitems_vr.dm @@ -303,6 +303,14 @@ character_name = list("Yikatihaki") allowed_roles = list("Explorer") +/datum/gear/fluff/suit/storage/flintlock + path = /obj/item/clothing/suit/storage/flintlock + display_name = "Flintlock's jacket" + slot = slot_wear_suit + ckeywhitelist = list("flintlockdafox") + character_name = list("Flintlock Sharpsman") + + // G CKEYS // H CKEYS diff --git a/code/modules/client/preference_setup/loadout/loadout_xeno.dm b/code/modules/client/preference_setup/loadout/loadout_xeno.dm index a7669a837fa..2cad142833e 100644 --- a/code/modules/client/preference_setup/loadout/loadout_xeno.dm +++ b/code/modules/client/preference_setup/loadout/loadout_xeno.dm @@ -134,11 +134,6 @@ cloaks[initial(cloak_type.name)] = cloak_type gear_tweaks += new/datum/gear_tweak/path(sortAssoc(cloaks)) -/datum/gear/mask/ipc_monitor - display_name = "display monitor (Full Body Prosthetic)" - path = /obj/item/clothing/mask/monitor - sort_category = "Xenowear" - /datum/gear/uniform/harness display_name = "gear harness (Full Body Prosthetic, Diona)" path = /obj/item/clothing/under/harness diff --git a/code/modules/client/preference_setup/occupation/occupation.dm b/code/modules/client/preference_setup/occupation/occupation.dm index 59229c1d70d..70d26a40603 100644 --- a/code/modules/client/preference_setup/occupation/occupation.dm +++ b/code/modules/client/preference_setup/occupation/occupation.dm @@ -76,6 +76,7 @@ . = list() . += "
" . += "Choose occupation chances
Unavailable occupations are crossed out.
" + . += "" . += "
" // Table within a table for alignment, also allows you to easily add more columns. . += "" var/index = -1 @@ -162,7 +163,32 @@ . += "" continue - if(pref.GetJobDepartment(job, 1) & job.flag) - . += " \[High]" - else if(pref.GetJobDepartment(job, 2) & job.flag) - . += " \[Medium]" - else if(pref.GetJobDepartment(job, 3) & job.flag) - . += " \[Low]" - else - . += " \[NEVER]" + . += " \[[prefLevelLabel]]" if(LAZYLEN(job.alt_titles)) . += "" . += "" @@ -222,8 +241,8 @@ return (pref.equip_preview_mob ? TOPIC_REFRESH_UPDATE_PREVIEW : TOPIC_REFRESH) else if(href_list["set_job"]) - if(SetJob(user, href_list["set_job"])) return (pref.equip_preview_mob ? TOPIC_REFRESH_UPDATE_PREVIEW : TOPIC_REFRESH) - + if(SetJob(user, href_list["set_job"], text2num(href_list["level"]))) + return (pref.equip_preview_mob ? TOPIC_REFRESH_UPDATE_PREVIEW : TOPIC_REFRESH) else if(href_list["job_info"]) var/rank = href_list["job_info"] @@ -272,7 +291,7 @@ if(job.title != new_title) pref.player_alt_titles[job.title] = new_title -/datum/category_item/player_setup_item/occupation/proc/SetJob(mob/user, role) +/datum/category_item/player_setup_item/occupation/proc/SetJob(mob/user, role, level) var/datum/job/job = job_master.GetJob(role) if(!job) return 0 @@ -284,77 +303,73 @@ pref.job_civilian_low |= job.flag return 1 - if(pref.GetJobDepartment(job, 1) & job.flag) - SetJobDepartment(job, 1) - else if(pref.GetJobDepartment(job, 2) & job.flag) - SetJobDepartment(job, 2) - else if(pref.GetJobDepartment(job, 3) & job.flag) - SetJobDepartment(job, 3) - else//job = Never - SetJobDepartment(job, 4) - + SetJobDepartment(job, level) return 1 +/datum/category_item/player_setup_item/occupation/proc/reset_jobhigh() + pref.job_civilian_med |= pref.job_civilian_high + pref.job_medsci_med |= pref.job_medsci_high + pref.job_engsec_med |= pref.job_engsec_high + pref.job_talon_med |= pref.job_talon_high //VOREStation Add + pref.job_civilian_high = 0 + pref.job_medsci_high = 0 + pref.job_engsec_high = 0 + pref.job_talon_high = 0 //VOREStation Add + +// Level is equal to the desired new level of the job. So for a value of 4, we want to disable the job. /datum/category_item/player_setup_item/occupation/proc/SetJobDepartment(var/datum/job/job, var/level) - if(!job || !level) return 0 - switch(level) - if(1)//Only one of these should ever be active at once so clear them all here - pref.job_civilian_high = 0 - pref.job_medsci_high = 0 - pref.job_engsec_high = 0 - pref.job_talon_high = 0 //VOREStation Add - return 1 - if(2)//Set current highs to med, then reset them - pref.job_civilian_med |= pref.job_civilian_high - pref.job_medsci_med |= pref.job_medsci_high - pref.job_engsec_med |= pref.job_engsec_high - pref.job_talon_med |= pref.job_talon_high //VOREStation Add - pref.job_civilian_high = 0 - pref.job_medsci_high = 0 - pref.job_engsec_high = 0 - pref.job_talon_high = 0 //VOREStation Add + if(!job || !level) + return 0 switch(job.department_flag) if(CIVILIAN) + pref.job_civilian_low &= ~job.flag + pref.job_civilian_med &= ~job.flag + pref.job_civilian_high &= ~job.flag switch(level) - if(2) + if(1) + reset_jobhigh() pref.job_civilian_high = job.flag - pref.job_civilian_med &= ~job.flag - if(3) + if(2) pref.job_civilian_med |= job.flag - pref.job_civilian_low &= ~job.flag - else + if(3) pref.job_civilian_low |= job.flag if(MEDSCI) + pref.job_medsci_low &= ~job.flag + pref.job_medsci_med &= ~job.flag + pref.job_medsci_high &= ~job.flag switch(level) - if(2) + if(1) + reset_jobhigh() pref.job_medsci_high = job.flag - pref.job_medsci_med &= ~job.flag - if(3) + if(2) pref.job_medsci_med |= job.flag - pref.job_medsci_low &= ~job.flag - else + if(3) pref.job_medsci_low |= job.flag if(ENGSEC) + pref.job_engsec_low &= ~job.flag + pref.job_engsec_med &= ~job.flag + pref.job_engsec_high &= ~job.flag switch(level) - if(2) + if(1) + reset_jobhigh() pref.job_engsec_high = job.flag - pref.job_engsec_med &= ~job.flag - if(3) + if(2) pref.job_engsec_med |= job.flag - pref.job_engsec_low &= ~job.flag - else + if(3) pref.job_engsec_low |= job.flag //VOREStation Add if(TALON) + pref.job_talon_low &= ~job.flag + pref.job_talon_med &= ~job.flag + pref.job_talon_high &= ~job.flag switch(level) - if(2) + if(1) + reset_jobhigh() pref.job_talon_high = job.flag - pref.job_talon_med &= ~job.flag - if(3) + if(2) pref.job_talon_med |= job.flag - pref.job_talon_low &= ~job.flag - else + if(3) pref.job_talon_low |= job.flag //VOREStation Add End diff --git a/code/modules/client/preference_setup/volume_sliders/01_volume.dm b/code/modules/client/preference_setup/volume_sliders/01_volume.dm new file mode 100644 index 00000000000..349d88318a1 --- /dev/null +++ b/code/modules/client/preference_setup/volume_sliders/01_volume.dm @@ -0,0 +1,106 @@ +/datum/category_group/player_setup_category/volume_sliders + name = "Sound" + sort_order = 7 + category_item_type = /datum/category_item/player_setup_item/volume_sliders + +/datum/category_item/player_setup_item/volume_sliders/volume + name = "General Volume" + sort_order = 1 + +/datum/category_item/player_setup_item/volume_sliders/volume/load_preferences(var/savefile/S) + S["volume_channels"] >> pref.volume_channels + +/datum/category_item/player_setup_item/volume_sliders/volume/save_preferences(var/savefile/S) + S["volume_channels"] << pref.volume_channels + +/datum/category_item/player_setup_item/volume_sliders/volume/sanitize_preferences() + if(isnull(pref.volume_channels)) + pref.volume_channels = list() + + for(var/channel in pref.volume_channels) + if(!(channel in GLOB.all_volume_channels)) + // Channel no longer exists, yeet + pref.volume_channels.Remove(channel) + + for(var/channel in GLOB.all_volume_channels) + if(!(channel in pref.volume_channels)) + pref.volume_channels["[channel]"] = 1 + else + pref.volume_channels["[channel]"] = clamp(pref.volume_channels["[channel]"], 0, 2) + +/datum/category_item/player_setup_item/volume_sliders/volume/content(var/mob/user) + . += "Volume Settings
" + for(var/channel in pref.volume_channels) + . += "[channel]: [pref.volume_channels[channel] * 100]%
" + . += "
" + +/datum/category_item/player_setup_item/volume_sliders/volume/OnTopic(var/href, var/list/href_list, var/mob/user) + if(href_list["change_volume"]) + if(CanUseTopic(user)) + var/channel = href_list["change_volume"] + if(!(channel in pref.volume_channels)) + pref.volume_channels["[channel]"] = 1 + var/value = input("Choose your volume for [channel] (0-200%)", "[channel] volume", (pref.volume_channels[channel] * 100)) + if(isnum(value)) + value = CLAMP(value, 0, 200) + pref.volume_channels["[channel]"] = (value / 100) + return TOPIC_REFRESH + return ..() + +/mob/proc/get_preference_volume_channel(volume_channel) + if(!client) + return 0 + return client.get_preference_volume_channel(volume_channel) + +/client/proc/get_preference_volume_channel(volume_channel) + if(!volume_channel || !prefs) + return 1 + if(!(volume_channel in prefs.volume_channels)) + prefs.volume_channels["[volume_channel]"] = 1 + return prefs.volume_channels["[volume_channel]"] + + +// Neat little volume adjuster thing in case you don't wanna touch preferences by hand you lazy fuck +/datum/volume_panel +/datum/volume_panel/tgui_state(mob/user) + return GLOB.tgui_always_state + +/datum/volume_panel/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "VolumePanel", "Volume Panel") + ui.open() + +/datum/volume_panel/tgui_data(mob/user) + if(!user.client || !user.client.prefs) + return list("error" = TRUE) + + var/list/data = ..() + data["volume_channels"] = user.client.prefs.volume_channels + return data + +/datum/volume_panel/tgui_act(action, params) + if(..()) + return TRUE + + if(!usr?.client?.prefs) + return TRUE + + var/datum/preferences/P = usr.client.prefs + switch(action) + if("adjust_volume") + var/channel = params["channel"] + if(channel in P.volume_channels) + P.volume_channels["[channel]"] = clamp(params["vol"], 0, 2) + SScharacter_setup.queue_preferences_save(P) + return TRUE + +/client/verb/volume_panel() + set name = "Volume Panel" + set category = "Preferences" + set desc = "Allows you to adjust volume levels on the fly." + + if(!volume_panel) + volume_panel = new(src) + + volume_panel.tgui_interact(mob) diff --git a/code/modules/client/preference_setup/global/05_media.dm b/code/modules/client/preference_setup/volume_sliders/02_media.dm similarity index 80% rename from code/modules/client/preference_setup/global/05_media.dm rename to code/modules/client/preference_setup/volume_sliders/02_media.dm index 7ae263d9ea1..97e42324a01 100644 --- a/code/modules/client/preference_setup/global/05_media.dm +++ b/code/modules/client/preference_setup/volume_sliders/02_media.dm @@ -2,23 +2,23 @@ var/media_volume = 1 var/media_player = 2 // 0 = VLC, 1 = WMP, 2 = HTML5, 3+ = unassigned -/datum/category_item/player_setup_item/player_global/media +/datum/category_item/player_setup_item/volume_sliders/media name = "Media" - sort_order = 5 + sort_order = 2 -/datum/category_item/player_setup_item/player_global/media/load_preferences(var/savefile/S) +/datum/category_item/player_setup_item/volume_sliders/media/load_preferences(var/savefile/S) S["media_volume"] >> pref.media_volume S["media_player"] >> pref.media_player -/datum/category_item/player_setup_item/player_global/media/save_preferences(var/savefile/S) +/datum/category_item/player_setup_item/volume_sliders/media/save_preferences(var/savefile/S) S["media_volume"] << pref.media_volume S["media_player"] << pref.media_player -/datum/category_item/player_setup_item/player_global/media/sanitize_preferences() +/datum/category_item/player_setup_item/volume_sliders/media/sanitize_preferences() pref.media_volume = isnum(pref.media_volume) ? CLAMP(pref.media_volume, 0, 1) : initial(pref.media_volume) pref.media_player = sanitize_inlist(pref.media_player, list(0, 1, 2), initial(pref.media_player)) -/datum/category_item/player_setup_item/player_global/media/content(var/mob/user) +/datum/category_item/player_setup_item/volume_sliders/media/content(var/mob/user) . += "Jukebox Volume:" . += "[round(pref.media_volume * 100)]%
" . += "Media Player Type: Depending on you operating system, one of these might work better. " @@ -30,7 +30,7 @@ . += (pref.media_player == 0) ? "VLC " : "VLC " . += "
" -/datum/category_item/player_setup_item/player_global/media/OnTopic(var/href, var/list/href_list, var/mob/user) +/datum/category_item/player_setup_item/volume_sliders/media/OnTopic(var/href, var/list/href_list, var/mob/user) if(href_list["change_media_volume"]) if(CanUseTopic(user)) var/value = input("Choose your Jukebox volume (0-100%)", "Jukebox volume", round(pref.media_volume * 100)) diff --git a/code/modules/client/preference_setup/vore/01_ears.dm b/code/modules/client/preference_setup/vore/01_ears.dm index 8a26513a01b..c36ccd4bca3 100644 --- a/code/modules/client/preference_setup/vore/01_ears.dm +++ b/code/modules/client/preference_setup/vore/01_ears.dm @@ -1,7 +1,7 @@ // Global stuff that will put us on the map /datum/category_group/player_setup_category/vore name = "VORE" - sort_order = 7 + sort_order = 8 category_item_type = /datum/category_item/player_setup_item/vore // Define a place to save appearance in character setup diff --git a/code/modules/client/preference_setup/vore/07_traits.dm b/code/modules/client/preference_setup/vore/07_traits.dm index 6462a142c7d..e653166b7ad 100644 --- a/code/modules/client/preference_setup/vore/07_traits.dm +++ b/code/modules/client/preference_setup/vore/07_traits.dm @@ -14,6 +14,7 @@ var/traits_cheating = 0 //Varedit by admins allows saving new maximums on people who apply/etc var/starting_trait_points = STARTING_SPECIES_POINTS var/max_traits = MAX_SPECIES_TRAITS + var/dirty_synth = 0 //Are you a synth // Definition of the stuff for Ears /datum/category_item/player_setup_item/vore/traits @@ -82,6 +83,10 @@ /datum/category_item/player_setup_item/vore/traits/copy_to_mob(var/mob/living/carbon/human/character) character.custom_species = pref.custom_species var/datum/species/selected_species = GLOB.all_species[pref.species] + + if(character.isSynthetic()) //Checking if we have a synth on our hands, boys. + pref.dirty_synth = 1 + if(selected_species.selects_bodytype) var/datum/species/custom/CS = character.species var/S = pref.custom_base ? pref.custom_base : "Human" @@ -255,6 +260,14 @@ var/conflict = FALSE + user.isSynthetic() //Recheck just to be sure + if(pref.dirty_synth && instance.not_for_synths)//if you are a synth you can't take this trait. + alert("You cannot take this trait as a SYNTH.\ + Please remove that trait, or pick another trait to add.","Error") + pref.dirty_synth = 0 //Just to be sure + return TOPIC_REFRESH + + if(trait_choice in pref.pos_traits + pref.neu_traits + pref.neg_traits) conflict = instance.name diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index e6619e66fed..f16504b3ca4 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -150,6 +150,8 @@ datum/preferences var/examine_text_mode = 0 // Just examine text, include usage (description_info), switch to examine panel. var/multilingual_mode = 0 // Default behaviour, delimiter-key-space, delimiter-key-delimiter, off + var/list/volume_channels = list() + /datum/preferences/New(client/C) player_setup = new(src) diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index be8f3567f9b..213cc8f694e 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -111,7 +111,7 @@ . = FALSE if(LAZYLEN(accessories)) for(var/obj/item/clothing/C in accessories) - if(C.handle_low_temperature(tempcheck)) + if(C.handle_high_temperature(tempcheck)) . = TRUE if(max_heat_protection_temperature && max_heat_protection_temperature >= tempcheck) diff --git a/code/modules/clothing/glasses/hud_vr.dm b/code/modules/clothing/glasses/hud_vr.dm index 09e2af254d6..613c09e91e4 100644 --- a/code/modules/clothing/glasses/hud_vr.dm +++ b/code/modules/clothing/glasses/hud_vr.dm @@ -1,7 +1,9 @@ /obj/item/clothing/glasses/omnihud name = "\improper AR glasses" desc = "The ARG-62 AR Glasses are capable of displaying information on individuals. \ - Commonly used to allow non-augmented crew to interact with virtual interfaces." + Commonly used to allow non-augmented crew to interact with virtual interfaces. \ +
They are also fitted with toggleable cosmetic electrochromic lenses. \ + The lenses will not protect against sudden bright flashes or welding." origin_tech = list(TECH_MAGNET = 3, TECH_BIO = 3) var/obj/item/clothing/glasses/hud/omni/hud = null var/mode = "civ" @@ -45,6 +47,13 @@ spawn(20 SECONDS) arscreen = disconnect_ar tgarscreen = disconnect_tgar + + //extra fun for non-sci variants; a small chance flip the state to the dumb 3d glasses when EMP'd + if(icon_state == "glasses" || icon_state == "sun") + if(prob(10)) + icon_state = "3d" + if(ishuman(loc)) + to_chat(loc, "The lenses of your [src.name] malfunction!") ..() /obj/item/clothing/glasses/omnihud/proc/flashed() @@ -55,11 +64,13 @@ prescription = !prescription playsound(src,'sound/items/screwdriver.ogg', 50, 1) if(prescription) - name = "[initial(name)] (pr)" - user.visible_message("[user] uploads new prescription data to the [src.name].") + user.visible_message("[user] uploads new prescription data to the [src.name] and resets the lenses.") + name = "[initial(name)] (pr)" //change the name *after* the text so the message above is accurate + icon_state = "[initial(icon_state)]" //reset the icon state just to be safe else + user.visible_message("[user] deletes the prescription data on the [src.name] and resets the lenses.") name = "[initial(name)]" - user.visible_message("[user] deletes the prescription data on the [src.name].") + icon_state = "[initial(icon_state)]" /obj/item/clothing/glasses/omnihud/attack_self(mob/user) if(!ishuman(user)) @@ -72,6 +83,45 @@ if(!ar_interact(H)) to_chat(user, "The [src] does not have any kind of special display.") +//cosmetic shading, doesn't enhance eye protection +/obj/item/clothing/glasses/omnihud/verb/chromatize() + set name = "Toggle AR Glasses Shading" + set desc = "Toggle the cosmetic electrochromatic shading of your AR glasses." + set category = "Object" + set src in usr + if(!usr.canmove || usr.stat || usr.restrained()) + return + if(icon_state == "3d") + to_chat(usr, "You reset the electrochromic lenses of \the [src] back to normal.") + if(prescription) + name = "[initial(name)] (pr)" + else + name = "[initial(name)]" + icon_state = "[initial(icon_state)]" + else if(prescription) + if(icon_state == "glasses") + to_chat(usr, "You darken the electrochromic lenses of \the [src] to one-way transparency.") + name = "[initial(name)] (shaded, pr)" + icon_state = "sun" + else if(icon_state == "sun") + to_chat(usr, "You restore the electrochromic lenses of \the [src] to standard two-way transparency.") + name = "[initial(name)] (pr)" + icon_state = "glasses" + else + to_chat(usr, "The [src] don't seem to support this functionality.") + else if(!prescription) + if(icon_state == "glasses") + to_chat(usr, "You darken the electrochromic lenses of \the [src] to one-way transparency.") + name = "[initial(name)] (shaded)" + icon_state = "sun" + else if(icon_state == "sun") + to_chat(usr, "You restore the electrochromic lenses of \the [src] to standard two-way transparency.") + name = "[initial(name)]" + icon_state = "glasses" + else + to_chat(usr, "The [src] don't seem to support this functionality.") + update_clothing_icon() + /obj/item/clothing/glasses/omnihud/proc/ar_interact(var/mob/living/carbon/human/user) return 0 //The base models do nothing. @@ -82,7 +132,8 @@ /obj/item/clothing/glasses/omnihud/med name = "\improper AR-M glasses" desc = "The ARG-62-M AR Glasses are capable of displaying information on individuals. \ - These have been upgraded with medical records access and virus database integration." + These have been upgraded with medical records access and virus database integration. \ + They can also read data from active suit sensors using the crew monitoring system." mode = "med" action_button_name = "AR Console (Crew Monitor)" tgarscreen_path = /datum/tgui_module/crew_monitor/glasses @@ -96,9 +147,10 @@ /obj/item/clothing/glasses/omnihud/sec name = "\improper AR-S glasses" desc = "The ARG-62-S AR Glasses are capable of displaying information on individuals. \ - These have been upgraded with security records integration and flash protection." + These have been upgraded with security records integration and flash protection. \ + They also have access to security alerts such as camera and motion sensor alarms." mode = "sec" - flash_protection = FLASH_PROTECTION_MAJOR + flash_protection = FLASH_PROTECTION_MODERATE //weld protection is a little too widespread action_button_name = "AR Console (Security Alerts)" tgarscreen_path = /datum/tgui_module/alarm_monitor/security/glasses enables_planes = list(VIS_CH_ID,VIS_CH_HEALTH_VR,VIS_CH_WANTED,VIS_AUGMENTED) @@ -111,7 +163,8 @@ /obj/item/clothing/glasses/omnihud/eng name = "\improper AR-E glasses" desc = "The ARG-62-E AR Glasses are capable of displaying information on individuals. \ - These have been upgraded with advanced electrochromic lenses to protect your eyes during welding." + These have been upgraded with advanced electrochromic lenses to protect your eyes during welding, \ + and can also display a list of atmospheric, fire, and power alarms." mode = "eng" flash_protection = FLASH_PROTECTION_MAJOR action_button_name = "AR Console (Station Alerts)" @@ -125,15 +178,12 @@ /obj/item/clothing/glasses/omnihud/rnd name = "\improper AR-R glasses" desc = "The ARG-62-R AR Glasses are capable of displaying information on individuals. \ - These have been ... modified ... to fit into a different frame." + They... don't seem to do anything particularly interesting? But hey, at least they look kinda science-y." mode = "sci" - icon = 'icons/obj/clothing/glasses.dmi' - icon_override = null - icon_state = "purple" /obj/item/clothing/glasses/omnihud/eng/meson name = "meson scanner HUD" - desc = "A headset equipped with a scanning lens and mounted retinal projector. They don't provide any eye protection, but they're less obtrusive than goggles." + desc = "A headset equipped with a scanning lens and mounted retinal projector. It doesn't provide any eye protection, but it's less obtrusive than goggles." icon = 'icons/vore/custom_items_vr.dmi' icon_override = 'icons/vore/custom_clothes_vr.dmi' icon_state = "projector" @@ -141,6 +191,7 @@ body_parts_covered = 0 toggleable = 1 vision_flags = SEE_TURFS //but they can spot breaches. Due to the way HUDs work, they don't provide darkvision up-close the way mesons do. + flash_protection = 0 //it's an open, single-eye retinal projector. there's no way it protects your eyes from flashes or welders. /obj/item/clothing/glasses/omnihud/eng/meson/attack_self(mob/user) if(!active) @@ -171,10 +222,18 @@ /obj/item/clothing/glasses/omnihud/all name = "\improper AR-B glasses" desc = "The ARG-62-B AR Glasses are capable of displaying information on individuals. \ - These have been upgraded with every feature the lesser models have. Now we're talkin'." + These have been upgraded with (almost) every feature the lesser models have. Now we're talkin'. \ +
Offers full protection against bright flashes/welders and full access to system alarm monitoring." mode = "best" flash_protection = FLASH_PROTECTION_MAJOR enables_planes = list(VIS_CH_ID,VIS_CH_HEALTH_VR,VIS_CH_STATUS_R,VIS_CH_BACKUP,VIS_CH_WANTED) + action_button_name = "AR Console (All Alerts)" + tgarscreen_path = /datum/tgui_module/alarm_monitor/all/glasses + + ar_interact(var/mob/living/carbon/human/user) + if(tgarscreen) + tgarscreen.tgui_interact(user) + return 1 /obj/item/clothing/glasses/hud/security/eyepatch name = "Security Hudpatch" @@ -221,5 +280,4 @@ icon_state = "[icon_state]_1" else icon_state = initial(icon_state) - update_clothing_icon() - + update_clothing_icon() \ No newline at end of file diff --git a/code/modules/clothing/head/misc_special.dm b/code/modules/clothing/head/misc_special.dm index a3da836d7c1..b23f70b1853 100644 --- a/code/modules/clothing/head/misc_special.dm +++ b/code/modules/clothing/head/misc_special.dm @@ -7,6 +7,7 @@ * Kitty ears * Holiday hats Crown of Wrath + Warning cone */ /* @@ -288,3 +289,19 @@ /obj/item/clothing/head/psy_crown/gluttony/activate_ability(var/mob/living/wearer) ..() wearer.add_modifier(/datum/modifier/gluttonyregeneration, 45 SECONDS) + +/obj/item/clothing/head/cone + name = "warning cone" + desc = "This cone is trying to warn you of something!" + description_info = "It looks like you can wear it in your head slot." + icon_state = "cone" + item_state = "cone" + drop_sound = 'sound/items/drop/shoes.ogg' + force = 1 + throwforce = 3 + throw_speed = 2 + throw_range = 5 + w_class = 2 + body_parts_covered = HEAD + attack_verb = list("warned", "cautioned", "smashed") + armor = list("melee" = 5, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) \ No newline at end of file diff --git a/code/modules/clothing/spacesuits/rig/rig.dm b/code/modules/clothing/spacesuits/rig/rig.dm index 140bf6ecc9c..cd65478a05e 100644 --- a/code/modules/clothing/spacesuits/rig/rig.dm +++ b/code/modules/clothing/spacesuits/rig/rig.dm @@ -342,7 +342,7 @@ piece.armor["bio"] = 100 else piece.armor["bio"] = src.armor["bio"] - playsound(src, "[!seal_target ? 'sound/machines/boltsdown.ogg' : 'sound/machines/boltsup.ogg']", 10, FALSE) + playsound(src,'sound/machines/rig/rigservo.ogg', 10, FALSE) else failed_to_seal = 1 @@ -707,7 +707,7 @@ if(istype(holder)) if(use_obj && check_slot == use_obj) to_chat(H, "Your [use_obj.name] [use_obj.gender == PLURAL ? "retract" : "retracts"] swiftly.") - playsound(src, 'sound/machines/boltsup.ogg', 10, FALSE) + playsound(src, 'sound/machines/rig/rigservo.ogg', 10, FALSE) use_obj.canremove = 1 holder.drop_from_inventory(use_obj) use_obj.forceMove(get_turf(src)) @@ -726,7 +726,7 @@ return else to_chat(H, "Your [use_obj.name] [use_obj.gender == PLURAL ? "deploy" : "deploys"] swiftly.") - playsound(src, 'sound/machines/boltsdown.ogg', 10, FALSE) + playsound(src, 'sound/machines/rig/rigservo.ogg', 10, FALSE) if(piece == "helmet" && helmet) helmet.update_light(H) diff --git a/code/modules/clothing/suits/miscellaneous.dm b/code/modules/clothing/suits/miscellaneous.dm index 32e5e197437..6c12a2e68d6 100644 --- a/code/modules/clothing/suits/miscellaneous.dm +++ b/code/modules/clothing/suits/miscellaneous.dm @@ -892,3 +892,38 @@ obj/item/clothing/suit/kamishimo /obj/item/clothing/suit/storage/snowsuit/science name = "science snowsuit" icon_state = "snowsuit_science" + +/obj/item/clothing/suit/caution + name = "wet floor sign" + desc = "Caution! Wet Floor!" + description_fluff = "Used by the janitor to passive-aggressively point at when you eventually slip on one of their mopped floors." + description_info = "Alt-click, or click in-hand to toggle the caution lights. It looks like you can wear it in your suit slot." + icon_state = "caution" + drop_sound = 'sound/items/drop/shoes.ogg' + force = 1 + throwforce = 3 + throw_speed = 2 + throw_range = 5 + w_class = 2 + body_parts_covered = UPPER_TORSO|LOWER_TORSO + attack_verb = list("warned", "cautioned", "smashed") + armor = list("melee" = 5, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + +/obj/item/clothing/suit/caution/attack_self() + toggle() + +/obj/item/clothing/suit/caution/AltClick() + toggle() + +/obj/item/clothing/suit/caution/proc/toggle() + if(!usr || usr.stat || usr.lying || usr.restrained() || !Adjacent(usr)) return + else if(src.icon_state == "caution") + src.icon_state = "caution_blinking" + src.item_state = "caution_blinking" + usr.show_message("You turn the wet floor sign on.") + playsound(src.loc, 'sound/machines/button.ogg', 30, 1) + else + src.icon_state = "caution" + src.item_state = "caution" + usr.show_message("You turn the wet floor sign off.") + update_clothing_icon() \ No newline at end of file diff --git a/code/modules/clothing/under/nanotrasen_vr.dm b/code/modules/clothing/under/nanotrasen_vr.dm index f6eeecfb43b..65dee313479 100644 --- a/code/modules/clothing/under/nanotrasen_vr.dm +++ b/code/modules/clothing/under/nanotrasen_vr.dm @@ -3,29 +3,32 @@ /obj/item/clothing/under/nanotrasen name = "NanoTrasen uniform" desc = "A comfortable turtleneck and black trousers sporting nanotrasen symbols." - icon_state = "navyutility" - worn_state = "navyutility" + icon = 'icons/obj/clothing/uniforms_solgov.dmi' + icon_override = 'icons/mob/uniform_solgov.dmi' + item_icons = list(slot_w_uniform_str = 'icons/mob/uniform_solgov.dmi', slot_r_hand_str = "black", slot_l_hand_str = "black") + icon_state = "blackutility" + worn_state = "blackutility" armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0) siemens_coefficient = 0.9 /obj/item/clothing/under/nanotrasen/security name = "NanoTrasen security uniform" desc = "The security uniform of NanoTrasen's security. It looks sturdy and well padded" - icon_state = "navyutility_sec" - worn_state = "navyutility_sec" + icon_state = "blackutility_crew" + worn_state = "blackutility_crew" armor = list(melee = 10, bullet = 5, laser = 5, energy = 5, bomb = 5, bio = 0, rad = 0) /obj/item/clothing/under/nanotrasen/security/warden name = "NanoTrasen warden uniform" desc = "The uniform of the NanoTrasen's prison wardens. It looks sturdy and well padded. This one has gold cuffs." - icon_state = "navyutility_com" - worn_state = "navyutility_com" + icon_state = "blackutility_com" + worn_state = "blackutility_com" /obj/item/clothing/under/nanotrasen/security/commander name = "NanoTrasen security command uniform" desc = "The uniform of the NanoTrasen's security commanding officers. It looks sturdy and well padded. This one has gold trim and red blazes." - icon_state = "blackutility_seccom" - worn_state = "blackutility_seccom" + icon_state = "blackutility_com" + worn_state = "blackutility_com" //Head Gear @@ -42,7 +45,7 @@ /obj/item/clothing/head/beret/nanotrasen name = "NanoTrasen security beret" desc = "A NT blue beret belonging to the NanoTrasen security forces. For personnel that are more inclined towards style than safety." - icon_state = "beret_navy" + icon_state = "beret_navy_security" //Armor diff --git a/code/modules/clothing/under/xenos/seromi.dm b/code/modules/clothing/under/xenos/seromi.dm index 5126ab14604..8da5e527550 100644 --- a/code/modules/clothing/under/xenos/seromi.dm +++ b/code/modules/clothing/under/xenos/seromi.dm @@ -37,6 +37,22 @@ name = "small command dress" icon_state = "seromi_dress_cap" +/obj/item/clothing/under/seromi/smock/dress/science + name = "small research dress" + icon_state = "seromi_dress_science" + +/obj/item/clothing/under/seromi/smock/dress/security + name = "small security dress" + icon_state = "seromi_dress_security" + +/obj/item/clothing/under/seromi/smock/dress/engine + name = "small engineering dress" + icon_state = "seromi_dress_engine" + +/obj/item/clothing/under/seromi/smock/dress/medical + name = "small medical dress" + icon_state = "seromi_dress_medical" + /obj/item/clothing/under/seromi/smock/uniform name = "small command uniform" icon_state = "seromi_captain" diff --git a/code/modules/detectivework/microscope/dnascanner.dm b/code/modules/detectivework/microscope/dnascanner.dm index 0b9782b2c8d..1dac4a0f58f 100644 --- a/code/modules/detectivework/microscope/dnascanner.dm +++ b/code/modules/detectivework/microscope/dnascanner.dm @@ -9,7 +9,6 @@ circuit = /obj/item/weapon/circuitboard/dna_analyzer var/obj/item/weapon/forensics/swab/bloodsamp = null - var/closed = 0 var/scanning = 0 var/scanner_progress = 0 var/scanner_rate = 5 @@ -20,80 +19,76 @@ . = ..() default_apply_parts() -/obj/machinery/dnaforensics/attackby(var/obj/item/W, mob/user as mob) - +/obj/machinery/dnaforensics/attackby(obj/item/W, mob/user) if(bloodsamp) - to_chat(user, "There is already a sample in the machine.") + to_chat(user, "There is a sample in the machine.") return - if(closed) - if(!scanning) - if(default_deconstruction_screwdriver(user, W)) - return - if(default_deconstruction_crowbar(user, W)) - return - else - to_chat(user, "Open the cover before inserting the sample.") + if(scanning) + to_chat(user, "[src] is busy scanning right now.") + return + + if(default_deconstruction_screwdriver(user, W)) + return + if(default_deconstruction_crowbar(user, W)) return var/obj/item/weapon/forensics/swab/swab = W if(istype(swab) && swab.is_used()) user.unEquip(W) - src.bloodsamp = swab - swab.loc = src - to_chat(user, "You insert \the [W] into \the [src].") + bloodsamp = swab + swab.forceMove(src) + to_chat(user, "You insert [W] into [src].") + update_icon() else to_chat(user, "\The [src] only accepts used swabs.") return -/obj/machinery/dnaforensics/ui_interact(mob/user, ui_key = "main",var/datum/nanoui/ui = null) - if(stat & (NOPOWER)) return - if(user.stat || user.restrained()) return - var/list/data = list() +/obj/machinery/dnaforensics/tgui_interact(mob/user, datum/tgui/ui) + if(stat & (NOPOWER)) + return + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "DNAForensics", "QuikScan DNA Analyzer") // 540, 326 + ui.open() + +/obj/machinery/dnaforensics/tgui_data(mob/user) + var/list/data = ..() data["scan_progress"] = round(scanner_progress) data["scanning"] = scanning data["bloodsamp"] = (bloodsamp ? bloodsamp.name : "") data["bloodsamp_desc"] = (bloodsamp ? (bloodsamp.desc ? bloodsamp.desc : "No information on record.") : "") - data["lidstate"] = closed + return data - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data) - if (!ui) - ui = new(user, src, ui_key, "dnaforensics.tmpl", "QuikScan DNA Analyzer", 540, 326) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) - -/obj/machinery/dnaforensics/Topic(href, href_list) - - if(..()) return 1 +/obj/machinery/dnaforensics/tgui_act(action, list/params) + if(..()) + return TRUE if(stat & (NOPOWER)) - return 0 // don't update UIs attached to this object + return FALSE // don't update UIs attached to this object - if(href_list["scanItem"]) - if(scanning) - scanning = 0 - else - if(bloodsamp) - if(closed == 1) + . = TRUE + switch(action) + if("scanItem") + if(scanning) + scanning = FALSE + update_icon() + else + if(bloodsamp) scanner_progress = 0 - scanning = 1 + scanning = TRUE to_chat(usr, "Scan initiated.") update_icon() else - to_chat(usr, "Please close sample lid before initiating scan.") - else - to_chat(usr, "Insert an item to scan.") + to_chat(usr, "Insert an item to scan.") + . = TRUE - if(href_list["ejectItem"]) - if(bloodsamp) - bloodsamp.forceMove(src.loc) - bloodsamp = null - - if(href_list["toggleLid"]) - toggle_lid() - - return 1 + if("ejectItem") + if(bloodsamp) + bloodsamp.forceMove(loc) + bloodsamp = null + scanning = FALSE + update_icon() /obj/machinery/dnaforensics/process() if(scanning) @@ -110,7 +105,7 @@ last_process_worldtime = world.time /obj/machinery/dnaforensics/proc/complete_scan() - src.visible_message("[bicon(src)] makes an insistent chime.", 2) + visible_message("[bicon(src)] makes an insistent chime.", 2) update_icon() if(bloodsamp) var/obj/item/weapon/paper/P = new(src) @@ -127,38 +122,23 @@ data += "No DNA found.
" P.info = "[src] analysis report #[report_num]
" P.info += "Scanned item:
[bloodsamp.name]
[bloodsamp.desc]

" + data - P.forceMove(src.loc) + P.forceMove(loc) P.update_icon() - scanning = 0 + scanning = FALSE update_icon() return -/obj/machinery/dnaforensics/attack_ai(mob/user as mob) - ui_interact(user) +/obj/machinery/dnaforensics/attack_ai(mob/user) + tgui_interact(user) -/obj/machinery/dnaforensics/attack_hand(mob/user as mob) - ui_interact(user) - -/obj/machinery/dnaforensics/verb/toggle_lid() - set category = "Object" - set name = "Toggle Lid" - set src in oview(1) - - if(usr.stat || !isliving(usr)) - return - - if(scanning) - to_chat(usr, "You can't do that while [src] is scanning!") - return - - closed = !closed - src.update_icon() +/obj/machinery/dnaforensics/attack_hand(mob/user) + tgui_interact(user) /obj/machinery/dnaforensics/update_icon() ..() if(!(stat & NOPOWER) && scanning) icon_state = "dnaworking" - else if(closed) + else if(bloodsamp) icon_state = "dnaclosed" else icon_state = "dnaopen" diff --git a/code/modules/examine/descriptions/turfs.dm b/code/modules/examine/descriptions/turfs.dm index 4319c23ffe6..a494b8cdd36 100644 --- a/code/modules/examine/descriptions/turfs.dm +++ b/code/modules/examine/descriptions/turfs.dm @@ -30,4 +30,37 @@ results += "[desc_panel_image("welder")]to continue deconstruction." if(0) results += "[desc_panel_image("crowbar")]to finish deconstruction." - return results \ No newline at end of file + return results + +/turf/simulated/floor/get_description_info() + . = ..() + if(broken || burnt) + . += "It is broken." + +/turf/simulated/floor/get_description_interaction() + . = ..() + if(broken || burnt) + if(is_plating()) + . += "Use a welder on it to repair the damage." + else + . += "Use a crowbar on it to remove it." + else if(flooring) + if(flooring.flags & TURF_IS_FRAGILE) + . += "You can use a crowbar on it to remove it, but this will destroy it!" + else if(flooring.flags & TURF_REMOVE_CROWBAR) + . += "Use a crowbar on it to remove it." + if(flooring.flags & TURF_REMOVE_SCREWDRIVER) + . += "Use a screwdriver on it to remove it." + if(flooring.flags & TURF_REMOVE_WRENCH) + . += "Use a wrench on it to remove it." + if(flooring.flags & TURF_REMOVE_SHOVEL) + . += "Use a shovel on it to remove it." + +/turf/simulated/floor/outdoors/snow/get_description_interaction() + . = ..() + . += "Use a shovel on it to get rid of the snow and reveal the ground beneath." + . += "Use an empty hand on it to scoop up some snow, which you can use to make snowballs or snowmen." + +/turf/simulated/floor/outdoors/grass/get_description_interaction() + . = "Use floor tiles on it to make a plating." // using . = ..() would incorrectly say you can remove the grass with a shovel + . += "Use a shovel on it to dig for worms." diff --git a/code/modules/food/drinkingglass/glass_boxes.dm b/code/modules/food/drinkingglass/glass_boxes.dm index 7157e209c1e..2cd035843de 100644 --- a/code/modules/food/drinkingglass/glass_boxes.dm +++ b/code/modules/food/drinkingglass/glass_boxes.dm @@ -13,6 +13,7 @@ new /obj/item/weapon/reagent_containers/food/drinks/glass2/mug(src) new /obj/item/weapon/reagent_containers/food/drinks/glass2/wine(src) new /obj/item/weapon/reagent_containers/food/drinks/metaglass(src) + new /obj/item/weapon/reagent_containers/food/drinks/metaglass/metapint(src) /obj/item/weapon/storage/box/glasses name = "box of glasses" @@ -60,6 +61,10 @@ name = "box of half-pint metamorphic glasses" glass_type = /obj/item/weapon/reagent_containers/food/drinks/metaglass +/obj/item/weapon/storage/box/glasses/meta/metapint + name = "box of metamorphic pint glasses" + glass_type = /obj/item/weapon/reagent_containers/food/drinks/metaglass/metapint + /obj/item/weapon/storage/box/glass_extras name = "box of cocktail garnishings" var/extra_type = /obj/item/weapon/glass_extra diff --git a/code/modules/food/food/cans.dm b/code/modules/food/food/cans.dm index 66a25d8dade..f4ade46de4d 100644 --- a/code/modules/food/food/cans.dm +++ b/code/modules/food/food/cans.dm @@ -8,7 +8,8 @@ /obj/item/weapon/reagent_containers/food/drinks/cans/cola name = "\improper Space Cola" - desc = "Cola. in space." + desc = "Reassuringly artificial." + description_fluff = "The 'Space' branding was originally added to the 'Alpha Cola' product line in order to justify selling cans for 50% higher prices to 'off-world' retailers. Despite being chemically identical, Space Cola proved so popular that Centauri Provisions eventually applied the name to the entire product line - price hike and all." icon_state = "cola" center_of_mass = list("x"=16, "y"=10) @@ -18,7 +19,7 @@ /obj/item/weapon/reagent_containers/food/drinks/cans/waterbottle name = "bottled water" - desc = "Introduced to the vending machines by Skrellian request, this water comes straight from the Martian poles." + desc = "Ice cold and utterly tasteless, this 'all-natural' mineral water comes 'fresh' from one of NanoTrasen's heavy-duty bottling plants in the Sivian poles." icon_state = "waterbottle" center_of_mass = list("x"=16, "y"=8) drop_sound = 'sound/items/drop/food.ogg' @@ -30,6 +31,7 @@ /obj/item/weapon/reagent_containers/food/drinks/cans/space_mountain_wind name = "\improper Space Mountain Wind" desc = "Blows right through you like a space wind." + description_fluff = "The 'Space' branding was originally added to the 'Alpha Cola' product line in order to justify selling cans for 50% higher prices to 'off-world' retailers. Despite being chemically identical, Space Cola proved so popular that Centauri Provisions eventually applied the name to the entire product line - price hike and all." icon_state = "space_mountain_wind" center_of_mass = list("x"=16, "y"=8) @@ -39,7 +41,7 @@ /obj/item/weapon/reagent_containers/food/drinks/cans/thirteenloko name = "\improper Thirteen Loko" - desc = "The CMO has advised crew members that consumption of Thirteen Loko may result in seizures, blindness, drunkeness, or even death. Please Drink Responsibly." + desc = "The Vir Health Board has advised consumers that consumption of Thirteen Loko may result in seizures, blindness, drunkenness, or even death. Please Drink Responsibly." icon_state = "thirteen_loko" center_of_mass = list("x"=16, "y"=10) @@ -50,6 +52,7 @@ /obj/item/weapon/reagent_containers/food/drinks/cans/dr_gibb name = "\improper Dr. Gibb" desc = "A delicious mixture of 42 different flavors." + description_fluff = "Following a 2490 lawsuit and a spate of deaths, Gilthari Exports reminds customers that the 'Dr.' legally stands for 'Drink'." icon_state = "dr_gibb" center_of_mass = list("x"=16, "y"=8) @@ -57,9 +60,21 @@ ..() reagents.add_reagent("dr_gibb", 30) +/obj/item/weapon/reagent_containers/food/drinks/cans/dr_gibb_diet + name = "\improper Diet Dr. Gibb" + desc = "A delicious mixture of 42 different flavors, one of which is water." + description_fluff = "Following a 2490 lawsuit and a spate of deaths, Gilthari Exports reminds customers that the 'Dr.' legally stands for 'Drink'." + icon_state = "diet_dr_gibb" + center_of_mass = list("x"=16, "y"=8) + +/obj/item/weapon/reagent_containers/food/drinks/cans/dr_gibb_diet/Initialize() + ..() + reagents.add_reagent("diet_dr_gibb", 30) + /obj/item/weapon/reagent_containers/food/drinks/cans/starkist name = "\improper Star-kist" desc = "The taste of a star in liquid form. And, a bit of tuna...?" + description_fluff = "Brought back by popular demand in 2515 after a limited-run release in 2510, the cult success of this bizarre tasting soda has never truly been accounted for by economists." icon_state = "starkist" center_of_mass = list("x"=16, "y"=8) @@ -70,6 +85,7 @@ /obj/item/weapon/reagent_containers/food/drinks/cans/space_up name = "\improper Space-Up" desc = "Tastes like a hull breach in your mouth." + description_fluff = "The 'Space' branding was originally added to the 'Alpha Cola' product line in order to justify selling cans for 50% higher prices to 'off-world' retailers. Despite being chemically identical, Space Cola proved so popular that Centauri Provisions eventually applied the name to the entire product line - price hike and all." icon_state = "space-up" center_of_mass = list("x"=16, "y"=8) @@ -79,7 +95,8 @@ /obj/item/weapon/reagent_containers/food/drinks/cans/lemon_lime name = "\improper Lemon-Lime" - desc = "You wanted ORANGE. It gave you Lemon Lime." + desc = "You wanted ORANGE. It gave you Lemon-Lime." + description_fluff = "Not to be confused with 'lemon & lime soda', Lemon-Lime is specially formulated using the highly propriatary Lemon-Lime Fruit. Growing the Lemon-Lime without a license is punishable by fines or jail time. Accept no immitations." icon_state = "lemon-lime" center_of_mass = list("x"=16, "y"=8) @@ -90,6 +107,7 @@ /obj/item/weapon/reagent_containers/food/drinks/cans/iced_tea name = "\improper Vrisk Serket Iced Tea" desc = "That sweet, refreshing southern earthy flavor. That's where it's from, right? South Earth?" + description_fluff = "Produced exclusively on the planet Oasis, Vrisk Serket Iced Tea is not sold outside of the Golden Crescent, let alone Earth." icon_state = "ice_tea_can" center_of_mass = list("x"=16, "y"=8) @@ -100,6 +118,7 @@ /obj/item/weapon/reagent_containers/food/drinks/cans/grape_juice name = "\improper Grapel Juice" desc = "500 pages of rules of how to appropriately enter into a combat with this juice!" + description_fluff = "Strangely, this unassuming grape soda is a product of Hephaestus Industries." icon_state = "purple_can" center_of_mass = list("x"=16, "y"=8) @@ -109,7 +128,8 @@ /obj/item/weapon/reagent_containers/food/drinks/cans/tonic name = "\improper T-Borg's Tonic Water" - desc = "Quinine tastes funny, but at least it'll keep that Space Malaria away." + desc = "Quinine tastes funny, but at least it'll keep the Malaria away." + description_fluff = "Due to its technically medicinal properties and the complexities of chemical copyright law, T-Borg's Tonic Water is a rare product of Zeng-Hu's 'LifeWater' refreshments division." icon_state = "tonic" center_of_mass = list("x"=16, "y"=8) @@ -130,9 +150,22 @@ /obj/item/weapon/reagent_containers/food/drinks/cans/gingerale name = "\improper Classic Ginger Ale" desc = "For when you need to be more retro than NanoTrasen already pays you for." + description_fluff = "'Classic' beverages is a registered trademark of the Centauri Provisions corporation." icon_state = "gingerale" center_of_mass = list("x"=16, "y"=8) /obj/item/weapon/reagent_containers/food/drinks/cans/gingerale/Initialize() . = ..() - reagents.add_reagent("gingerale", 30) \ No newline at end of file + reagents.add_reagent("gingerale", 30) + +/obj/item/weapon/reagent_containers/food/drinks/cans/root_beer + name = "\improper R&D Root Beer" + desc = "Guaranteed to be both Rootin' and Tootin'." + description_fluff = "Despite centuries of humanity's expansion, this particular soda is still produced almost exclusively on Earth, in North America." + icon_state = "root_beer" + center_of_mass = list("x"=16, "y"=10) + +/obj/item/weapon/reagent_containers/food/drinks/cans/root_beer/Initialize() + . = ..() + reagents.add_reagent("rootbeer", 30) + diff --git a/code/modules/food/food/drinks.dm b/code/modules/food/food/drinks.dm index 816c9103396..e13d53cac80 100644 --- a/code/modules/food/food/drinks.dm +++ b/code/modules/food/food/drinks.dm @@ -10,6 +10,7 @@ flags = OPENCONTAINER amount_per_transfer_from_this = 5 volume = 50 + var/trash = null /obj/item/weapon/reagent_containers/food/drinks/on_reagent_change() if (reagents.reagent_list.len > 0) @@ -20,6 +21,21 @@ price_tag = null return +/obj/item/weapon/reagent_containers/food/drinks/proc/On_Consume(var/mob/M) + if(!usr) + usr = M + if(!reagents.total_volume) + M.visible_message("[M] finishes drinking \the [src].","You finish drinking \the [src].") + if(trash) + usr.drop_from_inventory(src) //so icons update :[ + if(ispath(trash,/obj/item)) + var/obj/item/TrashItem = new trash(usr) + usr.put_in_hands(TrashItem) + else if(istype(trash,/obj/item)) + usr.put_in_hands(trash) + qdel(src) + return + /obj/item/weapon/reagent_containers/food/drinks/attack_self(mob/user as mob) if(!is_open_container()) open(user) @@ -51,6 +67,7 @@ if(!is_open_container()) to_chat(user, "You need to open [src]!") return 1 + On_Consume(target,user) return ..() /obj/item/weapon/reagent_containers/food/drinks/standard_dispenser_refill(var/mob/user, var/obj/structure/reagent_dispensers/target) @@ -114,6 +131,7 @@ /obj/item/weapon/reagent_containers/food/drinks/milk name = "milk carton" desc = "It's milk. White and nutritious goodness!" + description_fluff = "A product of NanoPastures. Who would have thought that cows would thrive in zero-G?" icon_state = "milk" item_state = "carton" center_of_mass = list("x"=16, "y"=9) @@ -126,6 +144,7 @@ /obj/item/weapon/reagent_containers/food/drinks/soymilk name = "soymilk carton" desc = "It's soy milk. White and nutritious goodness!" + description_fluff = "A product of NanoPastures. For those skeptical that cows can thrive in zero-G." icon_state = "soymilk" item_state = "carton" center_of_mass = list("x"=16, "y"=9) @@ -138,6 +157,7 @@ /obj/item/weapon/reagent_containers/food/drinks/smallmilk name = "small milk carton" desc = "It's milk. White and nutritious goodness!" + description_fluff = "A product of NanoPastures. Who would have thought that cows would thrive in zero-G?" volume = 30 icon_state = "mini-milk" item_state = "carton" @@ -151,6 +171,7 @@ /obj/item/weapon/reagent_containers/food/drinks/smallchocmilk name = "small chocolate milk carton" desc = "It's milk! This one is in delicious chocolate flavour." + description_fluff = "A product of NanoPastures. Who would have thought that cows would thrive in zero-G?" volume = 30 icon_state = "mini-milk_choco" item_state = "carton" @@ -164,20 +185,25 @@ /obj/item/weapon/reagent_containers/food/drinks/coffee name = "\improper Robust Coffee" desc = "Careful, the beverage you're about to enjoy is extremely hot." + description_fluff = "Fresh coffee is almost unheard of outside of planets and stations where it is grown. Robust Coffee proudly advertises the six separate times it is freeze-dried during the production process of every cup of instant." icon_state = "coffee" + trash = /obj/item/trash/coffee center_of_mass = list("x"=15, "y"=10) - drop_sound = 'sound/items/drop/box.ogg' + drop_sound = 'sound/items/drop/papercup.ogg' /obj/item/weapon/reagent_containers/food/drinks/coffee/Initialize() . = ..() reagents.add_reagent("coffee", 30) /obj/item/weapon/reagent_containers/food/drinks/tea - name = "cup of Duke Purple Tea" + name = "cup of Duke Purple tea" desc = "An insult to Duke Purple is an insult to the Space Queen! Any proper gentleman will fight you, if you sully this tea." - icon_state = "teacup" + description_fluff = "Duke Purple is NanoPasture's proprietary strain of black tea, noted for its strong but otherwise completely non-distinctive flavour." + icon_state = "chai_vended" item_state = "coffee" + trash = /obj/item/trash/coffee center_of_mass = list("x"=16, "y"=14) + drop_sound = 'sound/items/drop/papercup.ogg' /obj/item/weapon/reagent_containers/food/drinks/tea/Initialize() . = ..() @@ -193,21 +219,70 @@ reagents.add_reagent("ice", 30) /obj/item/weapon/reagent_containers/food/drinks/h_chocolate - name = "cup of Dutch hot coco" - desc = "Made in Space South America." - icon_state = "hot_coco" + name = "cup of Counselor's Choice hot cocoa" + desc = "Who needs character traits when you can enjoy a hot mug of cocoa?" + description_fluff = "Counselor's Choice brand hot cocoa is made with a blend of hot water and non-dairy milk powder substitute, in a compromise destined to annoy all parties." + icon_state = "coffee" item_state = "coffee" + trash = /obj/item/trash/coffee center_of_mass = list("x"=15, "y"=13) + drop_sound = 'sound/items/drop/papercup.ogg' /obj/item/weapon/reagent_containers/food/drinks/h_chocolate/Initialize() ..() reagents.add_reagent("hot_coco", 30) +/obj/item/weapon/reagent_containers/food/drinks/greentea + name = "cup of green tea" + desc = "Exceptionally traditional, delightfully subtle." + description_fluff = "Tea remains an important tradition in many cultures originating on Earth. Among these, green tea is probably the most traditional of the bunch... Though the vending machines of the modern era hardly do it justice." + icon_state = "greentea_vended" + item_state = "coffee" + trash = /obj/item/trash/coffee + center_of_mass = list("x"=16, "y"=14) + drop_sound = 'sound/items/drop/papercup.ogg' + +/obj/item/weapon/reagent_containers/food/drinks/greentea/Initialize() + . = ..() + reagents.add_reagent("greentea", 30) + +/obj/item/weapon/reagent_containers/food/drinks/chaitea + name = "cup of chai tea" + desc = "The name is redundant but the flavor is delicious!" + description_fluff = "Chai Tea - tea blended with a spice mix of cinnamon and cloves - borders on a national drink on Kishar." + icon_state = "chai_vended" + item_state = "coffee" + trash = /obj/item/trash/coffee + center_of_mass = list("x"=16, "y"=14) + drop_sound = 'sound/items/drop/papercup.ogg' + +/obj/item/weapon/reagent_containers/food/drinks/chaitea/Initialize() + . = ..() + reagents.add_reagent("chaitea", 30) + +/obj/item/weapon/reagent_containers/food/drinks/decaf + name = "cup of decaf coffee" + desc = "Coffee with all the wake-up sucked out." + description_fluff = "A trial run on two NanoTrasen stations in 2481 attempted to replace all vending machine coffee with decaf in order to combat an epidemic of caffeine addiction. After two days, three major industrial accidents and a death, the initiative was cancelled. Decaf is now thankfully optional." + icon_state = "coffee" + item_state = "coffee" + trash = /obj/item/trash/coffee + center_of_mass = list("x"=16, "y"=14) + drop_sound = 'sound/items/drop/papercup.ogg' + +/obj/item/weapon/reagent_containers/food/drinks/decaf/Initialize() + . = ..() + reagents.add_reagent("decaf", 30) + /obj/item/weapon/reagent_containers/food/drinks/dry_ramen name = "Cup Ramen" desc = "Just add 10ml water, self heats! A taste that reminds you of your school years." + description_fluff = "Konohagakure Brand Ramen has been an instant meal staple for centuries. Cheap, quick and available in over two hundred varieties - though most taste like artifical chicken." icon_state = "ramen" + trash = /obj/item/trash/ramen center_of_mass = list("x"=16, "y"=11) + drop_sound = 'sound/items/drop/papercup.ogg' + /obj/item/weapon/reagent_containers/food/drinks/dry_ramen/Initialize() ..() reagents.add_reagent("dry_ramen", 30) @@ -219,7 +294,7 @@ possible_transfer_amounts = null volume = 10 center_of_mass = list("x"=16, "y"=12) - drop_sound = 'sound/items/drop/paper.ogg' + drop_sound = 'sound/items/drop/papercup.ogg' /obj/item/weapon/reagent_containers/food/drinks/sillycup/Initialize() . = ..() diff --git a/code/modules/food/food/drinks/bottle.dm b/code/modules/food/food/drinks/bottle.dm index 89c06552f57..c79f9bd36d2 100644 --- a/code/modules/food/food/drinks/bottle.dm +++ b/code/modules/food/food/drinks/bottle.dm @@ -202,7 +202,7 @@ /obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey name = "Uncle Git's Special Reserve" - desc = "A premium single-malt whiskey, gently matured inside the tunnels of a nuclear shelter." + desc = "A premium single-malt whiskey, gently matured in a highly classified location." icon_state = "whiskeybottle" center_of_mass = list("x"=16, "y"=3) @@ -233,7 +233,7 @@ /obj/item/weapon/reagent_containers/food/drinks/bottle/tequilla name = "Caccavo Guaranteed Quality Tequilla" desc = "Made from premium petroleum distillates, pure thalidomide and other fine quality ingredients!" - icon_state = "tequillabottle" + icon_state = "tequilabottle" center_of_mass = list("x"=16, "y"=3) /obj/item/weapon/reagent_containers/food/drinks/bottle/tequilla/Initialize() @@ -252,7 +252,7 @@ /obj/item/weapon/reagent_containers/food/drinks/bottle/patron name = "Wrapp Artiste Patron" - desc = "Silver laced tequilla, served in space night clubs across the galaxy." + desc = "Silver laced tequilla, served in night clubs across the galaxy." icon_state = "patronbottle" center_of_mass = list("x"=16, "y"=6) @@ -514,8 +514,9 @@ rag_underlay = "rag_small" /obj/item/weapon/reagent_containers/food/drinks/bottle/small/beer - name = "space beer" - desc = "Contains only water, malt and hops." + name = "Spacer beer" + desc = "A remarkably unremarkable pale lager. Barley malt, hops and yeast." + description_fluff = "Identical to an earlier Earth-based variety of beer, Spacer beer was rebranded at the height of humanity's first extra-solar colonization boom in the 2130s and become the go-to cheap booze for those dreaming of a brighter future in the stars. Today, the beer is advertised as 'brewed in space, for space." icon_state = "beer" center_of_mass = list("x"=16, "y"=12) @@ -523,6 +524,28 @@ . = ..() reagents.add_reagent("beer", 30) +/obj/item/weapon/reagent_containers/food/drinks/bottle/small/beer/silverdragon + name = "Silver Dragon pilsner" + desc = "An earthy pale lager produced exclusively on Nisp, best served cold." + description_fluff = "Brewed using locally grown hops, with hints of local flora, Silver Dragon has a reputation as the beer of the frontier hunter - and those trying to look just as tough." + icon_state = "beer2" + +/obj/item/weapon/reagent_containers/food/drinks/bottle/small/beer/meteor + name = "Meteor beer" + desc = "A strong, premium beer with a hint of maize." + description_fluff = "Sold across human space, Meteor beer has won more awards than any single variety in history. It should be noted that Meteor's parent company Gilthari Exports, owns most alcohol awards agencies." + icon_state = "beerprem" + +/obj/item/weapon/reagent_containers/food/drinks/bottle/small/litebeer + name = "Lite-Speed Lite beer" + desc = "A reduced-alcohol, reduced-calorie beer for the drunk on a diet." + description_fluff = "Lite-Speed is Spacer Beer's light brand, and despite being widely considered inferior in every regard, it's still pretty cheap. The lower alcohol content also appeals to some Skrell, for whom full-strength beer is too strong." + icon_state = "beerlite" + +/obj/item/weapon/reagent_containers/food/drinks/bottle/small/litebeer/Initialize() + . = ..() + reagents.add_reagent("litebeer", 30) + /obj/item/weapon/reagent_containers/food/drinks/bottle/small/cider name = "Crisp's Cider" desc = "Fermented apples never tasted this good." @@ -545,6 +568,16 @@ . = ..() reagents.add_reagent("ale", 30) +/obj/item/weapon/reagent_containers/food/drinks/bottle/small/ale/hushedwhisper + name = "Hushed Whisper IPA" + desc = "A popular Sivian pale ale named for an infamous space pirate." + description_fluff = "Named for one of history's most infamous pirates, Qar’raqel, who ruled over Natuna before suffering a mysterious fate. This ale is brewed on Sif by a small company... Owned by Centauri Provisions." + icon_state = "alebottle2" + +/obj/item/weapon/reagent_containers/food/drinks/bottle/small/ale/hushedwhisper/Initialize() + . = ..() + reagents.add_reagent("ale", 30) + /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." diff --git a/code/modules/food/food/snacks.dm b/code/modules/food/food/snacks.dm index d65679f6f73..ed3f8a37c57 100644 --- a/code/modules/food/food/snacks.dm +++ b/code/modules/food/food/snacks.dm @@ -307,8 +307,10 @@ bitesize = 3 /obj/item/weapon/reagent_containers/food/snacks/candy - name = "candy" - desc = "Nougat, love it or hate it." + name = "\improper Grandma Ellen's Hard Candy" + desc = "Now without nuts!" + description_fluff = "Hard candies were banned from many early human colony ships due to the tendency for brittle, sticky chunks to find their way inside vital equipment in zero-G conditions. This only made them all the more popular to new arrivees, and the Grandma Ellen's brand was Tau Ceti's answer to that demand." + icon = 'icons/obj/food_snacks.dmi' icon_state = "candy" trash = /obj/item/trash/candy filling_color = "#7D5F46" @@ -322,8 +324,10 @@ bitesize = 2 /obj/item/weapon/reagent_containers/food/snacks/candy/proteinbar - name = "protein bar" - desc = "SwoleMAX brand protein bars, guaranteed to get you feeling perfectly overconfident." + name = "\improper SwoleMAX protein bar" + desc = "Guaranteed to get you feeling perfectly overconfident." + description_fluff = "NanoMed's SwoleMAX boasts the highest density of protein mush per square inch among leading protein bar brands. While formulated for strength training, this high nutrient density in a mostly-solid form makes SwoleMAX a popular alternative for spacers looking to mix up their usual diet of pastes and gooes." + icon = 'icons/obj/food_snacks.dmi' icon_state = "proteinbar" trash = /obj/item/trash/candy/proteinbar nutriment_amt = 9 @@ -335,6 +339,21 @@ reagents.add_reagent("sugar", 4) bitesize = 6 +/obj/item/weapon/reagent_containers/food/snacks/candy/gummy + name = "\improper AlliCo Gummies" + desc = "Somehow, there's never enough cola bottles." + description_fluff = "AlliCo's grab-bags of gummy candies come in over a thousand novelty shapes and dozens of flavours. Shoes, astronauts, bunny rabbits and singularities all made an appearance." + icon = 'icons/obj/food_snacks.dmi' + icon_state = "candy_gums" + trash = /obj/item/trash/candy/gums + nutriment_amt = 5 + nutriment_desc = list("sugar" = 1, "artificial fruit flavour" = 1) + +/obj/item/weapon/reagent_containers/food/snacks/candy/gummy/Initialize() + . = ..() + reagents.add_reagent("sugar", 5) + bitesize = 1 + /obj/item/weapon/reagent_containers/food/snacks/candy/donor name = "Donor Candy" desc = "A little treat for blood donors." @@ -362,8 +381,10 @@ bitesize = 2 /obj/item/weapon/reagent_containers/food/snacks/chips - name = "chips" - desc = "Commander Riker's What-The-Crisps" + name = "\improper What-The-Crisps" + desc = "Commander Riker's What-The-Crisps, lightly salted." + description_fluff = "What-The-Crisps' retro-styled starship commander has been a marketing staple for almost 200 years." + icon = 'icons/obj/food_snacks.dmi' icon_state = "chips" trash = /obj/item/trash/chips filling_color = "#E8C31E" @@ -375,6 +396,20 @@ . = ..() bitesize = 1 +/obj/item/weapon/reagent_containers/food/snacks/chips/bbq + name = "\improper Legendary BBQ Chips" + desc = "You know I can't grab your ghost chips!" + description_fluff = "A local brand, Legendary Chips have proudly sponsored Vir's anti-drink-piloting campaign since 2558." + icon = 'icons/obj/food_snacks.dmi' + icon_state = "chips_bbq" + trash = /obj/item/trash/chips/bbq + nutriment_amt = 3 + nutriment_desc = list("salt" = 1, "barbeque sauce" = 2) + +/obj/item/weapon/reagent_containers/food/snacks/chips/Initialize() + . = ..() + bitesize = 1 + /obj/item/weapon/reagent_containers/food/snacks/cookie name = "cookie" desc = "COOKIE!!!" @@ -388,6 +423,37 @@ . = ..() bitesize = 1 +/obj/item/weapon/reagent_containers/food/snacks/cookiesnack + name = "Carps Ahoy! miniature cookies" + desc = "Now 100% carpotoxin free!" + description_fluff = "Carps Ahoy! cookies are required to sell under the 'Cap'n Choco' name in certain markets, out of concerns that children will become desensitized to the very real dangers of Space Carp." + icon = 'icons/obj/food_snacks.dmi' + icon_state = "cookiesnack" + trash = /obj/item/trash/cookiesnack + filling_color = "#DBC94F" + nutriment_amt = 3 + nutriment_desc = list("sweetness" = 1, "stale cookie" = 2) + +/obj/item/weapon/reagent_containers/food/snacks/cookiesnack/Initialize() + . = ..() + bitesize = 1 + +/obj/item/weapon/reagent_containers/food/snacks/fruitbar + name = "\improper ChewMAX fruit bar" + desc = "Guaranteed to get you feeling comfortably superior." + description_fluff = "NanoMed's ChewMAX is the low-carb alternative to the SwoleMAX range! Want short-term energy but not really interested in sustaining it? Hate fat but don't entirely understand nutrition? Just really like fruit? ChewMAX is for you!" + icon = 'icons/obj/food_snacks.dmi' + icon_state = "fruitbar" + trash = /obj/item/trash/candy/fruitbar + nutriment_amt = 9 + nutriment_desc = list("apricot" = 2, "sugar" = 2, "dates" = 2, "cranberry" = 2, "apple = 2") + +/obj/item/weapon/reagent_containers/food/snacks/candy/proteinbar/Initialize() + . = ..() + reagents.add_reagent("nutriment", 4) + reagents.add_reagent("sugar", 4) + bitesize = 6 + /obj/item/weapon/reagent_containers/food/snacks/chocolatebar name = "Chocolate Bar" desc = "Such sweet, fattening food." @@ -583,6 +649,210 @@ src.name = "Frosted Jelly Donut" reagents.add_reagent("sprinkles", 2) + +/obj/item/weapon/reagent_containers/food/snacks/tuna + name = "\improper Tuna Snax" + desc = "A packaged dried fish snack, guaranteed to do not contain space carp. Actual fish content may vary." + description_fluff = "Launched by Centuari Provisions to target the Tajaran immigrant market, Tuna Snax also found a surprising niche among Vir's sizable Scandinavian population. Elsewhere, the dried fish flakes are widely considered disgusting." + icon = 'icons/obj/food_snacks.dmi' + icon_state = "tuna" + filling_color = "#FFDEFE" + center_of_mass = list("x"=17, "y"=13) + nutriment_amt = 3 + nutriment_desc = list("smoked fish" = 5) + trash = /obj/item/trash/tuna + +/obj/item/weapon/reagent_containers/food/snacks/tuna/Initialize() + . = ..() + reagents.add_reagent("protein", 4) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/pistachios + name = "pistachios" + icon = 'icons/obj/food_snacks.dmi' + icon_state = "pistachios" + desc = "Pistachios. There is absolutely nothing remarkable about these." + filling_color = "#825D26" + center_of_mass = list("x"=17, "y"=13) + nutriment_desc = list("nuts" = 1) + nutriment_amt = 3 + bitesize = 1 + trash = /obj/item/trash/pistachios + +/obj/item/weapon/reagent_containers/food/snacks/semki + name = "\improper Semki" + icon = 'icons/obj/food_snacks.dmi' + icon_state = "semki" + desc = "Sunflower seeds. A favorite among both birds and gopniks." + filling_color = "#68645D" + center_of_mass = list("x"=17, "y"=13) + nutriment_desc = list("sunflower seeds" = 1) + nutriment_amt = 6 + bitesize = 1 + trash = /obj/item/trash/semki + +/obj/item/weapon/reagent_containers/food/snacks/cb01 + name = "\improper Tau Ceti Bar" + desc = "A dark chocolate caramel and nougat bar made famous on Binma." + description_fluff = "Binma's signature chocolate bar, the Tau Ceti Bar was originally made with cheap, heavily preserved ingredients available to Sol's first colonists. The modern recipe attempts to recreate this, baffling many not accustomed to its slightly stale taste." + filling_color = "#552200" + icon = 'icons/obj/food_snacks.dmi' + icon_state = "cb01" + nutriment_amt = 4 + nutriment_desc = list("stale chocolate" = 2, "nougat" = 1, "caramel" = 1) + w_class = 1 + +/obj/item/weapon/reagent_containers/food/snacks/cb01/Initialize() + . = ..() + reagents.add_reagent("sugar", 1) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/cb02 + name = "\improper Hundred-Thousand Thaler Bar" + desc = "An ironically cheap puffed rice caramel milk chocolate bar." + description_fluff = "The Hundred-Thousand Thaler bar has been the focal point of dozens of exonet and radio giveaway pranks over its long history. In 2500 the company got in on the action, offering a prize of one-hundred thousand one-hundred thousand thaler bars to one lucky entrant, who reportedly turned down the prize in favour of a 250 Thaler cash prize." + filling_color = "#552200" + icon = 'icons/obj/food_snacks.dmi' + icon_state = "cb02" + nutriment_amt = 4 + nutriment_desc = list("chocolate" = 2, "caramel" = 1, "puffed rice" = 1) + w_class = 1 + +/obj/item/weapon/reagent_containers/food/snacks/cb02/Initialize() + . = ..() + reagents.add_reagent("sugar", 1) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/cb03 + name = "\improper Aerostat Bar" + desc = "Bubbly milk chocolate." + description_fluff = "An early slogan claimed the chocolate's bubbles where made with 'real Venusian gases', which is thought to have seriously harmed sales. The claim remains true, since the main production plant remains on Venus, but the company tries to avoid association with toxic air." + filling_color = "#552200" + icon = 'icons/obj/food_snacks.dmi' + icon_state = "cb03" + nutriment_amt = 4 + nutriment_desc = list("chocolate" = 4) + w_class = 1 + +/obj/item/weapon/reagent_containers/food/snacks/cb03/Initialize() + . = ..() + reagents.add_reagent("sugar", 1) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/cb04 + name = "\improper Lars' Saltlakris" + desc = "Milk chocolate embedded with chunks of salty licorice." + description_fluff = "Produced exclusively in Kalmar for sale in Vir, Lars' Saltlakris is one of the system's most popular home-grown confectionaries." + filling_color = "#552200" + icon = 'icons/obj/food_snacks.dmi' + icon_state = "cb04" + nutriment_amt = 4 + nutriment_desc = list("chocolate" = 2, "salt = 1", "licorice" = 1) + w_class = 1 + +/obj/item/weapon/reagent_containers/food/snacks/cb04/Initialize() + . = ..() + reagents.add_reagent("sugar", 1) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/cb05 + name = "\improper Andromeda Bar" + desc = "A cheap milk chocolate bar loaded with sugar." + description_fluff = "The galaxy's top-selling chocolate brand for almost 400 years. Also comes in dozens of varieties, including caramel, cookie, fruit and nut, and almond. This is just the basic stuff, though." + filling_color = "#552200" + icon = 'icons/obj/food_snacks.dmi' + icon_state = "cb05" + nutriment_amt = 3 + nutriment_desc = list("milk chocolate" = 2) + w_class = 1 + +/obj/item/weapon/reagent_containers/food/snacks/cb05/Initialize() + . = ..() + reagents.add_reagent("sugar", 3) + bitesize = 3 + +/obj/item/weapon/reagent_containers/food/snacks/cb06 + name = "\improper Mocha Crunch" + desc = "A large latte flavored wafer chocolate bar." + description_fluff = "Lightly caffeinated, the Mocha Crunch is often considered to be more of an authentic coffee taste than most vending machine coffees." + filling_color = "#552200" + icon = 'icons/obj/food_snacks.dmi' + icon_state = "cb06" + nutriment_amt = 4 + nutriment_desc = list("chocolate" = 2, "coffee" = 1, "vanilla wafer" = 1) + w_class = 1 + +/obj/item/weapon/reagent_containers/food/snacks/cb06/Initialize() + . = ..() + reagents.add_reagent("sugar", 1) + bitesize = 3 + +/obj/item/weapon/reagent_containers/food/snacks/cb07 + name = "\improper TaroMilk Bar" + desc = "A light milk chocolate shell with a Taro paste filling. Chewy!" + description_fluff = "The best-selling Kishari snack finally made its way to the galactic stage in 2562. Whether it is here to stay remains to be seen, though it has found some popularity with the Skrell.." + filling_color = "#552200" + icon = 'icons/obj/food_snacks.dmi' + icon_state = "cb07" + nutriment_amt = 4 + nutriment_desc = list("chocolate" = 2, "taro" = 2) + w_class = 1 + +/obj/item/weapon/reagent_containers/food/snacks/cb07/Initialize() + . = ..() + reagents.add_reagent("sugar", 1) + bitesize = 3 + +/obj/item/weapon/reagent_containers/food/snacks/cb08 + name = "\improper Cronk Bar" + desc = "A large puffed malt milk chocolate bar." + description_fluff = "The Cronk Bar proudly 'Comes in one flavour, so you'll never pick the wrong one!'. Its enduring popularity may be in part due to a longstanding deal with the SCG Fleet to include Cronk in standard military rations." + filling_color = "#552200" + icon = 'icons/obj/food_snacks.dmi' + icon_state = "cb08" + nutriment_amt = 3 + nutriment_desc = list("chocolate" = 2, "malt puffs" = 1) + w_class = 1 + +/obj/item/weapon/reagent_containers/food/snacks/cb08/Initialize() + . = ..() + reagents.add_reagent("sugar", 2) + bitesize = 3 + +/obj/item/weapon/reagent_containers/food/snacks/cb09 + name = "\improper Kaju Mamma! Bar" + desc = "A massive cluster of cashews and peanuts covered in a condensed milk solid." + description_fluff = "Based on traditional South Asian desserts, the Kaju Mamma! is a deceptively soft, sweet bar voted 'Most allergenic candy' nineteen years running." + filling_color = "#552200" + icon = 'icons/obj/food_snacks.dmi' + icon_state = "cb09" + nutriment_amt = 6 + nutriment_desc = list("peanuts" = 3, "condensed milk" = 1, "cashews" = 2) + w_class = 1 + +/obj/item/weapon/reagent_containers/food/snacks/cb09/Initialize() + . = ..() + reagents.add_reagent("sugar", 1) + reagents.add_reagent("milk", 1) + bitesize = 3 + +/obj/item/weapon/reagent_containers/food/snacks/cb10 + name = "\improper Shantak Bar" + desc = "Nuts, nougat, peanuts, and caramel covered in chocolate." + description_fluff = "Despite being often mistaken for a regional favourite, the Shantak Bar is sold under different 'localized' names in almost every human system in the galaxy, and adds up to being the third best selling confection produced by Centauri Provisions." + filling_color = "#552200" + icon = 'icons/obj/food_snacks.dmi' + icon_state = "cb10" + nutriment_amt = 5 + nutriment_desc = list("chocolate" = 2, "caramel" = 1, "peanuts" = 1, "nougat" = 1) + w_class = 1 + +/obj/item/weapon/reagent_containers/food/snacks/cb10/Initialize() + . = ..() + bitesize = 3 + reagents.add_reagent("sugar", 1) + reagents.add_reagent("protein", 1) + /obj/item/weapon/reagent_containers/food/snacks/egg name = "egg" desc = "An egg!" @@ -1375,8 +1645,10 @@ /obj/item/weapon/reagent_containers/food/snacks/sosjerky name = "Scaredy's Private Reserve Beef Jerky" + icon = 'icons/obj/food_snacks.dmi' icon_state = "sosjerky" - desc = "Beef jerky made from the finest space cows." + desc = "Beef jerky made from the finest space-reared cows." + description_fluff = "Raising cows in low-gravity environments has the natural result of particularly tender meat. The jerking process largely undoes this apparent benefit, but it's just too damn efficient to ship not to." trash = /obj/item/trash/sosjerky filling_color = "#631212" center_of_mass = list("x"=15, "y"=9) @@ -1388,8 +1660,10 @@ /obj/item/weapon/reagent_containers/food/snacks/no_raisin name = "4no Raisins" + icon = 'icons/obj/food_snacks.dmi' icon_state = "4no_raisins" desc = "Best raisins in the universe. Not sure why." + description_fluff = "The popularity of dried foods across the galaxy is either a direct result of ease of shipping, or a clever marketing ploy by corporations trying to cut back costs. Whatever it is, there must be SOME reason?" trash = /obj/item/trash/raisins filling_color = "#343834" center_of_mass = list("x"=15, "y"=4) @@ -1401,9 +1675,11 @@ reagents.add_reagent("nutriment", 6) /obj/item/weapon/reagent_containers/food/snacks/spacetwinkie - name = "Space Twinkie" + name = "Spacer Snack Cake" + icon = 'icons/obj/food_snacks.dmi' icon_state = "space_twinkie" - desc = "Guaranteed to survive longer then you will." + desc = "Guaranteed to survive longer than you will." + description_fluff = "Despite Spacer advertisements consistently portraying their snack cakes as life-saving, tear-jerking survival food for spacers in all kinds of dramatic scenarios, the Spacer Snack Cake has been statistically proven to lower survival rates on all missions where it is present." filling_color = "#FFE591" center_of_mass = list("x"=15, "y"=11) @@ -1414,8 +1690,10 @@ /obj/item/weapon/reagent_containers/food/snacks/cheesiehonkers name = "Cheesie Honkers" + icon = 'icons/obj/food_snacks.dmi' icon_state = "cheesie_honkers" - desc = "Bite sized cheesie snacks that will honk all over your mouth" + desc = "Bite sized cheesie snacks that will honk all over your mouth." + description_fluff = "The origins of the flourescent orange dust produced by Cheesie Honkers is considered a trade secret, despite having been leaked on the exonet decades ago. It's the cheese." trash = /obj/item/trash/cheesie filling_color = "#FFA305" center_of_mass = list("x"=15, "y"=9) @@ -1428,8 +1706,10 @@ /obj/item/weapon/reagent_containers/food/snacks/syndicake name = "Syndi-Cakes" + icon = 'icons/obj/food_snacks.dmi' icon_state = "syndi_cakes" desc = "An extremely moist snack cake that tastes just as good after being nuked." + description_fluff = "Spacer Snack Cakes' meaner, tastier cousin. The Syndi-Cakes brand was at risk of dissolution in 2429 when it was revealed that the entire production chain was a Nos Amis joint. The brand was quickly aquired by Centauri Provisions and some mild hallucinogenic 'add-ins' were axed from the recipe." filling_color = "#FF5D05" center_of_mass = list("x"=16, "y"=10) trash = /obj/item/trash/syndi_cakes @@ -2433,6 +2713,28 @@ reagents.add_reagent("mint", 1) bitesize = 1 +/obj/item/weapon/reagent_containers/food/snacks/mint/admints + desc = "Spearmint, peppermint's non-festive cousin." + icon = 'icons/obj/food_snacks.dmi' + icon_state = "admint" + +/obj/item/weapon/storage/box/admints + name = "Ad-mints" + desc = "A pack of air fresheners for your mouth." + description_fluff = "Ad-mints earned their name, and reputation when a Major Bill's senior executive attended a meeting at a large a marketing firm and was so astounded by the quality of their complimentary mints, that he immediately bought the company - the mints company, not the ad agency - and began providing 'Ad-mints' on every MBT flight." + icon = 'icons/obj/food_snacks.dmi' + icon_state = "admint_pack" + item_state = "candy" + slot_flags = SLOT_EARS + w_class = 1 + starts_with = list(/obj/item/weapon/reagent_containers/food/snacks/mint/admints = 6) + can_hold = list(/obj/item/weapon/reagent_containers/food/snacks/mint/admints) + use_sound = 'sound/items/drop/paper.ogg' + drop_sound = 'sound/items/drop/wrapper.ogg' + max_storage_space = 6 + foldable = null + trash = /obj/item/trash/admints + /obj/item/weapon/reagent_containers/food/snacks/mushroomsoup name = "chantrelle soup" desc = "A delicious and hearty mushroom soup." @@ -3813,6 +4115,8 @@ /obj/item/weapon/reagent_containers/food/snacks/tastybread name = "bread tube" desc = "Bread in a tube. Chewy...and surprisingly tasty." + description_fluff = "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/food_snacks.dmi' icon_state = "tastybread" trash = /obj/item/trash/tastybread filling_color = "#A66829" @@ -3827,6 +4131,8 @@ /obj/item/weapon/reagent_containers/food/snacks/skrellsnacks name = "\improper SkrellSnax" desc = "Cured fungus shipped all the way from Qerr'balak, almost like jerky! Almost." + description_fluff = "Despite the packaging, most SkrellSnax sold in Vir are produced using locally-grown fungi in controversial Skrell-owned biodomes on the suface of Sif." + icon = 'icons/obj/food_snacks.dmi' icon_state = "skrellsnacks" filling_color = "#A66829" center_of_mass = list("x"=15, "y"=12) @@ -3839,8 +4145,10 @@ /obj/item/weapon/reagent_containers/food/snacks/unajerky name = "Moghes Imported Sissalik Jerky" + icon = 'icons/obj/food_snacks.dmi' icon_state = "unathitinred" desc = "An incredibly well made jerky, shipped in all the way from Moghes." + description_fluff = "The exact meat and spices used in the curing of Sissalik Jerky are a well-kept secret, and thought to not exist at all outside of Hegemony space. Many have tried to replicate the flavour, but none have come close, so the brand remains a highly prized import." trash = /obj/item/trash/unajerky filling_color = "#631212" center_of_mass = list("x"=15, "y"=9) @@ -4529,8 +4837,8 @@ center_of_mass = list("x"=16, "y"=16) do_coating_prefix = 0 bitesize = 2 - - + + /obj/item/weapon/reagent_containers/food/snacks/sausage/battered/Initialize() . = ..() reagents.add_reagent("protein", 6) @@ -4561,7 +4869,7 @@ icon_state = "ratburger" center_of_mass = list("x"=16, "y"=11) bitesize = 2 - + /obj/item/weapon/reagent_containers/food/snacks/mouseburger/Initialize() . = ..() reagents.add_reagent("protein", 4) @@ -6036,7 +6344,7 @@ /obj/item/weapon/reagent_containers/food/snacks/cosmicbrowniesslice/filled/Initialize() . = ..() reagents.add_reagent("protein", 1) - + /obj/item/weapon/reagent_containers/food/snacks/lasagna name = "lasagna" desc = "Meaty, tomato-y, and ready to eat-y. Favorite of cats." diff --git a/code/modules/food/kitchen/cooking_machines/_appliance.dm b/code/modules/food/kitchen/cooking_machines/_appliance.dm index d8c4e761ca2..297dc688f42 100644 --- a/code/modules/food/kitchen/cooking_machines/_appliance.dm +++ b/code/modules/food/kitchen/cooking_machines/_appliance.dm @@ -182,7 +182,7 @@ //Handles all validity checking and error messages for inserting things /obj/machinery/appliance/proc/can_insert(var/obj/item/I, var/mob/user) - if (istype(I.loc, /mob/living/silicon)) + if (istype(I, /obj/item/weapon/gripper)) return 0 else if (istype(I.loc, /obj/item/rig_module)) return 0 diff --git a/code/modules/gamemaster/event2/events/security/swarm_boarder.dm b/code/modules/gamemaster/event2/events/security/swarm_boarder.dm index 283333c6796..54dc03189b6 100644 --- a/code/modules/gamemaster/event2/events/security/swarm_boarder.dm +++ b/code/modules/gamemaster/event2/events/security/swarm_boarder.dm @@ -5,6 +5,7 @@ departments = list(DEPARTMENT_EVERYONE, DEPARTMENT_SECURITY, DEPARTMENT_ENGINEERING) chaos = 60 chaotic_threshold = EVENT_CHAOS_THRESHOLD_HIGH_IMPACT + enabled = FALSE // Turns out they are in fact grossly OP. var/safe_for_extended = FALSE /datum/event2/meta/swarm_boarder/get_weight() diff --git a/code/modules/materials/material_recipes.dm b/code/modules/materials/material_recipes.dm index 2efef5783ff..b852e10383a 100644 --- a/code/modules/materials/material_recipes.dm +++ b/code/modules/materials/material_recipes.dm @@ -139,6 +139,7 @@ recipes += new/datum/stack_recipe("lampshade", /obj/item/weapon/lampshade, 1, time = 1, pass_stack_color = TRUE) recipes += new/datum/stack_recipe("plastic net", /obj/item/weapon/material/fishing_net, 25, time = 1 MINUTE, pass_stack_color = TRUE) recipes += new/datum/stack_recipe("plastic fishtank", /obj/item/glass_jar/fish/plastic, 2, time = 30 SECONDS) + recipes += new/datum/stack_recipe("reagent tubing", /obj/item/stack/hose, 1, 4, 20, pass_stack_color = TRUE) /material/wood/generate_recipes() ..() diff --git a/code/modules/materials/materials.dm b/code/modules/materials/materials.dm index eb1a76b32c5..012e64b4ecb 100644 --- a/code/modules/materials/materials.dm +++ b/code/modules/materials/materials.dm @@ -824,6 +824,7 @@ var/list/name_to_material name = "alienalloy" display_name = "durable alloy" stack_type = null + flags = MATERIAL_UNMELTABLE icon_colour = "#6C7364" integrity = 1200 melting_point = 6000 // Hull plating. diff --git a/code/modules/mining/abandonedcrates.dm b/code/modules/mining/abandonedcrates.dm index 7c866dd5700..199b1ed0d0a 100644 --- a/code/modules/mining/abandonedcrates.dm +++ b/code/modules/mining/abandonedcrates.dm @@ -58,7 +58,7 @@ if(53 to 54) new/obj/item/latexballon(src) if(55 to 56) - var/newitem = pick(typesof(/obj/item/toy/prize) - /obj/item/toy/prize) + var/newitem = pick(typesof(/obj/item/toy/mecha) - /obj/item/toy/mecha) new newitem(src) if(57 to 58) new/obj/item/toy/syndicateballoon(src) diff --git a/code/modules/mining/machine_processing.dm b/code/modules/mining/machine_processing.dm index 03b23b15a64..93c711b6beb 100644 --- a/code/modules/mining/machine_processing.dm +++ b/code/modules/mining/machine_processing.dm @@ -33,7 +33,10 @@ /obj/machinery/mineral/processing_unit_console/attack_hand(mob/user) if(..()) return - interact(user) + if(!allowed(user)) + to_chat(user, "Access denied.") + return + tgui_interact(user) /obj/machinery/mineral/processing_unit_console/attackby(var/obj/item/I, var/mob/user) if(istype(I, /obj/item/weapon/card/id)) @@ -42,97 +45,89 @@ if(!inserted_id && user.unEquip(I)) I.forceMove(src) inserted_id = I - interact(user) + SStgui.update_uis(src) return ..() -/obj/machinery/mineral/processing_unit_console/interact(mob/user) - if(..()) - return +/obj/machinery/mineral/processing_unit_console/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "MiningOreProcessingConsole", name) + ui.open() - if(!allowed(user)) - to_chat(user, "Access denied.") - return +/obj/machinery/mineral/processing_unit_console/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() + data["unclaimedPoints"] = machine.points - user.set_machine(src) - - var/dat = "

Ore processor console

" - - dat += "Current unclaimed points: [machine.points]
" - if(istype(inserted_id)) - dat += "You have [inserted_id.mining_points] mining points collected. Eject ID.
" - dat += "Claim points.
" + if(inserted_id) + data["has_id"] = TRUE + data["id"] = list( + "name" = inserted_id.registered_name, + "points" = inserted_id.mining_points, + ) else - dat += "No ID inserted. Insert ID.
" - - dat += "
" - . += "" + var/prefLevelLabel = "ERROR" + var/prefLevelColor = "pink" + var/prefUpperLevel = -1 // level to assign on left click + var/prefLowerLevel = -1 // level to assign on right click + if(pref.GetJobDepartment(job, 1) & job.flag) + prefLevelLabel = "High" + prefLevelColor = "55cc55" + prefUpperLevel = 4 + prefLowerLevel = 2 + else if(pref.GetJobDepartment(job, 2) & job.flag) + prefLevelLabel = "Medium" + prefLevelColor = "eecc22" + prefUpperLevel = 1 + prefLowerLevel = 3 + else if(pref.GetJobDepartment(job, 3) & job.flag) + prefLevelLabel = "Low" + prefLevelColor = "cc5555" + prefUpperLevel = 2 + prefLowerLevel = 4 + else + prefLevelLabel = "NEVER" + prefLevelColor = "black" + prefUpperLevel = 3 + prefLowerLevel = 1 + + . += "" if(job.type == /datum/job/assistant)//Assistant is special if(pref.job_civilian_low & ASSISTANT) @@ -174,14 +200,7 @@ . += "
 \[[pref.GetPlayerAltTitle(job)]\]
" + data["has_id"] = FALSE + data["ores"] = list() for(var/ore in machine.ores_processing) - - if(!machine.ores_stored[ore] && !show_all_ores) continue + if(!machine.ores_stored[ore] && !show_all_ores) + continue var/ore/O = ore_data[ore] - if(!O) continue - dat += "" + if(!O) + continue + data["ores"].Add(list(list( + "ore" = ore, + "name" = O.display_name, + "amount" = machine.ores_stored[ore], + "processing" = machine.ores_processing[ore] ? machine.ores_processing[ore] : 0, + ))) - dat += "
[capitalize(O.display_name)][machine.ores_stored[ore]]" - if(machine.ores_processing[ore]) - switch(machine.ores_processing[ore]) - if(PROCESS_NONE) - dat += "not processing" - if(PROCESS_SMELT) - dat += "smelting" - if(PROCESS_COMPRESS) - dat += "compressing" - if(PROCESS_ALLOY) - dat += "alloying" - else - dat += "not processing" - dat += ".\[change\]

" - dat += "Currently displaying [show_all_ores ? "all ore types" : "only available ore types"]. \[[show_all_ores ? "show less" : "show more"]\]
" - dat += "The ore processor is currently [(machine.active ? "processing" : "disabled")]." - user << browse(dat, "window=processor_console;size=400x500") - onclose(user, "processor_console") - return + data["showAllOres"] = show_all_ores + data["power"] = machine.active -/obj/machinery/mineral/processing_unit_console/Topic(href, href_list) + return data + +/obj/machinery/mineral/processing_unit_console/tgui_act(action, list/params) if(..()) - return 1 - usr.set_machine(src) - src.add_fingerprint(usr) + return TRUE - if(href_list["toggle_smelting"]) - - var/choice = input("What setting do you wish to use for processing [href_list["toggle_smelting"]]?") as null|anything in list("Smelting","Compressing","Alloying","Nothing") - if(!choice) return - - switch(choice) - if("Nothing") choice = PROCESS_NONE - if("Smelting") choice = PROCESS_SMELT - if("Compressing") choice = PROCESS_COMPRESS - if("Alloying") choice = PROCESS_ALLOY - - machine.ores_processing[href_list["toggle_smelting"]] = choice - - if(href_list["toggle_power"]) - - machine.active = !machine.active - - if(href_list["toggle_ores"]) - - show_all_ores = !show_all_ores - - if(href_list["choice"]) - if(istype(inserted_id)) - if(href_list["choice"] == "eject") - usr.put_in_hands(inserted_id) - inserted_id = null - if(href_list["choice"] == "claim") + add_fingerprint(usr) + switch(action) + if("toggleSmelting") + var/ore = params["ore"] + var/new_setting = params["set"] + if(new_setting == null) + new_setting = input("What setting do you wish to use for processing [ore]]?") as null|anything in list("Smelting","Compressing","Alloying","Nothing") + if(!new_setting) + return + switch(new_setting) + if("Nothing") new_setting = PROCESS_NONE + if("Smelting") new_setting = PROCESS_SMELT + if("Compressing") new_setting = PROCESS_COMPRESS + if("Alloying") new_setting = PROCESS_ALLOY + machine.ores_processing[ore] = new_setting + . = TRUE + if("power") + machine.active = !machine.active + . = TRUE + if("showAllOres") + show_all_ores = !show_all_ores + . = TRUE + if("logoff") + if(!inserted_id) + return + usr.put_in_hands(inserted_id) + inserted_id = null + . = TRUE + if("claim") + if(istype(inserted_id)) if(access_mining_station in inserted_id.access) inserted_id.mining_points += machine.points machine.points = 0 else to_chat(usr, "Required access not found.") - else if(href_list["choice"] == "insert") + . = TRUE + if("insert") var/obj/item/weapon/card/id/I = usr.get_active_hand() if(istype(I)) usr.drop_item() @@ -140,9 +135,9 @@ inserted_id = I else to_chat(usr, "No valid ID.") - - src.updateUsrDialog() - return + . = TRUE + else + return FALSE /**********************Mineral processing unit**************************/ diff --git a/code/modules/mining/machine_stacking.dm b/code/modules/mining/machine_stacking.dm index ec6b7623df6..c1d6c4ee4c3 100644 --- a/code/modules/mining/machine_stacking.dm +++ b/code/modules/mining/machine_stacking.dm @@ -25,46 +25,47 @@ /obj/machinery/mineral/stacking_unit_console/attack_hand(mob/user) add_fingerprint(user) - interact(user) + tgui_interact(user) -/obj/machinery/mineral/stacking_unit_console/interact(mob/user) - user.set_machine(src) +/obj/machinery/mineral/stacking_unit_console/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "MiningStackingConsole", name) + ui.open() - var/dat - - dat += text("

Stacking unit console


") +/obj/machinery/mineral/stacking_unit_console/tgui_data(mob/user) + var/list/data = ..() + data["stacktypes"] = list() for(var/stacktype in machine.stack_storage) if(machine.stack_storage[stacktype] > 0) - dat += "" - dat += "
[capitalize(stacktype)]:[machine.stack_storage[stacktype]]\[release\]

" - dat += text("
Stacking: [machine.stack_amt] \[change\]

") + data["stacktypes"].Add(list(list( + "type" = stacktype, + "amt" = machine.stack_storage[stacktype], + ))) + data["stackingAmt"] = machine.stack_amt + return data - user << browse("[dat]", "window=console_stacking_machine") - onclose(user, "console_stacking_machine") - - -/obj/machinery/mineral/stacking_unit_console/Topic(href, href_list) +/obj/machinery/mineral/stacking_unit_console/tgui_act(action, list/params) if(..()) - return 1 + return TRUE - if(href_list["change_stack"]) - var/choice = input("What would you like to set the stack amount to?") as null|anything in list(1,5,10,20,50) - if(!choice) return - machine.stack_amt = choice + switch(action) + if("change_stack") + machine.stack_amt = clamp(text2num(params["amt"]), 1, 50) + . = TRUE - if(href_list["release_stack"]) - if(machine.stack_storage[href_list["release_stack"]] > 0) - var/stacktype = machine.stack_paths[href_list["release_stack"]] - var/obj/item/stack/material/S = new stacktype (get_turf(machine.output)) - S.amount = machine.stack_storage[href_list["release_stack"]] - machine.stack_storage[href_list["release_stack"]] = 0 - S.update_icon() + if("release_stack") + var/stack = params["stack"] + if(machine.stack_storage[stack] > 0) + var/stacktype = machine.stack_paths[stack] + var/obj/item/stack/material/S = new stacktype(get_turf(machine.output)) + S.amount = machine.stack_storage[stack] + machine.stack_storage[stack] = 0 + S.update_icon() + . = TRUE - src.add_fingerprint(usr) - src.updateUsrDialog() - - return + add_fingerprint(usr) /**********************Mineral stacking unit**************************/ diff --git a/code/modules/mining/mineral_effect.dm b/code/modules/mining/mineral_effect.dm index b5b3d1a1924..9406231c566 100644 --- a/code/modules/mining/mineral_effect.dm +++ b/code/modules/mining/mineral_effect.dm @@ -7,11 +7,14 @@ anchored = 1 var/ore_key var/image/scanner_image + var/ore_reagent // Reagent from pumping water near this ore. /obj/effect/mineral/New(var/newloc, var/ore/M) ..(newloc) name = "[M.display_name] deposit" ore_key = M.name + if(M.reagent) + ore_reagent = M.reagent icon_state = "rock_[ore_key]" var/turf/T = get_turf(src) layer = T.layer+0.1 diff --git a/code/modules/mining/ore_datum.dm b/code/modules/mining/ore_datum.dm index f888ae3bb63..0bca24db1f9 100644 --- a/code/modules/mining/ore_datum.dm +++ b/code/modules/mining/ore_datum.dm @@ -17,6 +17,7 @@ var/global/list/ore_data = list() "million" = 999 ) var/xarch_source_mineral = "iron" + var/reagent = "silicate" /ore/New() . = ..() @@ -36,6 +37,7 @@ var/global/list/ore_data = list() "million" = 704 ) xarch_source_mineral = "potassium" + reagent = "uranium" /ore/hematite name = "hematite" @@ -46,6 +48,7 @@ var/global/list/ore_data = list() spread_chance = 25 ore = /obj/item/weapon/ore/iron scan_icon = "mineral_common" + reagent = "iron" /ore/coal name = "carbon" @@ -57,6 +60,7 @@ var/global/list/ore_data = list() spread_chance = 25 ore = /obj/item/weapon/ore/coal scan_icon = "mineral_common" + reagent = "carbon" /ore/glass name = "sand" @@ -81,6 +85,7 @@ var/global/list/ore_data = list() "billion_lower" = 10 ) xarch_source_mineral = "phoron" + reagent = "phoron" /ore/silver name = "silver" @@ -90,6 +95,7 @@ var/global/list/ore_data = list() spread_chance = 10 ore = /obj/item/weapon/ore/silver scan_icon = "mineral_uncommon" + reagent = "silver" /ore/gold smelts_to = "gold" @@ -105,6 +111,7 @@ var/global/list/ore_data = list() "billion" = 4, "billion_lower" = 3 ) + reagent = "gold" /ore/diamond name = "diamond" @@ -116,6 +123,7 @@ var/global/list/ore_data = list() ore = /obj/item/weapon/ore/diamond scan_icon = "mineral_rare" xarch_source_mineral = "nitrogen" + reagent = "carbon" /ore/platinum name = "platinum" @@ -127,6 +135,7 @@ var/global/list/ore_data = list() spread_chance = 10 ore = /obj/item/weapon/ore/osmium scan_icon = "mineral_rare" + reagent = "platinum" /ore/hydrogen name = "mhydrogen" @@ -134,6 +143,7 @@ var/global/list/ore_data = list() smelts_to = "tritium" compresses_to = "mhydrogen" scan_icon = "mineral_rare" + reagent = "hydrogen" /ore/verdantium name = MAT_VERDANTIUM @@ -156,6 +166,7 @@ var/global/list/ore_data = list() spread_chance = 10 ore = /obj/item/weapon/ore/marble scan_icon = "mineral_common" + reagent = "calciumcarbonate" /ore/lead name = MAT_LEAD @@ -165,3 +176,4 @@ var/global/list/ore_data = list() spread_chance = 20 ore = /obj/item/weapon/ore/lead scan_icon = "mineral_rare" + reagent = "lead" diff --git a/code/modules/mining/ore_redemption_machine/equipment_vendor.dm b/code/modules/mining/ore_redemption_machine/equipment_vendor.dm index 822dccaf577..2f388e2ba54 100644 --- a/code/modules/mining/ore_redemption_machine/equipment_vendor.dm +++ b/code/modules/mining/ore_redemption_machine/equipment_vendor.dm @@ -1,3 +1,9 @@ +// Use this define to register something as a purchasable! +// * n — The proper name of the purchasable +// * o — The object type path of the purchasable to spawn +// * p — The price of the purchasable in mining points +#define EQUIPMENT(n, o, p) n = new /datum/data/mining_equipment(n, o, p) + /**********************Mining Equipment Locker**************************/ /obj/machinery/mineral/equipment_vendor @@ -11,81 +17,8 @@ var/icon_vend = "adh-tool-vend" circuit = /obj/item/weapon/circuitboard/mining_equipment_vendor var/obj/item/weapon/card/id/inserted_id - //VOREStation Edit Start - Heavily modified list - var/list/prize_list = list( - new /datum/data/mining_equipment("1 Marker Beacon", /obj/item/stack/marker_beacon, 10), - new /datum/data/mining_equipment("10 Marker Beacons", /obj/item/stack/marker_beacon/ten, 100), - new /datum/data/mining_equipment("30 Marker Beacons", /obj/item/stack/marker_beacon/thirty, 300), - new /datum/data/mining_equipment("Whiskey", /obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey, 125), - new /datum/data/mining_equipment("Absinthe", /obj/item/weapon/reagent_containers/food/drinks/bottle/absinthe, 125), - new /datum/data/mining_equipment("Cigar", /obj/item/clothing/mask/smokable/cigarette/cigar/havana, 150), - new /datum/data/mining_equipment("Soap", /obj/item/weapon/soap/nanotrasen, 200), - new /datum/data/mining_equipment("Laser Pointer", /obj/item/device/laser_pointer, 900), - new /datum/data/mining_equipment("Geiger Counter", /obj/item/device/geiger, 750), - new /datum/data/mining_equipment("Plush Toy", /obj/random/plushie, 300), - new /datum/data/mining_equipment("GPS Device", /obj/item/device/gps/mining, 100), - // TODO new /datum/data/mining_equipment("Advanced Scanner", /obj/item/device/t_scanner/adv_mining_scanner, 800), - new /datum/data/mining_equipment("Fulton Beacon", /obj/item/fulton_core, 500), - new /datum/data/mining_equipment("Shelter Capsule", /obj/item/device/survivalcapsule, 500), - // TODO new /datum/data/mining_equipment("Explorer's Webbing", /obj/item/storage/belt/mining, 500), - new /datum/data/mining_equipment("Umbrella", /obj/item/weapon/melee/umbrella/random, 200), - new /datum/data/mining_equipment("Point Transfer Card", /obj/item/weapon/card/mining_point_card, 500), - new /datum/data/mining_equipment("Trauma Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/trauma, 250), - new /datum/data/mining_equipment("Burn Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/burn, 250), - new /datum/data/mining_equipment("Oxy Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/oxy, 250), - new /datum/data/mining_equipment("Detox Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/detox, 250), - new /datum/data/mining_equipment("Mini-Translocator", /obj/item/device/perfect_tele/one_beacon, 1200), - // new /datum/data/mining_equipment("Kinetic Crusher", /obj/item/twohanded/required/kinetic_crusher, 750), - new /datum/data/mining_equipment("Kinetic Accelerator", /obj/item/weapon/gun/energy/kinetic_accelerator, 900), - new /datum/data/mining_equipment("Resonator", /obj/item/resonator, 900), - new /datum/data/mining_equipment("Fulton Pack", /obj/item/extraction_pack, 1200), - new /datum/data/mining_equipment("Silver Pickaxe", /obj/item/weapon/pickaxe/silver, 1200), - // new /datum/data/mining_equipment("Mining Conscription Kit", /obj/item/storage/backpack/duffelbag/mining_conscript, 1000), - new /datum/data/mining_equipment("Thalers - 100", /obj/item/weapon/spacecash/c100, 1000), - new /datum/data/mining_equipment("Hardsuit - Control Module", /obj/item/weapon/rig/industrial/vendor, 2000), - new /datum/data/mining_equipment("Hardsuit - Plasma Cutter", /obj/item/rig_module/device/plasmacutter, 800), - new /datum/data/mining_equipment("Hardsuit - Drill", /obj/item/rig_module/device/drill, 5000), - new /datum/data/mining_equipment("Hardsuit - Ore Scanner", /obj/item/rig_module/device/orescanner, 1000), - new /datum/data/mining_equipment("Hardsuit - Material Scanner", /obj/item/rig_module/vision/material, 500), - new /datum/data/mining_equipment("Hardsuit - Maneuvering Jets", /obj/item/rig_module/maneuvering_jets, 1250), - new /datum/data/mining_equipment("Hardsuit - Intelligence Storage", /obj/item/rig_module/ai_container, 2500), - new /datum/data/mining_equipment("Hardsuit - Smoke Bomb Deployer", /obj/item/rig_module/grenade_launcher/smoke, 2000), - new /datum/data/mining_equipment("Industrial Equipment - Phoron Bore", /obj/item/weapon/gun/magnetic/matfed, 3000), - new /datum/data/mining_equipment("Industrial Equipment - Sheet-Snatcher",/obj/item/weapon/storage/bag/sheetsnatcher, 500), - new /datum/data/mining_equipment("Digital Tablet - Standard", /obj/item/modular_computer/tablet/preset/custom_loadout/standard, 500), - new /datum/data/mining_equipment("Digital Tablet - Advanced", /obj/item/modular_computer/tablet/preset/custom_loadout/advanced, 1000), - // new /datum/data/mining_equipment("Diamond Pickaxe", /obj/item/weapon/pickaxe/diamond, 2000), - new /datum/data/mining_equipment("Super Resonator", /obj/item/resonator/upgraded, 2500), - new /datum/data/mining_equipment("Jump Boots", /obj/item/clothing/shoes/bhop, 2500), - new /datum/data/mining_equipment("Luxury Shelter Capsule", /obj/item/device/survivalcapsule/luxury, 3100), - new /datum/data/mining_equipment("Bar Shelter Capsule", /obj/item/device/survivalcapsule/luxurybar, 10000), - new /datum/data/mining_equipment("KA White Tracer Rounds", /obj/item/borg/upgrade/modkit/tracer, 125), - new /datum/data/mining_equipment("KA Adjustable Tracer Rounds", /obj/item/borg/upgrade/modkit/tracer/adjustable, 175), - new /datum/data/mining_equipment("KA Super Chassis", /obj/item/borg/upgrade/modkit/chassis_mod, 250), - new /datum/data/mining_equipment("KA Hyper Chassis", /obj/item/borg/upgrade/modkit/chassis_mod/orange, 300), - new /datum/data/mining_equipment("KA Range Increase", /obj/item/borg/upgrade/modkit/range, 1000), - new /datum/data/mining_equipment("KA Damage Increase", /obj/item/borg/upgrade/modkit/damage, 1000), - new /datum/data/mining_equipment("KA Efficiency Increase", /obj/item/borg/upgrade/modkit/efficiency, 1200), - new /datum/data/mining_equipment("KA AoE Damage", /obj/item/borg/upgrade/modkit/aoe/mobs, 2000), - new /datum/data/mining_equipment("KA Holster", /obj/item/clothing/accessory/holster/waist/kinetic_accelerator, 350), - new /datum/data/mining_equipment("Fine Excavation Kit - Chisels",/obj/item/weapon/storage/excavation, 500), - new /datum/data/mining_equipment("Fine Excavation Kit - Measuring Tape",/obj/item/device/measuring_tape, 125), - new /datum/data/mining_equipment("Fine Excavation Kit - Hand Pick",/obj/item/weapon/pickaxe/hand, 375), - new /datum/data/mining_equipment("Explosive Excavation Kit - Plastic Charge",/obj/item/weapon/plastique/seismic/locked, 1500), - new /datum/data/mining_equipment("Injector (L) - Glucose",/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/glucose, 500), - new /datum/data/mining_equipment("Injector (L) - Panacea",/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/purity, 500), - new /datum/data/mining_equipment("Injector (L) - Trauma",/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/brute, 500), - new /datum/data/mining_equipment("Nanopaste Tube", /obj/item/stack/nanopaste, 1000), - new /datum/data/mining_equipment("Defense Equipment - Smoke Bomb",/obj/item/weapon/grenade/smokebomb, 100), - new /datum/data/mining_equipment("Defense Equipment - Razor Drone Deployer",/obj/item/weapon/grenade/spawnergrenade/manhacks/station/locked, 1000), - new /datum/data/mining_equipment("Defense Equipment - Sentry Drone Deployer",/obj/item/weapon/grenade/spawnergrenade/ward, 1500), - new /datum/data/mining_equipment("Defense Equipment - Plasteel Machete", /obj/item/weapon/material/knife/machete, 500), - new /datum/data/mining_equipment("Fishing Net", /obj/item/weapon/material/fishing_net, 500), - new /datum/data/mining_equipment("Titanium Fishing Rod", /obj/item/weapon/material/fishing_rod/modern, 1000), - new /datum/data/mining_equipment("Durasteel Fishing Rod", /obj/item/weapon/material/fishing_rod/modern/strong, 7500), - new /datum/data/mining_equipment("Survival Equipment - Insulated Poncho", /obj/random/thermalponcho, 750) - ) - //VOREStation Edit End + var/list/prize_list // Initialized just below! (if you're wondering why - check CONTRIBUTING.md, look for: "hidden" init proc) + var/dirty_items = FALSE // Used to refresh the static/redundant data in case the machine gets VV'd /datum/data/mining_equipment var/equipment_name = "generic" @@ -97,9 +30,96 @@ src.equipment_path = path src.cost = cost -/obj/machinery/power/quantumpad/Initialize() +/obj/machinery/mineral/equipment_vendor/Initialize(mapload) . = ..() - default_apply_parts() + //VOREStation Edit Start - Heavily modified list + prize_list = list() + prize_list["Gear"] = list( + // TODO EQUIPMENT("Advanced Scanner", /obj/item/device/t_scanner/adv_mining_scanner, 800), + // TODO EQUIPMENT("Explorer's Webbing", /obj/item/storage/belt/mining, 500), + EQUIPMENT("Defense Equipment - Plasteel Machete", /obj/item/weapon/material/knife/machete, 500), + EQUIPMENT("Defense Equipment - Razor Drone Deployer", /obj/item/weapon/grenade/spawnergrenade/manhacks/station/locked, 1000), + EQUIPMENT("Defense Equipment - Sentry Drone Deployer", /obj/item/weapon/grenade/spawnergrenade/ward, 1500), + EQUIPMENT("Defense Equipment - Smoke Bomb", /obj/item/weapon/grenade/smokebomb, 100), + EQUIPMENT("Durasteel Fishing Rod", /obj/item/weapon/material/fishing_rod/modern/strong, 7500), + EQUIPMENT("Titanium Fishing Rod", /obj/item/weapon/material/fishing_rod/modern, 1000), + EQUIPMENT("Fishing Net", /obj/item/weapon/material/fishing_net, 500), + EQUIPMENT("Fulton Beacon", /obj/item/fulton_core, 500), + EQUIPMENT("Geiger Counter", /obj/item/device/geiger, 750), + EQUIPMENT("GPS Device", /obj/item/device/gps/mining, 100), + // EQUIPMENT("Mining Conscription Kit", /obj/item/storage/backpack/duffelbag/mining_conscript, 1000), + EQUIPMENT("Jump Boots", /obj/item/clothing/shoes/bhop, 2500), + EQUIPMENT("Mini-Translocator", /obj/item/device/perfect_tele/one_beacon, 1200), + EQUIPMENT("Survival Equipment - Insulated Poncho", /obj/random/thermalponcho, 750), + + ) + prize_list["Consumables"] = list( + EQUIPMENT("1 Marker Beacon", /obj/item/stack/marker_beacon, 1), + EQUIPMENT("10 Marker Beacons", /obj/item/stack/marker_beacon/ten, 10), + EQUIPMENT("30 Marker Beacons", /obj/item/stack/marker_beacon/thirty, 30), + EQUIPMENT("Fulton Pack", /obj/item/extraction_pack, 1200), + EQUIPMENT("Injector (L) - Glucose", /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/glucose, 500), + EQUIPMENT("Injector (L) - Panacea", /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/purity, 500), + EQUIPMENT("Injector (L) - Trauma", /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/brute, 500), + EQUIPMENT("Nanopaste Tube", /obj/item/stack/nanopaste, 1000), + EQUIPMENT("Point Transfer Card", /obj/item/weapon/card/mining_point_card, 500), + EQUIPMENT("Shelter Capsule", /obj/item/device/survivalcapsule, 500), + EQUIPMENT("Burn Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/burn, 250), + EQUIPMENT("Detox Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/detox, 250), + EQUIPMENT("Oxy Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/oxy, 250), + EQUIPMENT("Trauma Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/trauma, 250), + ) + prize_list["Kinetic Accelerator"] = list( + EQUIPMENT("Kinetic Accelerator", /obj/item/weapon/gun/energy/kinetic_accelerator, 900), + EQUIPMENT("KA AoE Damage", /obj/item/borg/upgrade/modkit/aoe/mobs, 2000), + EQUIPMENT("KA Damage Increase", /obj/item/borg/upgrade/modkit/damage, 1000), + EQUIPMENT("KA Efficiency Increase", /obj/item/borg/upgrade/modkit/efficiency, 1200), + EQUIPMENT("KA Range Increase", /obj/item/borg/upgrade/modkit/range, 1000), + EQUIPMENT("KA Holster", /obj/item/clothing/accessory/holster/waist/kinetic_accelerator, 350), + EQUIPMENT("KA Super Chassis", /obj/item/borg/upgrade/modkit/chassis_mod, 250), + EQUIPMENT("KA Hyper Chassis", /obj/item/borg/upgrade/modkit/chassis_mod/orange, 300), + EQUIPMENT("KA Adjustable Tracer Rounds",/obj/item/borg/upgrade/modkit/tracer/adjustable, 175), + EQUIPMENT("KA White Tracer Rounds", /obj/item/borg/upgrade/modkit/tracer, 125), + ) + prize_list["Digging Tools"] = list( + // EQUIPMENT("Diamond Pickaxe", /obj/item/weapon/pickaxe/diamond, 2000), + // EQUIPMENT("Kinetic Crusher", /obj/item/twohanded/required/kinetic_crusher, 750), + EQUIPMENT("Resonator", /obj/item/resonator, 900), + EQUIPMENT("Silver Pickaxe", /obj/item/weapon/pickaxe/silver, 1200), + EQUIPMENT("Super Resonator", /obj/item/resonator/upgraded, 2500), + EQUIPMENT("Fine Excavation Kit - Chisels", /obj/item/weapon/storage/excavation, 500), + EQUIPMENT("Fine Excavation Kit - Measuring Tape", /obj/item/device/measuring_tape, 125), + EQUIPMENT("Fine Excavation Kit - Hand Pick", /obj/item/weapon/pickaxe/hand, 375), + EQUIPMENT("Explosive Excavation Kit - Plastic Charge",/obj/item/weapon/plastique/seismic/locked, 1500), + EQUIPMENT("Industrial Equipment - Phoron Bore", /obj/item/weapon/gun/magnetic/matfed, 3000), + EQUIPMENT("Industrial Equipment - Sheet-Snatcher",/obj/item/weapon/storage/bag/sheetsnatcher, 500), + ) + prize_list["Hardsuit"] = list( + EQUIPMENT("Hardsuit - Control Module", /obj/item/weapon/rig/industrial/vendor, 2000), + EQUIPMENT("Hardsuit - Drill", /obj/item/rig_module/device/drill, 5000), + EQUIPMENT("Hardsuit - Intelligence Storage",/obj/item/rig_module/ai_container, 2500), + EQUIPMENT("Hardsuit - Maneuvering Jets", /obj/item/rig_module/maneuvering_jets, 1250), + EQUIPMENT("Hardsuit - Material Scanner", /obj/item/rig_module/vision/material, 500), + EQUIPMENT("Hardsuit - Ore Scanner", /obj/item/rig_module/device/orescanner, 1000), + EQUIPMENT("Hardsuit - Plasma Cutter", /obj/item/rig_module/device/plasmacutter, 800), + EQUIPMENT("Hardsuit - Smoke Bomb Deployer", /obj/item/rig_module/grenade_launcher/smoke,2000), + ) + prize_list["Miscellaneous"] = list( + EQUIPMENT("Absinthe", /obj/item/weapon/reagent_containers/food/drinks/bottle/absinthe, 125), + EQUIPMENT("Cigar", /obj/item/clothing/mask/smokable/cigarette/cigar/havana, 150), + EQUIPMENT("Digital Tablet - Standard", /obj/item/modular_computer/tablet/preset/custom_loadout/standard, 500), + EQUIPMENT("Digital Tablet - Advanced", /obj/item/modular_computer/tablet/preset/custom_loadout/advanced, 1000), + EQUIPMENT("Laser Pointer", /obj/item/device/laser_pointer, 900), + EQUIPMENT("Luxury Shelter Capsule", /obj/item/device/survivalcapsule/luxury, 3100), + EQUIPMENT("Bar Shelter Capsule", /obj/item/device/survivalcapsule/luxurybar, 10000), + EQUIPMENT("Plush Toy", /obj/random/plushie, 300), + EQUIPMENT("Soap", /obj/item/weapon/soap/nanotrasen, 200), + EQUIPMENT("Thalers - 100", /obj/item/weapon/spacecash/c100, 1000), + EQUIPMENT("Umbrella", /obj/item/weapon/melee/umbrella/random, 200), + EQUIPMENT("Whiskey", /obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey, 125), + ) + prize_list["Extra"] = list() // Used in child vendors + //VOREStation Edit End /obj/machinery/mineral/equipment_vendor/power_change() var/old_stat = stat @@ -126,73 +146,104 @@ /obj/machinery/mineral/equipment_vendor/attack_hand(mob/user) if(..()) return - interact(user) + tgui_interact(user) /obj/machinery/mineral/equipment_vendor/attack_ghost(mob/user) - interact(user) + tgui_interact(user) -/obj/machinery/mineral/equipment_vendor/interact(mob/user) - user.set_machine(src) +/obj/machinery/mineral/equipment_vendor/tgui_data(mob/user) + var/list/data = ..() - var/dat - dat +="
" - if(istype(inserted_id)) - dat += "You have [inserted_id.mining_points] mining points collected. Eject ID.
" + // ID + if(inserted_id) + data["has_id"] = TRUE + data["id"] = list() + data["id"]["name"] = inserted_id.registered_name + data["id"]["points"] = get_points(inserted_id) else - dat += "No ID inserted. Insert ID.
" - dat += "
" - dat += "
Equipment point cost list:
" - for(var/datum/data/mining_equipment/prize in prize_list) - dat += "" - dat += "
[prize.equipment_name][prize.cost]Purchase
" - var/datum/browser/popup = new(user, "miningvendor", "Mining Equipment Vendor", 400, 600) - popup.set_content(dat) - popup.open() + data["has_id"] = FALSE -/obj/machinery/mineral/equipment_vendor/Topic(href, href_list) + return data + +/obj/machinery/mineral/equipment_vendor/proc/get_points(obj/item/weapon/card/id/target) + if(!istype(target)) + return 0 + return target.mining_points + +/obj/machinery/mineral/equipment_vendor/proc/remove_points(obj/item/weapon/card/id/target, amt) + target.mining_points -= amt + +/obj/machinery/mineral/equipment_vendor/tgui_static_data(mob/user) + var/list/static_data[0] + + // Available items - in static data because we don't wanna compute this list every time! It hardly changes. + static_data["items"] = list() + for(var/cat in prize_list) + var/list/cat_items = list() + for(var/prize_name in prize_list[cat]) + var/datum/data/mining_equipment/prize = prize_list[cat][prize_name] + cat_items[prize_name] = list("name" = prize_name, "price" = prize.cost) + static_data["items"][cat] = cat_items + + return static_data + +/obj/machinery/mineral/equipment_vendor/vv_edit_var(var_name, var_value) + // Gotta update the static data in case an admin VV's the items for some reason..! + if(var_name == "prize_list") + dirty_items = TRUE + return ..() + +/obj/machinery/mineral/equipment_vendor/tgui_interact(mob/user, datum/tgui/ui = null) + // Update static data if need be + if(dirty_items) + update_tgui_static_data(user, ui) + dirty_items = FALSE + + // Open the window + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "MiningVendor", name) + ui.open() + ui.set_autoupdate(FALSE) + + +/obj/machinery/mineral/equipment_vendor/tgui_act(action, params) if(..()) - return 1 + return - if(href_list["choice"]) - if(istype(inserted_id)) - if(href_list["choice"] == "eject") - to_chat(usr, "You eject the ID from [src]'s card slot.") - usr.put_in_hands(inserted_id) - inserted_id = null - else if(href_list["choice"] == "insert") - var/obj/item/weapon/card/id/I = usr.get_active_hand() - if(istype(I) && !inserted_id && usr.unEquip(I)) - I.forceMove(src) - inserted_id = I - interact(usr) - to_chat(usr, "You insert the ID into [src]'s card slot.") - else - to_chat(usr, "No valid ID.") - flick(icon_deny, src) - - if(href_list["purchase"]) - if(istype(inserted_id)) - var/datum/data/mining_equipment/prize = locate(href_list["purchase"]) - if (!prize || !(prize in prize_list)) - to_chat(usr, "Error: Invalid choice!") - flick(icon_deny, src) + . = TRUE + switch(action) + if("logoff") + if(!inserted_id) return - if(prize.cost > inserted_id.mining_points) - to_chat(usr, "Error: Insufficent points for [prize.equipment_name]!") - flick(icon_deny, src) - else - inserted_id.mining_points -= prize.cost - to_chat(usr, "[src] clanks to life briefly before vending [prize.equipment_name]!") - new prize.equipment_path(drop_location()) - flick(icon_vend, src) + usr.put_in_hands(inserted_id) + inserted_id = null + if("purchase") + if(!inserted_id) + flick(icon_deny, src) //VOREStation Add + return + var/category = params["cat"] // meow + var/name = params["name"] + if(!(category in prize_list) || !(name in prize_list[category])) // Not trying something that's not in the list, are you? + flick(icon_deny, src) //VOREStation Add + return + var/datum/data/mining_equipment/prize = prize_list[category][name] + if(prize.cost > get_points(inserted_id)) // shouldn't be able to access this since the button is greyed out, but.. + to_chat(usr, "You have insufficient points.") + flick(icon_deny, src) //VOREStation Add + return + + remove_points(inserted_id, prize.cost) + new prize.equipment_path(loc) + flick(icon_vend, src) //VOREStation Add else - to_chat(usr, "Error: Please insert a valid ID!") - flick(icon_deny, src) - updateUsrDialog() + flick(icon_deny, src) //VOREStation Add + return FALSE + add_fingerprint() + /obj/machinery/mineral/equipment_vendor/attackby(obj/item/I, mob/user, params) if(default_deconstruction_screwdriver(user, I)) - updateUsrDialog() return if(default_part_replacement(user, I)) return @@ -201,7 +252,7 @@ if(istype(I, /obj/item/mining_voucher)) if(!powered()) return - RedeemVoucher(I, user) + redeem_voucher(I, user) return if(istype(I,/obj/item/weapon/card/id)) if(!powered()) @@ -209,16 +260,23 @@ else if(!inserted_id && user.unEquip(I)) I.forceMove(src) inserted_id = I - interact(user) + tgui_interact(user) return - ..() + return ..() /obj/machinery/mineral/equipment_vendor/dismantle() if(inserted_id) inserted_id.forceMove(loc) //Prevents deconstructing the ORM from deleting whatever ID was inside it. . = ..() -/obj/machinery/mineral/equipment_vendor/proc/RedeemVoucher(obj/item/mining_voucher/voucher, mob/redeemer) +/** + * Called when someone slaps the machine with a mining voucher + * + * Arguments: + * * voucher - The voucher card item + * * redeemer - The person holding it + */ +/obj/machinery/mineral/equipment_vendor/proc/redeem_voucher(obj/item/mining_voucher/voucher, mob/redeemer) var/selection = input(redeemer, "Pick your equipment", "Mining Voucher Redemption") as null|anything in list("Kinetic Accelerator", "Resonator", "Mining Drone", "Advanced Scanner", "Crusher") if(!selection || !Adjacent(redeemer) || voucher.loc != redeemer) return diff --git a/code/modules/mining/ore_redemption_machine/survey_vendor.dm b/code/modules/mining/ore_redemption_machine/survey_vendor.dm index 65b7ccc76dd..1eb8672ef64 100644 --- a/code/modules/mining/ore_redemption_machine/survey_vendor.dm +++ b/code/modules/mining/ore_redemption_machine/survey_vendor.dm @@ -8,109 +8,69 @@ circuit = /obj/item/weapon/circuitboard/exploration_equipment_vendor icon_deny = "exploration-deny" //VOREStation Edit icon_vend = "exploration-vend" //VOREStation Add + +/obj/machinery/mineral/equipment_vendor/survey/Initialize(mapload) + . = ..() //VOREStation Edit Start - Heavily modified list - prize_list = list( - new /datum/data/mining_equipment("1 Marker Beacon", /obj/item/stack/marker_beacon, 1), - new /datum/data/mining_equipment("10 Marker Beacons", /obj/item/stack/marker_beacon/ten, 10), - new /datum/data/mining_equipment("30 Marker Beacons", /obj/item/stack/marker_beacon/thirty, 30), - new /datum/data/mining_equipment("GPS Device", /obj/item/device/gps/explorer, 10), - new /datum/data/mining_equipment("Whiskey", /obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey, 10), - new /datum/data/mining_equipment("Absinthe", /obj/item/weapon/reagent_containers/food/drinks/bottle/absinthe, 10), - new /datum/data/mining_equipment("Cigar", /obj/item/clothing/mask/smokable/cigarette/cigar/havana, 15), - new /datum/data/mining_equipment("Soap", /obj/item/weapon/soap/nanotrasen, 20), - new /datum/data/mining_equipment("Laser Pointer", /obj/item/device/laser_pointer, 90), - new /datum/data/mining_equipment("Geiger Counter", /obj/item/device/geiger, 75), - new /datum/data/mining_equipment("Plush Toy", /obj/random/plushie, 30), - new /datum/data/mining_equipment("Extraction Equipment - Fulton Beacon",/obj/item/fulton_core, 300), - new /datum/data/mining_equipment("Extraction Equipment - Fulton Pack",/obj/item/extraction_pack, 125), - new /datum/data/mining_equipment("Umbrella", /obj/item/weapon/melee/umbrella/random, 20), - new /datum/data/mining_equipment("Shelter Capsule", /obj/item/device/survivalcapsule, 50), - new /datum/data/mining_equipment("Point Transfer Card", /obj/item/weapon/card/mining_point_card/survey, 50), - new /datum/data/mining_equipment("Trauma Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/trauma, 25), - new /datum/data/mining_equipment("Burn Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/burn, 25), - new /datum/data/mining_equipment("Oxy Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/oxy, 25), - new /datum/data/mining_equipment("Detox Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/detox, 25), - new /datum/data/mining_equipment("Injector (L) - Glucose", /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/glucose,50), - new /datum/data/mining_equipment("Injector (L) - Panacea", /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/purity,50), - new /datum/data/mining_equipment("Injector (L) - Trauma", /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/brute,50), - new /datum/data/mining_equipment("Digital Tablet - Standard", /obj/item/modular_computer/tablet/preset/custom_loadout/standard, 50), - new /datum/data/mining_equipment("Digital Tablet - Advanced", /obj/item/modular_computer/tablet/preset/custom_loadout/advanced, 100), - new /datum/data/mining_equipment("Nanopaste Tube", /obj/item/stack/nanopaste, 100), - new /datum/data/mining_equipment("Mini-Translocator", /obj/item/device/perfect_tele/one_beacon, 120), - new /datum/data/mining_equipment("UAV - Recon Skimmer", /obj/item/device/uav, 400), - new /datum/data/mining_equipment("Thalers - 100", /obj/item/weapon/spacecash/c100, 100), - new /datum/data/mining_equipment("Jump Boots", /obj/item/clothing/shoes/bhop, 250), - new /datum/data/mining_equipment("Luxury Shelter Capsule", /obj/item/device/survivalcapsule/luxury, 310), - new /datum/data/mining_equipment("Bar Shelter Capsule", /obj/item/device/survivalcapsule/luxurybar, 1000), - new /datum/data/mining_equipment("Industrial Equipment - Phoron Bore",/obj/item/weapon/gun/magnetic/matfed, 300), - new /datum/data/mining_equipment("Survey Tools - Shovel", /obj/item/weapon/shovel, 40), - new /datum/data/mining_equipment("Survey Tools - Mechanical Trap", /obj/item/weapon/beartrap, 50), - new /datum/data/mining_equipment("Defense Equipment - Smoke Bomb",/obj/item/weapon/grenade/smokebomb, 10), - new /datum/data/mining_equipment("Defense Equipment - Razor Drone Deployer",/obj/item/weapon/grenade/spawnergrenade/manhacks/station/locked, 100), - new /datum/data/mining_equipment("Defense Equipment - Sentry Drone Deployer",/obj/item/weapon/grenade/spawnergrenade/ward, 150), - new /datum/data/mining_equipment("Defense Equipment - Steel Machete", /obj/item/weapon/material/knife/machete, 75), - new /datum/data/mining_equipment("Fishing Net", /obj/item/weapon/material/fishing_net, 50), - new /datum/data/mining_equipment("Titanium Fishing Rod", /obj/item/weapon/material/fishing_rod/modern, 100), - new /datum/data/mining_equipment("Durasteel Fishing Rod", /obj/item/weapon/material/fishing_rod/modern/strong, 750), - new /datum/data/mining_equipment("Survival Equipment - Insulated Poncho", /obj/random/thermalponcho, 75) - ) - //VOREStation Edit End + prize_list = list() + prize_list["Gear"] = list( + EQUIPMENT("Defense Equipment - Smoke Bomb", /obj/item/weapon/grenade/smokebomb, 10), + 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("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), + EQUIPMENT("Fulton Beacon", /obj/item/fulton_core, 300), + EQUIPMENT("Geiger Counter", /obj/item/device/geiger, 75), + EQUIPMENT("GPS Device", /obj/item/device/gps/mining, 10), + EQUIPMENT("Jump Boots", /obj/item/clothing/shoes/bhop, 250), + EQUIPMENT("Mini-Translocator", /obj/item/device/perfect_tele/one_beacon, 120), + EQUIPMENT("Survival Equipment - Insulated Poncho", /obj/random/thermalponcho, 75), + ) + prize_list["Consumables"] = list( + EQUIPMENT("1 Marker Beacon", /obj/item/stack/marker_beacon, 1), + EQUIPMENT("10 Marker Beacons", /obj/item/stack/marker_beacon/ten, 10), + EQUIPMENT("30 Marker Beacons", /obj/item/stack/marker_beacon/thirty, 30), + EQUIPMENT("Fulton Pack", /obj/item/extraction_pack, 125), + EQUIPMENT("Injector (L) - Glucose", /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/glucose, 50), + EQUIPMENT("Injector (L) - Panacea", /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/purity, 50), + EQUIPMENT("Injector (L) - Trauma", /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/brute, 50), + EQUIPMENT("Nanopaste Tube", /obj/item/stack/nanopaste, 100), + EQUIPMENT("Point Transfer Card", /obj/item/weapon/card/mining_point_card/survey, 50), + EQUIPMENT("Shelter Capsule", /obj/item/device/survivalcapsule, 50), + EQUIPMENT("Burn Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/burn, 25), + EQUIPMENT("Detox Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/detox, 25), + EQUIPMENT("Oxy Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/oxy, 25), + EQUIPMENT("Trauma Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/trauma, 25), + ) + prize_list["Digging Tools"] = list( + EQUIPMENT("Survey Tools - Shovel", /obj/item/weapon/shovel, 40), + EQUIPMENT("Survey Tools - Mechanical Trap", /obj/item/weapon/beartrap, 50), + ) + prize_list["Miscellaneous"] = list( + EQUIPMENT("Absinthe", /obj/item/weapon/reagent_containers/food/drinks/bottle/absinthe, 10), + EQUIPMENT("Whiskey", /obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey, 10), + EQUIPMENT("Cigar", /obj/item/clothing/mask/smokable/cigarette/cigar/havana, 15), + EQUIPMENT("Digital Tablet - Standard", /obj/item/modular_computer/tablet/preset/custom_loadout/standard, 50), + EQUIPMENT("Digital Tablet - Advanced", /obj/item/modular_computer/tablet/preset/custom_loadout/advanced, 100), + EQUIPMENT("Industrial Equipment - Phoron Bore", /obj/item/weapon/gun/magnetic/matfed, 300), + EQUIPMENT("Laser Pointer", /obj/item/device/laser_pointer, 90), + EQUIPMENT("Luxury Shelter Capsule", /obj/item/device/survivalcapsule/luxury, 310), + EQUIPMENT("Bar Shelter Capsule", /obj/item/device/survivalcapsule/luxurybar, 1000), + EQUIPMENT("Plush Toy", /obj/random/plushie, 30), + EQUIPMENT("Soap", /obj/item/weapon/soap/nanotrasen, 20), + EQUIPMENT("Thalers - 100", /obj/item/weapon/spacecash/c100, 100), + EQUIPMENT("Umbrella", /obj/item/weapon/melee/umbrella/random, 20), + EQUIPMENT("UAV - Recon Skimmer", /obj/item/device/uav, 40), -/obj/machinery/mineral/equipment_vendor/survey/interact(mob/user) - user.set_machine(src) + ) + //VOREStation Edit End - var/dat - dat +="
" - if(istype(inserted_id)) - dat += "You have [inserted_id.survey_points] survey points collected. Eject ID.
" - else - dat += "No ID inserted. Insert ID.
" - dat += "
" - dat += "
Equipment point cost list:
" - for(var/datum/data/mining_equipment/prize in prize_list) - dat += "" - dat += "
[prize.equipment_name][prize.cost]Purchase
" - var/datum/browser/popup = new(user, "miningvendor", "Survey Equipment Vendor", 400, 600) - popup.set_content(dat) - popup.open() +/obj/machinery/mineral/equipment_vendor/survey/get_points(obj/item/weapon/card/id/target) + if(!istype(target)) + return 0 + return target.survey_points -/obj/machinery/mineral/equipment_vendor/survey/Topic(href, href_list) - if(..()) - return 1 - - if(href_list["choice"]) - if(istype(inserted_id)) - if(href_list["choice"] == "eject") - to_chat(usr, "You eject the ID from [src]'s card slot.") - usr.put_in_hands(inserted_id) - inserted_id = null - else if(href_list["choice"] == "insert") - var/obj/item/weapon/card/id/I = usr.get_active_hand() - if(istype(I) && !inserted_id && usr.unEquip(I)) - I.forceMove(src) - inserted_id = I - interact(usr) - to_chat(usr, "You insert the ID into [src]'s card slot.") - else - to_chat(usr, "No valid ID.") - flick(icon_deny, src) - - if(href_list["purchase"]) - if(istype(inserted_id)) - var/datum/data/mining_equipment/prize = locate(href_list["purchase"]) - if (!prize || !(prize in prize_list)) - to_chat(usr, "Error: Invalid choice!") - flick(icon_deny, src) - return - if(prize.cost > inserted_id.survey_points) - to_chat(usr, "Error: Insufficent points for [prize.equipment_name]!") - flick(icon_deny, src) - else - inserted_id.survey_points -= prize.cost - to_chat(usr, "[src] clanks to life briefly before vending [prize.equipment_name]!") - flick(icon_vend, src) //VOREStation Add - new prize.equipment_path(drop_location()) - else - to_chat(usr, "Error: Please insert a valid ID!") - flick(icon_deny, src) - updateUsrDialog() +/obj/machinery/mineral/equipment_vendor/survey/remove_points(obj/item/weapon/card/id/target, amt) + target.survey_points -= amt diff --git a/code/modules/mob/_modifiers/medical.dm b/code/modules/mob/_modifiers/medical.dm index 7e150ceb935..3d170719039 100644 --- a/code/modules/mob/_modifiers/medical.dm +++ b/code/modules/mob/_modifiers/medical.dm @@ -50,3 +50,13 @@ evasion = -5 attack_speed_percent = 1.1 disable_duration_percent = 1.05 + +/datum/modifier/clone_stabilizer + name = "clone stabilized" + desc = "Your body's regeneration is highly restricted." + + on_created_text = "You feel nauseous." + on_expired_text = "You feel healthier." + stacks = MODIFIER_STACK_EXTEND + + incoming_healing_percent = 0.1 diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 9dca9c6fdc6..13f794176d0 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -24,6 +24,7 @@ //Note that this is not a reliable way to determine if admins started as observers, since they change mobs a lot. var/has_enabled_antagHUD = 0 var/medHUD = 0 + var/secHUD = 0 var/antagHUD = 0 universal_speak = 1 var/atom/movable/following = null @@ -160,6 +161,12 @@ I = getFlatIcon(src, defdir = SOUTH, no_anim = TRUE) set_cached_examine_icon(src, I, 200 SECONDS) return I + +/mob/observer/dead/examine(mob/user) + . = ..() + + if(is_admin(user)) + . += "\t>[ADMIN_FULLMONTY(src)]" /* Transfer_mind is there to check if mob is being deleted/not going to have a body. @@ -290,6 +297,19 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp plane_holder.set_vis(VIS_CH_STATUS_OOC, medHUD) to_chat(src, "Medical HUD [medHUD ? "Enabled" : "Disabled"]") +/mob/observer/dead/verb/toggle_secHUD() + set category = "Ghost" + set name = "Toggle Security HUD" + set desc = "Toggles Security HUD allowing you to see people's displayed ID's job, wanted status, etc" + + secHUD = !secHUD + plane_holder.set_vis(VIS_CH_ID, secHUD) + plane_holder.set_vis(VIS_CH_WANTED, secHUD) + plane_holder.set_vis(VIS_CH_IMPTRACK, secHUD) + plane_holder.set_vis(VIS_CH_IMPLOYAL, secHUD) + plane_holder.set_vis(VIS_CH_IMPCHEM, secHUD) + to_chat(src, "Security HUD [secHUD ? "Enabled" : "Disabled"]") + /mob/observer/dead/verb/toggle_antagHUD() set category = "Ghost" set name = "Toggle AntagHUD" diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm index c778470b191..e6a618272ef 100644 --- a/code/modules/mob/inventory.dm +++ b/code/modules/mob/inventory.dm @@ -178,7 +178,7 @@ var/list/slot_equipment_priority = list( \ if(!I) //If there's nothing to drop, the drop is automatically successful. return 1 var/slot = get_inventory_slot(I) - return slot && I.mob_can_unequip(src, slot) + return I.mob_can_unequip(src, slot) /mob/proc/get_inventory_slot(obj/item/I) var/slot = 0 diff --git a/code/modules/mob/living/bot/bot.dm b/code/modules/mob/living/bot/bot.dm index 0822dca3756..30ff2c1d2c4 100644 --- a/code/modules/mob/living/bot/bot.dm +++ b/code/modules/mob/living/bot/bot.dm @@ -197,6 +197,12 @@ else startPatrol() else + if((locate(/obj/machinery/door) in loc) && !pulledby) //Don't hang around blocking doors, but don't run off if someone tries to pull us through one. + var/turf/my_turf = get_turf(src) + var/list/can_go = my_turf.CardinalTurfsWithAccess(botcard) + if(LAZYLEN(can_go)) + if(step_towards(src, pick(can_go))) + return handleIdle() /mob/living/bot/proc/handleRegular() diff --git a/code/modules/mob/living/bot/cleanbot.dm b/code/modules/mob/living/bot/cleanbot.dm index 6a4c45f123b..75124803741 100644 --- a/code/modules/mob/living/bot/cleanbot.dm +++ b/code/modules/mob/living/bot/cleanbot.dm @@ -19,6 +19,11 @@ ..() get_targets() +/mob/living/bot/cleanbot/Destroy() + if(target) + cleanbot_reserved_turfs -= target + return ..() + /mob/living/bot/cleanbot/handleIdle() if(!screwloose && !oddbutton && prob(2)) custom_emote(2, "makes an excited booping sound!") @@ -65,18 +70,29 @@ return . /mob/living/bot/cleanbot/lookForTargets() - for(var/obj/effect/decal/cleanable/D in view(world.view, src)) // There was some odd code to make it start with nearest decals, it's unnecessary, this works - if(confirmTarget(D)) - target = D - return + for(var/i = 0, i <= world.view, i++) + for(var/obj/effect/decal/cleanable/D in view(i, src)) + if (i > 0 && get_dist(src, D) < i) + continue // already checked this one + else if(confirmTarget(D)) + target = D + cleanbot_reserved_turfs += D + return + +/mob/living/bot/resetTarget() + cleanbot_reserved_turfs -= target + ..() /mob/living/bot/cleanbot/confirmTarget(var/obj/effect/decal/cleanable/D) if(!..()) - return 0 + return FALSE + if(D.loc in cleanbot_reserved_turfs) + return FALSE for(var/T in target_types) if(istype(D, T)) - return 1 - return 0 + return TRUE + return FALSE + /mob/living/bot/cleanbot/handleAdjacentTarget() if(get_turf(target) == src.loc) @@ -105,6 +121,7 @@ return qdel(D) if(D == target) + cleanbot_reserved_turfs -= target target = null busy = 0 update_icons() diff --git a/code/modules/mob/living/bot/mulebot.dm b/code/modules/mob/living/bot/mulebot.dm index 67fc8fd0517..fa0b76009f1 100644 --- a/code/modules/mob/living/bot/mulebot.dm +++ b/code/modules/mob/living/bot/mulebot.dm @@ -61,72 +61,57 @@ load(C) /mob/living/bot/mulebot/attack_hand(var/mob/user) - interact(user) + tgui_interact(user) -/mob/living/bot/mulebot/proc/interact(var/mob/user) - var/dat - dat += "Multiple Utility Load Effector Mk. III

" - dat += "ID: [suffix]
" - dat += "Power: [on ? "On" : "Off"]
" +/mob/living/bot/mulebot/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "MuleBot", "Mulebot [suffix ? "([suffix])" : ""]") + ui.open() - if(!open) - dat += "
Current Load: [load ? load.name : "none"]
" +/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, + ) + return data - if(locked) - dat += "
Controls are locked" - else - dat += "
Controls are unlocked

" - - if(!locked || issilicon(user)) - dat += "Toggle power
" - dat += "Stop
" - dat += "Proceed
" - dat += "Return to home
" - dat += "Set destination
" - dat += "Set home
" - dat += "Toggle auto return home ([auto_return ? "On" : "Off"])
" - dat += "Toggle non-standard cargo ([crates_only ? "Off" : "On"])
" - - if(load) - dat += "Unload now
" - dat += "
The maintenance hatch is closed.
" - - else - if(!issilicon(user)) - dat += "The maintenance hatch is open.

" - - dat += "Toggle safety ([safety ? "On" : "Off - DANGER"])
" - else - dat += "The bot is in maintenance mode and cannot be controlled.
" - - user << browse("Mulebot [suffix ? "([suffix])" : ""][dat]", "window=mulebot;size=350x500") - onclose(user, "mulebot") - return - -/mob/living/bot/mulebot/Topic(href, href_list) +/mob/living/bot/mulebot/tgui_act(action, params) if(..()) - return - usr.set_machine(src) + return TRUE + add_fingerprint(usr) - switch(href_list["op"]) + switch(action) if("power") if(on) turn_off() else turn_on() visible_message("[usr] switches [on ? "on" : "off"] [src].") + . = TRUE if("stop") obeyCommand("Stop") + . = TRUE if("go") obeyCommand("GoTD") + . = TRUE if("home") obeyCommand("Home") + . = TRUE if("destination") obeyCommand("SetD") + . = TRUE if("sethome") var/new_dest @@ -138,20 +123,23 @@ if(new_dest) home = get_turf(beaconlist[new_dest]) homeName = new_dest + . = TRUE if("unload") unload() + . = TRUE if("autoret") auto_return = !auto_return + . = TRUE if("cargotypes") crates_only = !crates_only + . = TRUE if("safety") safety = !safety - - interact(usr) + . = TRUE /mob/living/bot/mulebot/attackby(var/obj/item/O, var/mob/user) ..() diff --git a/code/modules/mob/living/carbon/human/human_helpers.dm b/code/modules/mob/living/carbon/human/human_helpers.dm index f9c15a48525..7494867d2d8 100644 --- a/code/modules/mob/living/carbon/human/human_helpers.dm +++ b/code/modules/mob/living/carbon/human/human_helpers.dm @@ -103,6 +103,7 @@ if(T && T.robotic >= ORGAN_ROBOT) src.verbs += /mob/living/carbon/human/proc/self_diagnostics src.verbs += /mob/living/carbon/human/proc/reagent_purge //VOREStation Add + src.verbs += /mob/living/carbon/human/proc/setmonitor_state var/datum/robolimb/R = all_robolimbs[T.model] synthetic = R return synthetic diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm index cd2d368d6d2..0d6766b7a32 100644 --- a/code/modules/mob/living/carbon/human/human_movement.dm +++ b/code/modules/mob/living/carbon/human/human_movement.dm @@ -162,6 +162,9 @@ . += turf_move_cost // Wind makes it easier or harder to move, depending on if you're with or against the wind. + // I don't like that so I'm commenting it out :) + // VOREstation Edit Start +/* if(T.outdoors && (T.z <= SSplanets.z_to_planet.len)) var/datum/planet/P = SSplanets.z_to_planet[z] if(P) @@ -174,6 +177,8 @@ else if(direct & reverse_dir[WH.wind_dir]) . += WH.wind_speed +*/ +// VOREstation Edit End. #undef HUMAN_LOWEST_SLOWDOWN /mob/living/carbon/human/Process_Spacemove(var/check_drift = 0) diff --git a/code/modules/mob/living/carbon/human/human_powers.dm b/code/modules/mob/living/carbon/human/human_powers.dm index 9c1a2ef398f..d63b866e6fa 100644 --- a/code/modules/mob/living/carbon/human/human_powers.dm +++ b/code/modules/mob/living/carbon/human/human_powers.dm @@ -209,32 +209,37 @@ if(stat == DEAD) return to_chat(src, "Performing self-diagnostic, please wait...") - sleep(50) - var/output = "Self-Diagnostic Results:\n" - output += "Internal Temperature: [convert_k2c(bodytemperature)] Degrees Celsius\n" + spawn(50) + var/output = "Self-Diagnostic Results:\n" - output += "Current Battery Charge: [nutrition]\n" + output += "Internal Temperature: [convert_k2c(bodytemperature)] Degrees Celsius\n" - var/toxDam = getToxLoss() - if(toxDam) - output += "System Instability: [toxDam > 25 ? "Severe" : "Moderate"]. Seek charging station for cleanup.\n" - else - output += "System Instability: OK\n" + if(isSynthetic()) + output += "Current Battery Charge: [nutrition]\n" - for(var/obj/item/organ/external/EO in organs) - if(EO.brute_dam || EO.burn_dam) - output += "[EO.name] - [EO.burn_dam + EO.brute_dam > EO.min_broken_damage ? "Heavy Damage" : "Light Damage"]\n" //VOREStation Edit - Makes robotic limb damage scalable - else - output += "[EO.name] - OK\n" + if(isSynthetic()) + var/toxDam = getToxLoss() + if(toxDam) + output += "System Instability: [toxDam > 25 ? "Severe" : "Moderate"]. Seek charging station for cleanup.\n" + else + output += "System Instability: OK\n" - for(var/obj/item/organ/IO in internal_organs) - if(IO.damage) - output += "[IO.name] - [IO.damage > 10 ? "Heavy Damage" : "Light Damage"]\n" - else - output += "[IO.name] - OK\n" + for(var/obj/item/organ/external/EO in organs) + if(EO.robotic >= ORGAN_ASSISTED) + if(EO.brute_dam || EO.burn_dam) + output += "[EO.name] - [EO.burn_dam + EO.brute_dam > EO.min_broken_damage ? "Heavy Damage" : "Light Damage"]\n" //VOREStation Edit - Makes robotic limb damage scalable + else + output += "[EO.name] - OK\n" - to_chat(src,output) + for(var/obj/item/organ/IO in internal_organs) + if(IO.robotic >= ORGAN_ASSISTED) + if(IO.damage) + output += "[IO.name] - [IO.damage > 10 ? "Heavy Damage" : "Light Damage"]\n" + else + output += "[IO.name] - OK\n" + + to_chat(src,output) /mob/living/carbon/human var/next_sonar_ping = 0 @@ -347,3 +352,28 @@ to_chat(src, "Your regeneration is interrupted!") adjust_nutrition(-75) active_regen = FALSE + +/mob/living/carbon/human/proc/setmonitor_state() + set name = "Set monitor display" + set desc = "Set your monitor display" + set category = "IC" + if(stat) + to_chat(src,"You must be awake and standing to perform this action!") + return + var/obj/item/organ/external/head/E = organs_by_name[BP_HEAD] + if(!E) + to_chat(src,"You don't seem to have a head!") + return + var/datum/robolimb/robohead = all_robolimbs[E.model] + if(!robohead.monitor_styles || !robohead.monitor_icon) + to_chat(src,"Your head doesn't have a monitor or it doens't support to be changed!") + return + var/list/states + if(!states) + states = params2list(robohead.monitor_styles) + var/choice = input("Select a screen icon.") as null|anything in states + if(choice) + E.eye_icon_location = robohead.monitor_icon + E.eye_icon = states[choice] + to_chat(src,"You set your monitor to display [choice]!") + update_icons_body() diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 50552b68447..93eda8ca849 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -784,10 +784,13 @@ if (species.body_temperature == null) return //this species doesn't have metabolic thermoregulation - // FBPs will overheat, prosthetic limbs are fine. - if(robobody_count) - if(!nif || !nif.flag_check(NIF_O_HEATSINKS,NIF_FLAGS_OTHER)) //VOREStation Edit - NIF heatsinks - bodytemperature += round(robobody_count*1.75) + // FBPs will overheat when alive, prosthetic limbs are fine. + if(stat != DEAD && robobody_count) + if(!nif || !nif.flag_check(NIF_O_HEATSINKS,NIF_FLAGS_OTHER)) //VOREStation Edit - NIF heatsinks prevent the base heat increase per tick if installed. + bodytemperature += round(robobody_count*1.15) + var/obj/item/organ/internal/robotic/heatsink/HS = internal_organs_by_name[O_HEATSINK] + if(!HS || HS.is_broken()) // However, NIF Heatsinks will not compensate for a core FBP component (your heatsink) being lost. + bodytemperature += round(robobody_count*0.5) var/body_temperature_difference = species.body_temperature - bodytemperature @@ -906,14 +909,14 @@ if(reagents) chem_effects.Cut() - if(!isSynthetic()) + if(touching) + touching.metabolize() + if(ingested) + ingested.metabolize() + if(bloodstr) + bloodstr.metabolize() - if(touching) - touching.metabolize() - if(ingested) - ingested.metabolize() - if(bloodstr) - bloodstr.metabolize() + if(!isSynthetic()) var/total_phoronloss = 0 for(var/obj/item/I in src) @@ -1448,7 +1451,7 @@ if(prob(5)) to_chat(src, "You lose directional control!") Confuse(10) - if (getToxLoss() >= 45) + if (getToxLoss() >= 45 && !isSynthetic()) spawn vomit() diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm index 237428e24b1..d4086e1442d 100644 --- a/code/modules/mob/living/carbon/human/species/species.dm +++ b/code/modules/mob/living/carbon/human/species/species.dm @@ -41,6 +41,7 @@ var/show_ssd = "fast asleep" var/virus_immune var/short_sighted // Permanent weldervision. + var/blood_name = "blood" // Name for the species' blood. var/blood_volume = 560 // Initial blood volume. var/bloodloss_rate = 1 // Multiplier for how fast a species bleeds out. Higher = Faster var/blood_level_safe = 0.85 //"Safe" blood level; above this, you're OK @@ -100,6 +101,7 @@ var/chemOD_mod = 1 // Damage modifier for overdose; higher = more damage from ODs var/alcohol_mod = 1 // Multiplier to alcohol strength; 0.5 = half, 0 = no effect at all, 2 = double, etc. var/pain_mod = 1 // Multiplier to pain effects; 0.5 = half, 0 = no effect (equal to NO_PAIN, really), 2 = double, etc. + var/spice_mod = 1 // Multiplier to spice/capsaicin/frostoil effects; 0.5 = half, 0 = no effect (immunity), 2 = double, etc. // set below is EMP interactivity for nonsynth carbons var/emp_sensitivity = 0 // bitflag. valid flags are: EMP_PAIN, EMP_BLIND, EMP_DEAFEN, EMP_CONFUSE, EMP_STUN, and EMP_(BRUTE/BURN/TOX/OXY)_DMG var/emp_dmg_mod = 1 // Multiplier to all EMP damage sustained by the mob, if it's EMP-sensitive 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 8fe3f80a13e..0eeea4f9d4c 100644 --- a/code/modules/mob/living/carbon/human/species/species_getters.dm +++ b/code/modules/mob/living/carbon/human/species/species_getters.dm @@ -63,6 +63,14 @@ else return blood_color +/datum/species/proc/get_blood_name(var/mob/living/carbon/human/H) + if(H) + var/datum/robolimb/company = H.isSynthetic() + if(company) + return company.blood_name + else + return blood_name + /datum/species/proc/get_virus_immune(var/mob/living/carbon/human/H) return ((H && H.isSynthetic()) ? 1 : virus_immune) 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 6f7615c6fd7..bfb1b7d5e3d 100644 --- a/code/modules/mob/living/carbon/human/species/station/prometheans.dm +++ b/code/modules/mob/living/carbon/human/species/station/prometheans.dm @@ -34,6 +34,8 @@ var/datum/species/shapeshifter/promethean/prometheans secondary_langs = list(LANGUAGE_PROMETHEAN, LANGUAGE_SOL_COMMON) // For some reason, having this as their species language does not allow it to be chosen. assisted_langs = list(LANGUAGE_ROOTGLOBAL, LANGUAGE_VOX) // Prometheans are weird, let's just assume they can use basically any language. + blood_name = "gelatinous ooze" + breath_type = null poison_type = null 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 bd5ff8a5d9e..add47b9d943 100644 --- a/code/modules/mob/living/carbon/human/species/station/station.dm +++ b/code/modules/mob/living/carbon/human/species/station/station.dm @@ -292,7 +292,7 @@ appearance_flags = HAS_HAIR_COLOR | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR flesh_color = "#8CD7A3" - blood_color = "#1D2CBF" + blood_color = "#0081CD" base_color = "#006666" cold_level_1 = 280 //Default 260 - Lower is better diff --git a/code/modules/mob/living/carbon/human/species/station/traits_vr/negative.dm b/code/modules/mob/living/carbon/human/species/station/traits_vr/negative.dm index 8b6cfd0b602..b0cf780d66a 100644 --- a/code/modules/mob/living/carbon/human/species/station/traits_vr/negative.dm +++ b/code/modules/mob/living/carbon/human/species/station/traits_vr/negative.dm @@ -90,6 +90,13 @@ cost = -2 var_changes = list("siemens_coefficient" = 2.0) //This makes you extremely weak to tasers. +/datum/trait/haemophilia + name = "Haemophilia - Organics only" + desc = "When you bleed, you bleed a LOT. This trait is only for organics, buggy with synths!" + cost = -2 + var_changes = list("bloodloss_rate" = 2) + not_for_synths = 1 + /datum/trait/hollow name = "Hollow Bones/Aluminum Alloy" desc = "Your bones and robot limbs are much easier to break." 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 a16a72c6c20..9487ea36faf 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 @@ -132,7 +132,44 @@ ..(S,H) H.verbs |= /mob/living/proc/glow_toggle H.verbs |= /mob/living/proc/glow_color + +// Spicy Food Traits, from negative to positive. +/datum/trait/spice_intolerance_extreme + name = "Extreme Spice Intolerance" + desc = "Spicy (and chilly) peppers are three times as strong. (This does not affect pepperspray.)" + cost = 0 + var_changes = list("spice_mod" = 3) // 300% as effective if spice_mod is set to 1. If it's not 1 in species.dm, update this! +/datum/trait/spice_intolerance_basic + name = "Heavy Spice Intolerance" + desc = "Spicy (and chilly) peppers are twice as strong. (This does not affect pepperspray.)" + cost = 0 + var_changes = list("spice_mod" = 2) // 200% as effective if spice_mod is set to 1. If it's not 1 in species.dm, update this! + +/datum/trait/spice_intolerance_slight + name = "Slight Spice Intolerance" + desc = "You have a slight struggle with spicy foods. Spicy (and chilly) peppers are one and a half times stronger. (This does not affect pepperspray.)" + cost = 0 + var_changes = list("spice_mod" = 1.5) // 150% as effective if spice_mod is set to 1. If it's not 1 in species.dm, update this! + +/datum/trait/spice_tolerance_basic + name = "Spice Tolerance" + desc = "Spicy (and chilly) peppers are only three-quarters as strong. (This does not affect pepperspray.)" + cost = 0 + var_changes = list("spice_mod" = 0.75) // 75% as effective if spice_mod is set to 1. If it's not 1 in species.dm, update this! + +/datum/trait/spice_tolerance_advanced + name = "Strong Spice Tolerance" + desc = "Spicy (and chilly) peppers are only half as strong. (This does not affect pepperspray.)" + cost = 0 + var_changes = list("spice_mod" = 0.5) // 50% as effective if spice_mod is set to 1. If it's not 1 in species.dm, update this! + +/datum/trait/spice_immunity + name = "Extreme Spice Tolerance" + desc = "Spicy (and chilly) peppers are basically ineffective! (This does not affect pepperspray.)" + cost = 0 + var_changes = list("spice_mod" = 0.25) // 25% as effective if spice_mod is set to 1. If it's not 1 in species.dm, update this! + // Alcohol Traits Start Here, from negative to positive. /datum/trait/alcohol_intolerance_advanced name = "Liver of Air" diff --git a/code/modules/mob/living/carbon/human/species/station/traits_vr/trait.dm b/code/modules/mob/living/carbon/human/species/station/traits_vr/trait.dm index 1be1ea0268a..434fc8d846f 100644 --- a/code/modules/mob/living/carbon/human/species/station/traits_vr/trait.dm +++ b/code/modules/mob/living/carbon/human/species/station/traits_vr/trait.dm @@ -5,6 +5,7 @@ var/cost = 0 // 0 is neutral, negative cost means negative, positive cost means positive. var/list/var_changes // A list to apply to the custom species vars. var/list/excludes // Store a list of paths of traits to exclude, but done automatically if they change the same vars. + var/not_for_synths = 0 // Can freaking synths use those. //Proc can be overridden lower to include special changes, make sure to call up though for the vars changes /datum/trait/proc/apply(var/datum/species/S,var/mob/living/carbon/human/H) diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index 8cb2f44a088..99a0c828d1e 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -243,7 +243,9 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon() icon_key += "[rgb(eyes.eye_colour[1], eyes.eye_colour[2], eyes.eye_colour[3])]" else icon_key += "[r_eyes], [g_eyes], [b_eyes]" - + var/obj/item/organ/external/head/head = organs_by_name[BP_HEAD] + if(head) + icon_key += "[head.eye_icon]" for(var/organ_tag in species.has_limbs) var/obj/item/organ/external/part = organs_by_name[organ_tag] if(isnull(part) || part.is_stump() || part.is_hidden_by_tail()) //VOREStation Edit allowing tails to prevent bodyparts rendering, granting more spriter freedom for taur/digitigrade stuff. @@ -281,7 +283,6 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon() icon_key += "_t" //VOREStation Edit. icon_key = "[icon_key][husk ? 1 : 0][fat ? 1 : 0][hulk ? 1 : 0][skeleton ? 1 : 0]" - var/icon/base_icon if(human_icon_cache[icon_key]) base_icon = human_icon_cache[icon_key] diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index a472366b03e..f72ec0d4888 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -48,7 +48,7 @@ //mob verbs are faster than object verbs. See above. /mob/living/pointed(atom/A as mob|obj|turf in view()) - if(src.stat || !src.canmove || src.restrained()) + if(src.stat || src.restrained()) return 0 if(src.status_flags & FAKEDEATH) return 0 @@ -248,7 +248,7 @@ default behaviour is: /mob/living/Crossed(var/atom/movable/AM) // Transplanting this from /mob/living/carbon/human/Crossed() if(AM == src || AM.is_incorporeal()) // We're not going to run over ourselves or ghosts return - + if(istype(AM, /mob/living/bot/mulebot)) var/mob/living/bot/mulebot/MB = AM MB.runOver(src) diff --git a/code/modules/mob/living/silicon/robot/drone/drone_abilities.dm b/code/modules/mob/living/silicon/robot/drone/drone_abilities.dm index 6d28b6ce616..a799e2a1c9b 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone_abilities.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone_abilities.dm @@ -4,7 +4,7 @@ set desc = "Tag yourself for delivery through the disposals system." set category = "Robot Commands" - var/new_tag = input("Select the desired destination.", "Set Mail Tag", null) as null|anything in tagger_locations + var/new_tag = input("Select the desired destination.", "Set Mail Tag", null) as null|anything in GLOB.tagger_locations if(!new_tag) mail_destination = "" diff --git a/code/modules/mob/living/silicon/robot/drone/drone_console.dm b/code/modules/mob/living/silicon/robot/drone/drone_console.dm index 94b8bb2e2c0..77486ecfffd 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone_console.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone_console.dm @@ -53,7 +53,7 @@ data["fabricator"] = dronefab data["fabPower"] = dronefab?.produce_drones - data["areas"] = tagger_locations + data["areas"] = GLOB.tagger_locations data["selected_area"] = "[drone_call_area]" return data @@ -65,7 +65,7 @@ switch(action) if("set_dcall_area") var/t_area = params["area"] - if(!t_area || !(t_area in tagger_locations)) + if(!t_area || !(t_area in GLOB.tagger_locations)) return drone_call_area = t_area diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 6383449e0a6..5ba5b7deb82 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -336,6 +336,7 @@ /mob/living/silicon/robot/verb/Namepick() set category = "Robot Commands" if(custom_name) + to_chat(usr, "You can't pick another custom name. Go ask for a name change.") return 0 spawn(0) @@ -415,6 +416,7 @@ /mob/living/silicon/robot/verb/spark_plug() //So you can still sparkle on demand without violence. set category = "Robot Commands" set name = "Emit Sparks" + to_chat(src, "You harmlessly spark.") spark_system.start() // this function displays jetpack pressure in the stat panel @@ -690,7 +692,7 @@ //if(H.species.can_shred(H)) // attack_generic(H, rand(30,50), "slashed") // return - //VOREStation Edit: Adding borg petting. Help intent pets, Disarm intent taps, Grab should remove the battery for replacement, and Harm is punching(no damage) + //Adding borg petting. Help intent pets, Disarm intent taps, Grab should remove the battery for replacement, and Harm is punching(no damage) switch(H.a_intent) if(I_HELP) visible_message("[H] pets [src].") @@ -701,15 +703,15 @@ attack_generic(H, rand(30,50), "slashed") return else - playsound(src, 'sound/effects/bang.ogg', 10, 1) + playsound(src.loc, 'sound/effects/bang.ogg', 10, 1) visible_message("[H] punches [src], but doesn't leave a dent.") return if(I_DISARM) H.do_attack_animation(src) - playsound(src, 'sound/effects/clang1.ogg', 10, 1) + playsound(src.loc, 'sound/effects/clang2.ogg', 10, 1) visible_message("[H] taps [src].") return - //VOREStation Edit: Addition of borg petting end + if(opened && !wiresexposed && (!istype(user, /mob/living/silicon))) var/datum/robot_component/cell_component = components["power cell"] if(cell) @@ -1155,4 +1157,4 @@ uneq_active() if(current_selection_index) // Select what the player had before if possible. - select_module(current_selection_index) \ No newline at end of file + select_module(current_selection_index) diff --git a/code/modules/modular_computers/file_system/program.dm b/code/modules/modular_computers/file_system/program.dm index 9e011f442db..08589fb13c8 100644 --- a/code/modules/modular_computers/file_system/program.dm +++ b/code/modules/modular_computers/file_system/program.dm @@ -189,6 +189,8 @@ /datum/computer_file/program/proc/check_eye(var/mob/user) if(NM) return NM.check_eye(user) + if(TM) + return TM.check_eye(user) else return -1 diff --git a/code/modules/modular_computers/file_system/programs/ships/navigation.dm b/code/modules/modular_computers/file_system/programs/ships/navigation.dm index 88db90598bc..b8fecd96576 100644 --- a/code/modules/modular_computers/file_system/programs/ships/navigation.dm +++ b/code/modules/modular_computers/file_system/programs/ships/navigation.dm @@ -1,7 +1,7 @@ /datum/computer_file/program/ship_nav filename = "navviewer" filedesc = "Ship Navigational Screen" - nanomodule_path = /datum/nano_module/program/ship/nav + tguimodule_path = /datum/tgui_module/ship/nav/ntos program_icon_state = "helm" program_key_state = "generic_key" program_menu_icon = "pin-s" @@ -10,54 +10,3 @@ requires_ntnet = 1 network_destination = "ship position sensors" size = 4 - -/datum/nano_module/program/ship/nav - name = "Navigation Display" - -/datum/nano_module/program/ship/nav/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) - if(!linked) - to_chat(user, "You don't appear to be on a spaceship...") - if(program) - program.kill_program() - else if(ui) - ui.close() - return - - var/list/data = list() - if(program) - data = program.get_header_data() - - var/turf/T = get_turf(linked) - var/obj/effect/overmap/visitable/sector/current_sector = locate() in T - - data["sector"] = current_sector ? current_sector.name : "Deep Space" - data["sector_info"] = current_sector ? current_sector.desc : "Not Available" - data["s_x"] = linked.x - data["s_y"] = linked.y - data["speed"] = round(linked.get_speed()*1000, 0.01) - data["accel"] = round(linked.get_acceleration()*1000, 0.01) - data["heading"] = linked.get_heading_degrees() - data["viewing"] = viewing_overmap(user) - - if(linked.get_speed()) - data["ETAnext"] = "[round(linked.ETA()/10)] seconds" - else - data["ETAnext"] = "N/A" - - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "nav.tmpl", "[linked.name] Navigation Screen", 380, 530, state = state) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) - -/datum/nano_module/program/ship/nav/OnTopic(var/mob/user, var/list/href_list) - if(..()) - return TOPIC_HANDLED - - if (!linked) - return TOPIC_NOACTION - - if (href_list["viewing"]) - viewing_overmap(user) ? unlook(user) : look(user) - return TOPIC_REFRESH diff --git a/code/modules/modular_computers/file_system/programs/ships/ship.dm b/code/modules/modular_computers/file_system/programs/ships/ship.dm deleted file mode 100644 index 1db653153be..00000000000 --- a/code/modules/modular_computers/file_system/programs/ships/ship.dm +++ /dev/null @@ -1,87 +0,0 @@ -/datum/nano_module/program/ship - var/obj/effect/overmap/visitable/ship/linked - var/list/viewers - var/extra_view = 0 - -/datum/nano_module/program/ship/New() - ..() - sync_linked() - if(linked) - name = "[linked.name] [name]" - -/datum/nano_module/program/ship/Destroy() - if(LAZYLEN(viewers)) - for(var/weakref/W in viewers) - var/M = W.resolve() - if(M) - unlook(M) - . = ..() - -/datum/nano_module/program/ship/proc/sync_linked() - var/obj/effect/overmap/visitable/ship/sector = get_overmap_sector(get_z(nano_host())) - if(!sector) - return - return attempt_hook_up_recursive(sector) - -/datum/nano_module/program/ship/proc/attempt_hook_up_recursive(obj/effect/overmap/visitable/ship/sector) - if(attempt_hook_up(sector)) - return sector - for(var/obj/effect/overmap/visitable/ship/candidate in sector) - if((. = .(candidate))) - return - -/datum/nano_module/program/ship/proc/attempt_hook_up(obj/effect/overmap/visitable/ship/sector) - if(!istype(sector)) - return - if(sector.check_ownership(nano_host())) - linked = sector - return 1 - -/datum/nano_module/program/ship/proc/look(var/mob/user) - if(linked) - user.machine = nano_host() - user.reset_view(linked) - user.set_viewsize(world.view + extra_view) - GLOB.moved_event.register(user, src, /datum/nano_module/program/ship/proc/unlook) - LAZYDISTINCTADD(viewers, weakref(user)) - -/datum/nano_module/program/ship/proc/unlook(var/mob/user) - user.reset_view() - user.set_viewsize() // reset to default - GLOB.moved_event.unregister(user, src, /datum/nano_module/program/ship/proc/unlook) - LAZYREMOVE(viewers, weakref(user)) - -/datum/nano_module/program/ship/proc/viewing_overmap(mob/user) - return (weakref(user) in viewers) - -/datum/nano_module/program/ship/proc/DefaultTopicState() - return global.default_state - -/datum/nano_module/program/ship/Topic(var/href, var/href_list = list(), var/datum/topic_state/state) - if((. = ..())) - return - state = state || DefaultTopicState() || global.default_state - if(CanUseTopic(usr, state, href_list) == STATUS_INTERACTIVE) - CouldUseTopic(usr) - return OnTopic(usr, href_list, state) - CouldNotUseTopic(usr) - return TRUE - -/datum/nano_module/program/ship/proc/OnTopic(var/mob/user, var/href_list, var/datum/topic_state/state) - return TOPIC_NOACTION - -/datum/nano_module/program/ship/proc/CouldNotUseTopic(mob/user) - . = ..() - unlook(user) - -/datum/nano_module/program/ship/proc/CouldUseTopic(mob/user) - . = ..() - if(viewing_overmap(user)) - look(user) - -/datum/nano_module/program/ship/check_eye(var/mob/user) - if (!get_dist(user, nano_host()) > 1 || user.blinded || !linked ) - unlook(user) - return -1 - else - return 0 \ No newline at end of file diff --git a/code/modules/organs/blood.dm b/code/modules/organs/blood.dm index 49f9d5b6a45..f1214708f10 100644 --- a/code/modules/organs/blood.dm +++ b/code/modules/organs/blood.dm @@ -36,8 +36,13 @@ var/const/CE_STABLE_THRESHOLD = 0.5 for(var/datum/reagent/blood/B in vessel.reagent_list) if(B.id == "blood") B.data = list( "donor"=src,"viruses"=null,"species"=species.name,"blood_DNA"=dna.unique_enzymes,"blood_colour"= species.get_blood_colour(src),"blood_type"=dna.b_type, \ - "resistances"=null,"trace_chem"=null, "virus2" = null, "antibodies" = list()) + "resistances"=null,"trace_chem"=null, "virus2" = null, "antibodies" = list(), "blood_name" = species.get_blood_name(src)) + + if(isSynthetic()) + B.data["species"] = "synthetic" + B.color = B.data["blood_colour"] + B.name = B.data["blood_name"] // Takes care blood loss and regeneration /mob/living/carbon/human/handle_blood() @@ -369,6 +374,9 @@ proc/blood_splatter(var/target,var/datum/reagent/blood/source,var/large) B.synthblood = synth B.update_icon() + if(source.data["blood_name"]) + B.name = source.data["blood_name"] + // Update blood information. if(source.data["blood_DNA"]) B.blood_DNA = list() diff --git a/code/modules/organs/internal/heart.dm b/code/modules/organs/internal/heart.dm index 62e5fd16d22..9f015bcdc9f 100644 --- a/code/modules/organs/internal/heart.dm +++ b/code/modules/organs/internal/heart.dm @@ -37,3 +37,19 @@ if(ishuman(owner)) H = owner color = H.species.blood_color + +/obj/item/organ/internal/heart/machine + name = "hydraulic hub" + icon_state = "pump-on" + organ_tag = O_PUMP + dead_icon = "pump-off" + robotic = ORGAN_ROBOT + + standard_pulse_level = PULSE_NONE + +/obj/item/organ/internal/stomach/machine/handle_organ_proc_special() + ..() + if(owner && owner.stat != DEAD) + owner.bodytemperature += round(owner.robobody_count * 0.25, 0.1) + + return diff --git a/code/modules/organs/internal/robotic/diagnostic.dm b/code/modules/organs/internal/robotic/diagnostic.dm new file mode 100644 index 00000000000..7d915fa3323 --- /dev/null +++ b/code/modules/organs/internal/robotic/diagnostic.dm @@ -0,0 +1,14 @@ +/* + * Controls the ability to do a scan for internal damage / temperature. + */ + +/obj/item/organ/internal/robotic/diagnostic + name = "diagnostic processor" + + icon_state = "diagnostic" + + organ_tag = O_DIAGNOSTIC + + organ_verbs = list( + /mob/living/carbon/human/proc/self_diagnostics + ) diff --git a/code/modules/organs/internal/robotic/heatsink.dm b/code/modules/organs/internal/robotic/heatsink.dm new file mode 100644 index 00000000000..4db6e419224 --- /dev/null +++ b/code/modules/organs/internal/robotic/heatsink.dm @@ -0,0 +1,58 @@ + +/obj/item/organ/internal/robotic/heatsink + name = "heatsink" + icon_state = "heatsink" + + organ_tag = O_HEATSINK + +/obj/item/organ/internal/robotic/heatsink/handle_organ_proc_special() + if(owner && owner.stat != DEAD) + owner.bodytemperature += round(owner.robobody_count * 0.75, 0.1) + + var/thermostat = owner.species.body_temperature + var/turf/T = get_turf(src) + var/datum/gas_mixture/environment = T.return_air() + var/efficiency = max(0,(1 - owner.get_pressure_weakness(environment.return_pressure())) * (1 - damage / max_damage)) + var/temp_adj = 0 + var/env_temp = get_environment_temperature() + var/thermal_protection = owner.get_heat_protection(env_temp) + + if(thermal_protection < 1) + temp_adj = min(owner.bodytemperature - max(thermostat, env_temp), owner.robobody_count * 2) + else + temp_adj = min(owner.bodytemperature - thermostat, owner.robobody_count * 2) + + if(temp_adj < 0) + return + + owner.bodytemperature -= temp_adj*efficiency + + if(owner.bodytemperature > owner.species.heat_level_2) // If you're already overheating to the point of melting, the heatsink starts causing problems. + owner.adjustToxLoss(2 * damage / max_damage) + take_damage(max(0.5,round(damage / max_damage, 0.1))) + + return + +/obj/item/organ/internal/robotic/heatsink/proc/get_environment_temperature() + if(istype(owner.loc, /obj/mecha)) + var/obj/mecha/M = owner.loc + return M.return_temperature() + else if(istype(owner.loc, /obj/machinery/atmospherics/unary/cryo_cell)) + return owner.loc:air_contents.temperature + + var/turf/T = get_turf(src) + + var/datum/gas_mixture/environment = T.return_air() + + var/efficiency = 1 + + if(environment) + efficiency = (1 - owner.get_pressure_weakness(environment.return_pressure())) * (1 - damage / max_damage) + + if(istype(T, /turf/space)) + return owner.species.heat_level_2 * efficiency + + if(!environment) + return owner.species.heat_level_2 * efficiency + + return environment.temperature diff --git a/code/modules/organs/internal/robotic/robotic.dm b/code/modules/organs/internal/robotic/robotic.dm new file mode 100644 index 00000000000..7a40ab81011 --- /dev/null +++ b/code/modules/organs/internal/robotic/robotic.dm @@ -0,0 +1,11 @@ + +/obj/item/organ/internal/robotic + name = "FBP component" + desc = "A complex piece of a much more complex machine." + + icon_state = "eyes-prosthetic" + + can_reject = FALSE // It's a robotic part. Why would it reject. + decays = FALSE // Ditto. Rust takes a while. + + robotic = ORGAN_ROBOT diff --git a/code/modules/organs/internal/stomach.dm b/code/modules/organs/internal/stomach.dm index 02cf7cb31d7..c8e90d9f782 100644 --- a/code/modules/organs/internal/stomach.dm +++ b/code/modules/organs/internal/stomach.dm @@ -48,3 +48,20 @@ /obj/item/organ/internal/stomach/xeno color = "#555555" + acidtype = "pacid" + +/obj/item/organ/internal/stomach/machine + name = "reagent cycler" + icon_state = "cycler" + organ_tag = O_CYCLER + + robotic = ORGAN_ROBOT + + acidtype = "sacid" + +/obj/item/organ/internal/stomach/machine/handle_organ_proc_special() + ..() + if(owner && owner.stat != DEAD) + owner.bodytemperature += round(owner.robobody_count * 0.25, 0.1) + + return diff --git a/code/modules/organs/robolimbs.dm b/code/modules/organs/robolimbs.dm index a0ca24e9974..e7be5f4912a 100644 --- a/code/modules/organs/robolimbs.dm +++ b/code/modules/organs/robolimbs.dm @@ -45,13 +45,15 @@ var/const/standard_monitor_styles = "blank=ipc_blank;\ var/company = "Unbranded" // Shown when selecting the limb. var/desc = "A generic unbranded robotic prosthesis." // Seen when examining a limb. var/icon = 'icons/mob/human_races/robotic.dmi' // Icon base to draw from. + var/monitor_icon = 'icons/mob/monitor_icons.dmi' // Where it draws the monitor icon from. var/unavailable_at_chargen // If set, not available at chargen. var/unavailable_to_build // If set, can't be constructed. var/lifelike // If set, appears organic. var/skin_tone // If set, applies skin tone rather than part color Overrides color. var/skin_color // If set, applies skin color rather than part color. var/blood_color = "#030303" - var/list/species_cannot_use = list(SPECIES_TESHARI, SPECIES_PROMETHEAN, SPECIES_DIONA, SPECIES_XENOCHIMERA) //VOREStation Edit + var/blood_name = "oil" + var/list/species_cannot_use = list(SPECIES_TESHARI, SPECIES_PROMETHEAN, SPECIES_DIONA, SPECIES_XENOCHIMERA) //VOREStation Edit var/list/species_alternates = list(SPECIES_TAJ = "Unbranded - Tajaran", SPECIES_UNATHI = "Unbranded - Unathi") //"Species Name" = "Robolimb Company" , List, when initialized, will become "Species Name" = RobolimbDatum, used for alternate species sprites. var/list/monitor_styles //If empty, the model of limbs offers a head compatible with monitors. var/parts = BP_ALL //Defines what parts said brand can replace on a body. @@ -171,6 +173,7 @@ var/const/standard_monitor_styles = "blank=ipc_blank;\ desc = "This limb looks to be more like a strange.. puppet, than a prosthetic." icon = 'icons/mob/human_races/cyberlimbs/veymed/dionaea/skrellian.dmi' blood_color = "#63b521" + blood_name = "synthetic ichor" speech_bubble_appearance = "machine" unavailable_to_build = 1 species_cannot_use = list(SPECIES_TESHARI, SPECIES_PROMETHEAN, SPECIES_TAJ, SPECIES_HUMAN, SPECIES_VOX, SPECIES_HUMAN_VATBORN, SPECIES_UNATHI, SPECIES_SKRELL, SPECIES_ZADDAT) @@ -186,11 +189,10 @@ var/const/standard_monitor_styles = "blank=ipc_blank;\ unavailable_to_build = 1 /datum/robolimb/cybersolutions_alt2 - company = "Cyber Solutions - Array" - desc = "This limb is simple and functional; array of sensors on a featureless case." + company = "Cyber Solutions - Outdated" + desc = "This limb is of severely outdated design; there's no way it's comfortable or very functional to use." icon = 'icons/mob/human_races/cyberlimbs/cybersolutions/cybersolutions_alt2.dmi' unavailable_to_build = 1 - parts = list(BP_HEAD) /datum/robolimb/cybersolutions_alt1 company = "Cyber Solutions - Wight" @@ -198,6 +200,13 @@ var/const/standard_monitor_styles = "blank=ipc_blank;\ icon = 'icons/mob/human_races/cyberlimbs/cybersolutions/cybersolutions_alt1.dmi' unavailable_to_build = 1 +/datum/robolimb/cybersolutions_alt3 + company = "Cyber Solutions - Array" + desc = "This limb is simple and functional; array of sensors on a featureless case." + icon = 'icons/mob/human_races/cyberlimbs/cybersolutions/cybersolutions_alt3.dmi' + unavailable_to_build = 1 + parts = list(BP_HEAD) + /datum/robolimb/einstein company = "Einstein Engines" desc = "This limb is lightweight with a sleek design." @@ -301,6 +310,7 @@ var/const/standard_monitor_styles = "blank=ipc_blank;\ skin_tone = 1 species_alternates = list(SPECIES_SKRELL = "Vey-Med - Skrell") blood_color = "#CCCCCC" + blood_name = "coolant" speech_bubble_appearance = "normal" //robo_brute_mod = 1.1 //VOREStation Edit //robo_burn_mod = 1.1 //VOREStation Edit @@ -314,6 +324,7 @@ var/const/standard_monitor_styles = "blank=ipc_blank;\ skin_color = TRUE species_cannot_use = list(SPECIES_TESHARI, SPECIES_PROMETHEAN, SPECIES_TAJ, SPECIES_HUMAN, SPECIES_VOX, SPECIES_HUMAN_VATBORN, SPECIES_UNATHI, SPECIES_DIONA, SPECIES_ZADDAT) blood_color = "#4451cf" + blood_name = "coolant" speech_bubble_appearance = "normal" robo_brute_mod = 1.05 robo_burn_mod = 1.05 @@ -484,4 +495,4 @@ var/const/standard_monitor_styles = "blank=ipc_blank;\ species = SPECIES_ZADDAT /obj/item/weapon/disk/limb/cenilimicybernetics - company = "Cenilimi Cybernetics" \ No newline at end of file + company = "Cenilimi Cybernetics" diff --git a/code/modules/organs/subtypes/machine.dm b/code/modules/organs/subtypes/machine.dm index 6cefcfcee64..8624a714536 100644 --- a/code/modules/organs/subtypes/machine.dm +++ b/code/modules/organs/subtypes/machine.dm @@ -22,6 +22,13 @@ ..() owner.adjust_nutrition(-rand(10 / severity, 50 / severity)) +/obj/item/organ/internal/cell/machine/handle_organ_proc_special() + ..() + if(owner && owner.stat != DEAD) + owner.bodytemperature += round(owner.robobody_count * 0.5, 0.1) + + return + // Used for an MMI or posibrain being installed into a human. /obj/item/organ/internal/mmi_holder name = "brain interface" @@ -51,6 +58,11 @@ /obj/item/organ/internal/mmi_holder/proc/tick_defib_timer() return +/obj/item/organ/internal/mmi_holder/proc/get_control_efficiency() + . = max(0, 1 - round(damage / max_damage, 0.1)) + + return . + /obj/item/organ/internal/mmi_holder/proc/update_from_mmi() if(!stored_mmi.brainmob) diff --git a/code/modules/organs/subtypes/standard.dm b/code/modules/organs/subtypes/standard.dm index 63e4c4a7d27..bb4a9c7a138 100644 --- a/code/modules/organs/subtypes/standard.dm +++ b/code/modules/organs/subtypes/standard.dm @@ -28,6 +28,10 @@ // Give them fancy new organs. owner.internal_organs_by_name[O_CELL] = new /obj/item/organ/internal/cell(owner,1) owner.internal_organs_by_name[O_VOICE] = new /obj/item/organ/internal/voicebox/robot(owner, 1) + owner.internal_organs_by_name[O_PUMP] = new /obj/item/organ/internal/heart/machine(owner,1) + owner.internal_organs_by_name[O_CYCLER] = new /obj/item/organ/internal/stomach/machine(owner,1) + owner.internal_organs_by_name[O_HEATSINK] = new /obj/item/organ/internal/robotic/heatsink(owner,1) + owner.internal_organs_by_name[O_DIAGNOSTIC] = new /obj/item/organ/internal/robotic/diagnostic(owner,1) /obj/item/organ/external/chest/handle_germ_effects() . = ..() //Should return an infection level diff --git a/code/modules/overmap/disperser/disperser_console.dm b/code/modules/overmap/disperser/disperser_console.dm index 7ed212c8acc..5f977853413 100644 --- a/code/modules/overmap/disperser/disperser_console.dm +++ b/code/modules/overmap/disperser/disperser_console.dm @@ -118,14 +118,30 @@ obj/machinery/computer/ship/disperser/proc/is_valid_setup() if(B) return B -/obj/machinery/computer/ship/disperser/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = TRUE) +/obj/machinery/computer/ship/disperser/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui) if(!linked) display_reconnect_dialog(user, "disperser synchronization") return - var/data[0] + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "OvermapDisperser", "[linked.name] ORB control") // 400, 550 + ui.open() - if (!link_parts()) +/obj/machinery/computer/ship/disperser/tgui_data(mob/user) + var/list/data = list() + data["faillink"] = FALSE + data["calibration"] = null + data["overmapdir"] = null + data["cal_accuracy"] = 0 + data["strength"] = 0 + data["range"] = 0 + data["next_shot"] = -1 + data["nopower"] = TRUE + data["skill"] = FALSE + data["chargeload"] = null + + if(!link_parts()) data["faillink"] = TRUE else data["calibration"] = calibration @@ -137,56 +153,58 @@ obj/machinery/computer/ship/disperser/proc/is_valid_setup() data["nopower"] = !data["faillink"] && (!front.powered() || !middle.powered() || !back.powered()) data["skill"] = user.get_skill_value(core_skill) > skill_offset - var/charge = "UNKNOWN ERROR" + var/charge = "UNKNOWN ERROR" if(get_charge_type() == OVERMAP_WEAKNESS_NONE) - charge = "ERROR: No valid charge detected." + charge = "ERROR: No valid charge detected." else var/obj/structure/ship_munition/disperser_charge/B = get_charge() charge = B.chargedesc data["chargeload"] = charge - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "disperser.tmpl", "[linked.name] ORB control", 400, 550) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) + return data -/obj/machinery/computer/ship/disperser/OnTopic(mob/user, list/href_list, state) - . = ..() - if(.) - return +/obj/machinery/computer/ship/disperser/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) + if(..()) + return TRUE if(!linked) - return TOPIC_HANDLED + return FALSE - if (href_list["choose"]) - overmapdir = sanitize_integer(text2num(href_list["choose"]), 0, 9, 0) - reset_calibration() + switch(action) + if("choose") + overmapdir = sanitize_integer(text2num(params["dir"]), 0, 9, 0) + reset_calibration() + . = TRUE - if(href_list["calibration"]) - var/input = input("0-9", "disperser calibration", 0) as num|null - if(!isnull(input)) //can be zero so we explicitly check for null - var/calnum = sanitize_integer(text2num(href_list["calibration"]), 0, caldigit)//sanitiiiiize - calibration[calnum + 1] = sanitize_integer(input, 0, 9, 0)//must add 1 because nanoui indexes from 0 + if("calibration") + var/input = input("0-9", "disperser calibration", 0) as num|null + if(!isnull(input)) //can be zero so we explicitly check for null + var/calnum = sanitize_integer(text2num(params["calibration"]), 0, caldigit)//sanitiiiiize + calibration[calnum + 1] = sanitize_integer(input, 0, 9, 0)//must add 1 because js indexes from 0 + . = TRUE - if(href_list["skill_calibration"]) - for(var/i = 1 to min(caldigit, user.get_skill_value(core_skill) - skill_offset)) - calibration[i] = calexpected[i] + if("skill_calibration") + for(var/i = 1 to min(caldigit, usr.get_skill_value(core_skill) - skill_offset)) + calibration[i] = calexpected[i] + . = TRUE - if(href_list["strength"]) - var/input = input("1-5", "disperser strength", 1) as num|null - if(input && CanInteract(user, state)) - strength = sanitize_integer(input, 1, 5, 1) - middle.update_idle_power_usage(strength * range * 100) + if("strength") + var/input = input("1-5", "disperser strength", 1) as num|null + if(input && tgui_status(usr, state) == STATUS_INTERACTIVE) + strength = sanitize_integer(input, 1, 5, 1) + middle.update_idle_power_usage(strength * range * 100) + . = TRUE - if(href_list["range"]) - var/input = input("1-5", "disperser radius", 1) as num|null - if(input && CanInteract(user, state)) - range = sanitize_integer(input, 1, 5, 1) - middle.update_idle_power_usage(strength * range * 100) + if("range") + var/input = input("1-5", "disperser radius", 1) as num|null + if(input && tgui_status(usr, state) == STATUS_INTERACTIVE) + range = sanitize_integer(input, 1, 5, 1) + middle.update_idle_power_usage(strength * range * 100) + . = TRUE - if(href_list["fire"]) - fire(user) + if("fire") + fire(usr) + . = TRUE - return TOPIC_REFRESH + if(. && !issilicon(usr)) + playsound(src, "terminal_type", 50, 1) \ No newline at end of file diff --git a/code/modules/overmap/ships/computers/computer_shims.dm b/code/modules/overmap/ships/computers/computer_shims.dm index 5dbb61405d9..16d9285c392 100644 --- a/code/modules/overmap/ships/computers/computer_shims.dm +++ b/code/modules/overmap/ships/computers/computer_shims.dm @@ -54,22 +54,8 @@ // // Topic // - -/obj/machinery/computer/ship/proc/DefaultTopicState() - return global.default_state - -/obj/machinery/computer/ship/Topic(var/href, var/href_list = list(), var/datum/topic_state/state) - if((. = ..())) - return - state = state || DefaultTopicState() || global.default_state - if(CanUseTopic(usr, state, href_list) == STATUS_INTERACTIVE) - CouldUseTopic(usr) - return OnTopic(usr, href_list, state) - CouldNotUseTopic(usr) - return TRUE - -/obj/machinery/computer/ship/proc/OnTopic(var/mob/user, var/href_list, var/datum/topic_state/state) - return TOPIC_NOACTION +/obj/machinery/computer/ship/tgui_state() + return GLOB.tgui_default_state // // Interaction @@ -80,11 +66,11 @@ // If you perform direct interactions in here, you are responsible for ensuring that full interactivity checks have been made (i.e CanInteract). // The checks leading in to here only guarantee that the user should be able to view a UI. /obj/machinery/computer/ship/proc/interface_interact(var/mob/user) - ui_interact(user) + tgui_interact(user) return TRUE /obj/machinery/computer/ship/attack_ai(mob/user) - if(CanUseTopic(user, DefaultTopicState()) > STATUS_CLOSE) + if(tgui_status(user, tgui_state()) > STATUS_CLOSE) return interface_interact(user) // After a recent rework this should mostly be safe. @@ -98,6 +84,6 @@ return if(!allowed(user)) to_chat(user, "Access Denied.") - return 1 - if(CanUseTopic(user, DefaultTopicState()) > STATUS_CLOSE) + return TRUE + if(tgui_status(user, tgui_state()) > STATUS_CLOSE) return interface_interact(user) diff --git a/code/modules/overmap/ships/computers/engine_control.dm b/code/modules/overmap/ships/computers/engine_control.dm index c07fdf45cbd..5721c6f9c70 100644 --- a/code/modules/overmap/ships/computers/engine_control.dm +++ b/code/modules/overmap/ships/computers/engine_control.dm @@ -5,92 +5,92 @@ icon_keyboard = "tech_key" icon_screen = "engines" circuit = /obj/item/weapon/circuitboard/engine - var/display_state = "status" -/obj/machinery/computer/ship/engines/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) +/obj/machinery/computer/ship/engines/tgui_interact(mob/user, datum/tgui/ui) if(!linked) display_reconnect_dialog(user, "ship control systems") return - var/data[0] - data["state"] = display_state + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "OvermapEngines", "[linked.name] Engines Control") // 390, 530 + ui.open() + +/obj/machinery/computer/ship/engines/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = list() data["global_state"] = linked.engines_state data["global_limit"] = round(linked.thrust_limit*100) var/total_thrust = 0 - var/list/enginfo[0] + var/list/enginfo = list() for(var/datum/ship_engine/E in linked.engines) - var/list/rdata[0] + var/list/rdata = list() rdata["eng_type"] = E.name rdata["eng_on"] = E.is_on() rdata["eng_thrust"] = E.get_thrust() rdata["eng_thrust_limiter"] = round(E.get_thrust_limit()*100) - rdata["eng_status"] = E.get_status() + var/list/status = E.get_status() + if(!islist(status)) + log_runtime(EXCEPTION("Warning, ship [E.name] (\ref[E]) for [linked.name] returned a non-list status!")) + status = list("Error") + rdata["eng_status"] = status rdata["eng_reference"] = "\ref[E]" total_thrust += E.get_thrust() enginfo.Add(list(rdata)) data["engines_info"] = enginfo data["total_thrust"] = total_thrust + return data - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "engines_control.tmpl", "[linked.name] Engines Control", 390, 530) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) - -/obj/machinery/computer/ship/engines/OnTopic(var/mob/user, var/list/href_list, state) +/obj/machinery/computer/ship/engines/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) if(..()) - return ..() + return TRUE - if(href_list["state"]) - display_state = href_list["state"] - return TOPIC_REFRESH + switch(action) + if("global_toggle") + linked.engines_state = !linked.engines_state + for(var/datum/ship_engine/E in linked.engines) + if(linked.engines_state == !E.is_on()) + E.toggle() + . = TRUE - if(href_list["global_toggle"]) - linked.engines_state = !linked.engines_state - for(var/datum/ship_engine/E in linked.engines) - if(linked.engines_state == !E.is_on()) - E.toggle() - return TOPIC_REFRESH + if("set_global_limit") + var/newlim = input("Input new thrust limit (0..100%)", "Thrust limit", linked.thrust_limit*100) as num + if(tgui_status(usr, state) != STATUS_INTERACTIVE) + return FALSE + linked.thrust_limit = clamp(newlim/100, 0, 1) + for(var/datum/ship_engine/E in linked.engines) + E.set_thrust_limit(linked.thrust_limit) + . = TRUE - if(href_list["set_global_limit"]) - var/newlim = input("Input new thrust limit (0..100%)", "Thrust limit", linked.thrust_limit*100) as num - if(!CanInteract(user, state)) - return TOPIC_NOACTION - linked.thrust_limit = CLAMP(newlim/100, 0, 1) - for(var/datum/ship_engine/E in linked.engines) - E.set_thrust_limit(linked.thrust_limit) - return TOPIC_REFRESH + if("global_limit") + linked.thrust_limit = clamp(linked.thrust_limit + text2num(params["global_limit"]), 0, 1) + for(var/datum/ship_engine/E in linked.engines) + E.set_thrust_limit(linked.thrust_limit) + . = TRUE - if(href_list["global_limit"]) - linked.thrust_limit = CLAMP(linked.thrust_limit + text2num(href_list["global_limit"]), 0, 1) - for(var/datum/ship_engine/E in linked.engines) - E.set_thrust_limit(linked.thrust_limit) - return TOPIC_REFRESH - - if(href_list["engine"]) - if(href_list["set_limit"]) - var/datum/ship_engine/E = locate(href_list["engine"]) + if("set_limit") + var/datum/ship_engine/E = locate(params["engine"]) var/newlim = input("Input new thrust limit (0..100)", "Thrust limit", E.get_thrust_limit()) as num - if(!CanInteract(user, state)) - return - var/limit = CLAMP(newlim/100, 0, 1) + if(tgui_status(usr, state) != STATUS_INTERACTIVE) + return FALSE + var/limit = clamp(newlim/100, 0, 1) if(istype(E)) E.set_thrust_limit(limit) - return TOPIC_REFRESH - if(href_list["limit"]) - var/datum/ship_engine/E = locate(href_list["engine"]) - var/limit = CLAMP(E.get_thrust_limit() + text2num(href_list["limit"]), 0, 1) - if(istype(E)) - E.set_thrust_limit(limit) - return TOPIC_REFRESH + . = TRUE - if(href_list["toggle"]) - var/datum/ship_engine/E = locate(href_list["engine"]) + if("limit") + var/datum/ship_engine/E = locate(params["engine"]) + var/limit = clamp(E.get_thrust_limit() + text2num(params["limit"]), 0, 1) + if(istype(E)) + E.set_thrust_limit(limit) + . = TRUE + + if("toggle") + var/datum/ship_engine/E = locate(params["engine"]) if(istype(E)) E.toggle() - return TOPIC_REFRESH - return TOPIC_REFRESH - return TOPIC_NOACTION \ No newline at end of file + . = TRUE + + if(. && !issilicon(usr)) + playsound(src, "terminal_type", 50, 1) \ No newline at end of file diff --git a/code/modules/overmap/ships/computers/helm.dm b/code/modules/overmap/ships/computers/helm.dm index 70deb4347bf..1c231fc4e0a 100644 --- a/code/modules/overmap/ships/computers/helm.dm +++ b/code/modules/overmap/ships/computers/helm.dm @@ -22,6 +22,7 @@ GLOBAL_LIST_EMPTY(all_waypoints) circuit = /obj/item/weapon/circuitboard/helm core_skill = /datum/skill/pilot var/autopilot = 0 + var/autopilot_disabled = TRUE var/list/known_sectors = list() var/dx //desitnation var/dy //coordinates @@ -36,7 +37,7 @@ GLOBAL_LIST_EMPTY(all_waypoints) /obj/machinery/computer/ship/helm/proc/get_known_sectors() var/area/overmap/map = locate() in world for(var/obj/effect/overmap/visitable/sector/S in map) - if (S.known) + if(S.known) var/datum/computer_file/data/waypoint/R = new() R.fields["name"] = S.name R.fields["x"] = S.x @@ -45,7 +46,7 @@ GLOBAL_LIST_EMPTY(all_waypoints) /obj/machinery/computer/ship/helm/process() ..() - if (autopilot && dx && dy) + if(autopilot && dx && dy && !autopilot_disabled) var/turf/T = locate(dx,dy,global.using_map.overmap_z) if(linked.loc == T) if(linked.is_still()) @@ -60,13 +61,13 @@ GLOBAL_LIST_EMPTY(all_waypoints) var/heading = linked.get_heading() // Destination is current grid or speedlimit is exceeded - if ((get_dist(linked.loc, T) <= brake_path) || speed > speedlimit) + if((get_dist(linked.loc, T) <= brake_path) || speed > speedlimit) linked.decelerate() // Heading does not match direction - else if (heading & ~direction) + else if(heading & ~direction) linked.accelerate(turn(heading & ~direction, 180), accellimit) // All other cases, move toward direction - else if (speed + acceleration <= speedlimit) + else if(speed + acceleration <= speedlimit) linked.accelerate(direction, accellimit) linked.operator_skill = null//if this is on you can't dodge meteors return @@ -78,149 +79,176 @@ GLOBAL_LIST_EMPTY(all_waypoints) linked.relaymove(user, direction, accellimit) return 1 -/obj/machinery/computer/ship/helm/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - var/data[0] - +/obj/machinery/computer/ship/helm/tgui_interact(mob/user, datum/tgui/ui) if(!linked) display_reconnect_dialog(user, "helm") + return + + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "OvermapHelm", "[linked.name] Helm Control") // 565, 545 + ui.open() + +/obj/machinery/computer/ship/helm/tgui_data(mob/user) + var/list/data = ..() + + var/turf/T = get_turf(linked) + var/obj/effect/overmap/visitable/sector/current_sector = locate() in T + + data["sector"] = current_sector ? current_sector.name : "Deep Space" + data["sector_info"] = current_sector ? current_sector.desc : "Not Available" + data["landed"] = linked.get_landed_info() + data["s_x"] = linked.x + data["s_y"] = linked.y + data["dest"] = dy && dx + data["d_x"] = dx + data["d_y"] = dy + data["speedlimit"] = speedlimit ? speedlimit*1000 : "Halted" + data["accel"] = min(round(linked.get_acceleration()*1000, 0.01),accellimit*1000) + data["heading"] = linked.get_heading_degrees() + data["autopilot_disabled"] = autopilot_disabled + data["autopilot"] = autopilot + data["manual_control"] = viewing_overmap(user) + data["canburn"] = linked.can_burn() + data["accellimit"] = accellimit*1000 + + var/speed = round(linked.get_speed()*1000, 0.01) + var/speed_color = null + if(linked.get_speed() < SHIP_SPEED_SLOW) + speed_color = "good" + if(linked.get_speed() > SHIP_SPEED_FAST) + speed_color = "average" + data["speed"] = speed + data["speed_color"] = speed_color + + if(linked.get_speed()) + data["ETAnext"] = "[round(linked.ETA()/10)] seconds" else - var/turf/T = get_turf(linked) - var/obj/effect/overmap/visitable/sector/current_sector = locate() in T + data["ETAnext"] = "N/A" - data["sector"] = current_sector ? current_sector.name : "Deep Space" - data["sector_info"] = current_sector ? current_sector.desc : "Not Available" - data["landed"] = linked.get_landed_info() - data["s_x"] = linked.x - data["s_y"] = linked.y - data["dest"] = dy && dx - data["d_x"] = dx - data["d_y"] = dy - data["speedlimit"] = speedlimit ? speedlimit*1000 : "Halted" - data["accel"] = min(round(linked.get_acceleration()*1000, 0.01),accellimit*1000) - data["heading"] = linked.get_heading_degrees() - data["autopilot"] = autopilot - data["manual_control"] = viewing_overmap(user) - data["canburn"] = linked.can_burn() - data["accellimit"] = accellimit*1000 + var/list/locations[0] + for (var/key in known_sectors) + var/datum/computer_file/data/waypoint/R = known_sectors[key] + var/list/rdata[0] + rdata["name"] = R.fields["name"] + rdata["x"] = R.fields["x"] + rdata["y"] = R.fields["y"] + rdata["reference"] = "\ref[R]" + locations.Add(list(rdata)) - var/speed = round(linked.get_speed()*1000, 0.01) - if(linked.get_speed() < SHIP_SPEED_SLOW) - speed = "[speed]" - if(linked.get_speed() > SHIP_SPEED_FAST) - speed = "[speed]" - data["speed"] = speed + data["locations"] = locations + return data - if(linked.get_speed()) - data["ETAnext"] = "[round(linked.ETA()/10)] seconds" - else - data["ETAnext"] = "N/A" - - var/list/locations[0] - for (var/key in known_sectors) - var/datum/computer_file/data/waypoint/R = known_sectors[key] - var/list/rdata[0] - rdata["name"] = R.fields["name"] - rdata["x"] = R.fields["x"] - rdata["y"] = R.fields["y"] - rdata["reference"] = "\ref[R]" - locations.Add(list(rdata)) - - data["locations"] = locations - - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "helm.tmpl", "[linked.name] Helm Control", 565, 545) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) - -/obj/machinery/computer/ship/helm/OnTopic(var/mob/user, var/list/href_list, state) +/obj/machinery/computer/ship/helm/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) if(..()) - return TOPIC_HANDLED + return TRUE if(!linked) - return TOPIC_HANDLED + return FALSE - if (href_list["add"]) - var/datum/computer_file/data/waypoint/R = new() - var/sec_name = input("Input naviation entry name", "New navigation entry", "Sector #[known_sectors.len]") as text - if(!CanInteract(user,state)) - return TOPIC_NOACTION - if(!sec_name) - sec_name = "Sector #[known_sectors.len]" - R.fields["name"] = sec_name - if(sec_name in known_sectors) - to_chat(user, "Sector with that name already exists, please input a different name.") - return TOPIC_REFRESH - switch(href_list["add"]) - if("current") - R.fields["x"] = linked.x - R.fields["y"] = linked.y - if("new") - var/newx = input("Input new entry x coordinate", "Coordinate input", linked.x) as num - if(!CanInteract(user,state)) - return TOPIC_REFRESH - var/newy = input("Input new entry y coordinate", "Coordinate input", linked.y) as num - if(!CanInteract(user,state)) - return TOPIC_NOACTION - R.fields["x"] = CLAMP(newx, 1, world.maxx) - R.fields["y"] = CLAMP(newy, 1, world.maxy) - known_sectors[sec_name] = R + switch(action) + if("add") + var/datum/computer_file/data/waypoint/R = new() + var/sec_name = input("Input navigation entry name", "New navigation entry", "Sector #[known_sectors.len]") as text + if(tgui_status(usr, state) != STATUS_INTERACTIVE) + return FALSE + if(!sec_name) + sec_name = "Sector #[known_sectors.len]" + R.fields["name"] = sec_name + if(sec_name in known_sectors) + to_chat(usr, "Sector with that name already exists, please input a different name.") + return TRUE + switch(params["add"]) + if("current") + R.fields["x"] = linked.x + R.fields["y"] = linked.y + if("new") + var/newx = input("Input new entry x coordinate", "Coordinate input", linked.x) as num + if(tgui_status(usr, state) != STATUS_INTERACTIVE) + return TRUE + var/newy = input("Input new entry y coordinate", "Coordinate input", linked.y) as num + if(tgui_status(usr, state) != STATUS_INTERACTIVE) + return FALSE + R.fields["x"] = CLAMP(newx, 1, world.maxx) + R.fields["y"] = CLAMP(newy, 1, world.maxy) + known_sectors[sec_name] = R + . = TRUE - if (href_list["remove"]) - var/datum/computer_file/data/waypoint/R = locate(href_list["remove"]) - if(R) - known_sectors.Remove(R.fields["name"]) - qdel(R) + if("remove") + var/datum/computer_file/data/waypoint/R = locate(params["remove"]) + if(R) + known_sectors.Remove(R.fields["name"]) + qdel(R) + . = TRUE - if (href_list["setx"]) - var/newx = input("Input new destiniation x coordinate", "Coordinate input", dx) as num|null - if(!CanInteract(user,state)) - return - if (newx) - dx = CLAMP(newx, 1, world.maxx) + if("setcoord") + if(params["setx"]) + var/newx = input("Input new destiniation x coordinate", "Coordinate input", dx) as num|null + if(tgui_status(usr, state) != STATUS_INTERACTIVE) + return + if(newx) + dx = CLAMP(newx, 1, world.maxx) - if (href_list["sety"]) - var/newy = input("Input new destiniation y coordinate", "Coordinate input", dy) as num|null - if(!CanInteract(user,state)) - return - if (newy) - dy = CLAMP(newy, 1, world.maxy) + if(params["sety"]) + var/newy = input("Input new destiniation y coordinate", "Coordinate input", dy) as num|null + if(tgui_status(usr, state) != STATUS_INTERACTIVE) + return + if(newy) + dy = CLAMP(newy, 1, world.maxy) + . = TRUE - if (href_list["x"] && href_list["y"]) - dx = text2num(href_list["x"]) - dy = text2num(href_list["y"]) + if("setds") + dx = text2num(params["x"]) + dy = text2num(params["y"]) + . = TRUE - if (href_list["reset"]) - dx = 0 - dy = 0 + if("reset") + dx = 0 + dy = 0 + . = TRUE - if (href_list["speedlimit"]) - var/newlimit = input("Input new speed limit for autopilot (0 to brake)", "Autopilot speed limit", speedlimit*1000) as num|null - if(newlimit) - speedlimit = CLAMP(newlimit/1000, 0, 100) - if (href_list["accellimit"]) - var/newlimit = input("Input new acceleration limit", "Acceleration limit", accellimit*1000) as num|null - if(newlimit) - accellimit = max(newlimit/1000, 0) + if("speedlimit") + var/newlimit = input("Input new speed limit for autopilot (0 to brake)", "Autopilot speed limit", speedlimit*1000) as num|null + if(newlimit) + speedlimit = CLAMP(newlimit/1000, 0, 100) + . = TRUE - if (href_list["move"]) - var/ndir = text2num(href_list["move"]) - if(prob(user.skill_fail_chance(/datum/skill/pilot, 50, linked.skill_needed, factor = 1))) - ndir = turn(ndir,pick(90,-90)) - linked.relaymove(user, ndir, accellimit) + if("accellimit") + var/newlimit = input("Input new acceleration limit", "Acceleration limit", accellimit*1000) as num|null + if(newlimit) + accellimit = max(newlimit/1000, 0) + . = TRUE - if (href_list["brake"]) - linked.decelerate() + if("move") + var/ndir = text2num(params["dir"]) + if(prob(usr.skill_fail_chance(/datum/skill/pilot, 50, linked.skill_needed, factor = 1))) + ndir = turn(ndir,pick(90,-90)) + linked.relaymove(usr, ndir, accellimit) + . = TRUE - if (href_list["apilot"]) - autopilot = !autopilot + if("brake") + linked.decelerate() + . = TRUE - if (href_list["manual"]) - viewing_overmap(user) ? unlook(user) : look(user) + if("apilot") + if(autopilot_disabled) + autopilot = FALSE + else + autopilot = !autopilot + . = TRUE + + if("apilot_lock") + autopilot_disabled = !autopilot_disabled + autopilot = FALSE + . = TRUE - add_fingerprint(user) - updateUsrDialog() + if("manual") + viewing_overmap(usr) ? unlook(usr) : look(usr) + . = TRUE + + add_fingerprint(usr) + if(. && !issilicon(usr)) + playsound(src, "terminal_type", 50, 1) /obj/machinery/computer/ship/navigation @@ -228,49 +256,21 @@ GLOBAL_LIST_EMPTY(all_waypoints) icon_keyboard = "generic_key" icon_screen = "helm" circuit = /obj/item/weapon/circuitboard/nav + var/datum/tgui_module/ship/nav/nav_tgui -/obj/machinery/computer/ship/navigation/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - if(!linked) - display_reconnect_dialog(user, "Navigation") - return +/obj/machinery/computer/ship/navigation/Initialize() + . = ..() + nav_tgui = new(src) - var/data[0] +/obj/machinery/computer/ship/navigation/Destroy() + QDEL_NULL(nav_tgui) + . = ..() +/obj/machinery/computer/ship/navigation/sync_linked(user) + return nav_tgui?.sync_linked() - var/turf/T = get_turf(linked) - var/obj/effect/overmap/visitable/sector/current_sector = locate() in T - - data["sector"] = current_sector ? current_sector.name : "Deep Space" - data["sector_info"] = current_sector ? current_sector.desc : "Not Available" - data["s_x"] = linked.x - data["s_y"] = linked.y - data["speed"] = round(linked.get_speed()*1000, 0.01) - data["accel"] = round(linked.get_acceleration()*1000, 0.01) - data["heading"] = linked.get_heading_degrees() - data["viewing"] = viewing_overmap(user) - - if(linked.get_speed()) - data["ETAnext"] = "[round(linked.ETA()/10)] seconds" - else - data["ETAnext"] = "N/A" - - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "nav.tmpl", "[linked.name] Navigation Screen", 380, 530) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) - -/obj/machinery/computer/ship/navigation/OnTopic(var/mob/user, var/list/href_list) - if(..()) - return TOPIC_HANDLED - - if (!linked) - return TOPIC_NOACTION - - if (href_list["viewing"]) - viewing_overmap(user) ? unlook(user) : look(user) - return TOPIC_REFRESH +/obj/machinery/computer/ship/navigation/tgui_interact(mob/user, datum/tgui/ui) + return nav_tgui?.tgui_interact(user, ui) /obj/machinery/computer/ship/navigation/telescreen //little hacky but it's only used on one ship so it should be okay icon_state = "tele_nav" diff --git a/code/modules/overmap/ships/computers/sensors.dm b/code/modules/overmap/ships/computers/sensors.dm index e4e77f90059..61f82976330 100644 --- a/code/modules/overmap/ships/computers/sensors.dm +++ b/code/modules/overmap/ships/computers/sensors.dm @@ -20,14 +20,29 @@ sensors = S break -/obj/machinery/computer/ship/sensors/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) +/obj/machinery/computer/ship/sensors/tgui_interact(mob/user, datum/tgui/ui) if(!linked) display_reconnect_dialog(user, "sensors") return - var/data[0] + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "OvermapShipSensors", "[linked.name] Sensors Control") // 420, 530 + ui.open() + +/obj/machinery/computer/ship/sensors/tgui_data(mob/user) + var/list/data = list() data["viewing"] = viewing_overmap(user) + data["on"] = 0 + data["range"] = "N/A" + data["health"] = 0 + data["max_health"] = 0 + data["heat"] = 0 + data["critical_heat"] = 0 + data["status"] = "MISSING" + data["contacts"] = list() + if(sensors) data["on"] = sensors.use_power data["range"] = sensors.range @@ -53,54 +68,48 @@ if(bearing < 0) bearing += 360 contacts.Add(list(list("name"=O.name, "ref"="\ref[O]", "bearing"=bearing))) - if(contacts.len) - data["contacts"] = contacts - else - data["status"] = "MISSING" - data["range"] = "N/A" - data["on"] = 0 + data["contacts"] = contacts - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "shipsensors.tmpl", "[linked.name] Sensors Control", 420, 530, src) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) + return data -/obj/machinery/computer/ship/sensors/OnTopic(var/mob/user, var/list/href_list, state) +/obj/machinery/computer/ship/sensors/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) if(..()) - return TOPIC_HANDLED + return TRUE - if (!linked) - return TOPIC_NOACTION + if(!linked) + return FALSE - if (href_list["viewing"]) - if(user && !isAI(user)) - viewing_overmap(user) ? unlook(user) : look(user) - return TOPIC_REFRESH + switch(action) + if("viewing") + if(usr && !isAI(usr)) + viewing_overmap(usr) ? unlook(usr) : look(usr) + . = TRUE - if (href_list["link"]) - find_sensors() - return TOPIC_REFRESH + if("link") + find_sensors() + . = TRUE + + if("scan") + var/obj/effect/overmap/O = locate(params["scan"]) + if(istype(O) && !QDELETED(O) && (O in view(7,linked))) + new/obj/item/weapon/paper/(get_turf(src), O.get_scan_data(usr), "paper (Sensor Scan - [O])") + . = TRUE if(sensors) - if (href_list["range"]) - var/nrange = input("Set new sensors range", "Sensor range", sensors.range) as num|null - if(!CanInteract(user,state)) - return TOPIC_NOACTION - if (nrange) - sensors.set_range(CLAMP(nrange, 1, world.view)) - return TOPIC_REFRESH - if (href_list["toggle"]) - sensors.toggle() - return TOPIC_REFRESH + switch(action) + if("range") + var/nrange = input("Set new sensors range", "Sensor range", sensors.range) as num|null + if(tgui_status(usr, state) != STATUS_INTERACTIVE) + return FALSE + if(nrange) + sensors.set_range(CLAMP(nrange, 1, world.view)) + . = TRUE + if("toggle") + sensors.toggle() + . = TRUE - if (href_list["scan"]) - var/obj/effect/overmap/O = locate(href_list["scan"]) - if(istype(O) && !QDELETED(O) && (O in view(7,linked))) - playsound(src, "sound/machines/dotprinter.ogg", 30, 1) - new/obj/item/weapon/paper/(get_turf(src), O.get_scan_data(user), "paper (Sensor Scan - [O])") - return TOPIC_HANDLED + if(. && !issilicon(usr)) + playsound(src, "terminal_type", 50, 1) /obj/machinery/computer/ship/sensors/process() ..() diff --git a/code/modules/overmap/ships/computers/ship.dm b/code/modules/overmap/ships/computers/ship.dm index 497077a76e1..f0d54125aed 100644 --- a/code/modules/overmap/ships/computers/ship.dm +++ b/code/modules/overmap/ships/computers/ship.dm @@ -37,22 +37,31 @@ somewhere on that shuttle. Subtypes of these can be then used to perform ship ov popup.set_content("
Error
Unable to connect to [flavor].
Reconnect
") popup.open() +/obj/machinery/computer/ship/Topic(href, href_list) + if(..()) + return TRUE + if(href_list["sync"]) + if(sync_linked(usr)) + interface_interact(usr) + return TRUE + // In computer_shims for now - we had to define it. // /obj/machinery/computer/ship/interface_interact(var/mob/user) // ui_interact(user) // return TRUE -/obj/machinery/computer/ship/OnTopic(var/mob/user, var/list/href_list) +/obj/machinery/computer/ship/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) if(..()) - return TOPIC_HANDLED - if(href_list["sync"]) - sync_linked(user) - return TOPIC_REFRESH - if(href_list["close"]) - unlook(user) - user.unset_machine() - return TOPIC_HANDLED - return TOPIC_NOACTION + return TRUE + switch(action) + if("sync") + sync_linked(usr) + return TRUE + if("close") + unlook(usr) + usr.unset_machine() + return TRUE + return FALSE // Management of mob view displacement. look to shift view to the ship on the overmap; unlook to shift back. @@ -60,6 +69,7 @@ somewhere on that shuttle. Subtypes of these can be then used to perform ship ov if(linked) apply_visual(user) user.reset_view(linked) + user.set_machine(src) user.set_viewsize(world.view + extra_view) GLOB.moved_event.register(user, src, /obj/machinery/computer/ship/proc/unlook) // TODO GLOB.stat_set_event.register(user, src, /obj/machinery/computer/ship/proc/unlook) @@ -75,17 +85,21 @@ somewhere on that shuttle. Subtypes of these can be then used to perform ship ov /obj/machinery/computer/ship/proc/viewing_overmap(mob/user) return (weakref(user) in viewers) -/obj/machinery/computer/ship/CouldNotUseTopic(mob/user) +/obj/machinery/computer/ship/tgui_status(mob/user) . = ..() + if(. > STATUS_DISABLED) + if(viewing_overmap(user)) + look(user) + return unlook(user) -/obj/machinery/computer/ship/CouldUseTopic(mob/user) +/obj/machinery/computer/ship/tgui_close(mob/user) . = ..() - if(viewing_overmap(user)) - look(user) + user.unset_machine() + unlook(user) /obj/machinery/computer/ship/check_eye(var/mob/user) - if (!get_dist(user, src) > 1 || user.blinded || !linked ) + if(!get_dist(user, src) > 1 || user.blinded || !linked) unlook(user) return -1 else diff --git a/code/modules/overmap/ships/computers/shuttle.dm b/code/modules/overmap/ships/computers/shuttle.dm index 42904d2a422..f51587d5942 100644 --- a/code/modules/overmap/ships/computers/shuttle.dm +++ b/code/modules/overmap/ships/computers/shuttle.dm @@ -2,9 +2,9 @@ /obj/machinery/computer/shuttle_control/explore name = "general shuttle control console" circuit = /obj/item/weapon/circuitboard/shuttle_console/explore - ui_template = "shuttle_control_console_exploration.tmpl" + tgui_subtemplate = "ShuttleControlConsoleExploration" -/obj/machinery/computer/shuttle_control/explore/get_ui_data(var/datum/shuttle/autodock/overmap/shuttle) +/obj/machinery/computer/shuttle_control/explore/shuttlerich_tgui_data(var/datum/shuttle/autodock/overmap/shuttle) . = ..() if(istype(shuttle)) var/total_gas = 0 @@ -25,22 +25,28 @@ "fuel_span" = fuel_span ) -/obj/machinery/computer/shuttle_control/explore/handle_topic_href(var/datum/shuttle/autodock/overmap/shuttle, var/list/href_list) +/obj/machinery/computer/shuttle_control/explore/tgui_act(action, list/params) + if(..()) + return TRUE + + var/datum/shuttle/autodock/overmap/shuttle = SSshuttles.shuttles[shuttle_tag] + if(!istype(shuttle)) + to_chat(usr, "Unable to establish link with the shuttle.") + return TRUE + if(ismob(usr)) var/mob/user = usr shuttle.operator_skill = user.get_skill_value(/datum/skill/pilot) - if((. = ..()) != null) - return - - if(href_list["pick"]) - var/list/possible_d = shuttle.get_possible_destinations() - var/D - if(possible_d.len) - D = input("Choose shuttle destination", "Shuttle Destination") as null|anything in possible_d - else - to_chat(usr,"No valid landing sites in range.") - possible_d = shuttle.get_possible_destinations() - if(CanInteract(usr, global.default_state) && (D in possible_d)) - shuttle.set_destination(possible_d[D]) - return TOPIC_REFRESH + switch(action) + if("pick") + var/list/possible_d = shuttle.get_possible_destinations() + var/D + if(possible_d.len) + D = input("Choose shuttle destination", "Shuttle Destination") as null|anything in possible_d + else + to_chat(usr,"No valid landing sites in range.") + possible_d = shuttle.get_possible_destinations() + if(CanInteract(usr, global.default_state) && (D in possible_d)) + shuttle.set_destination(possible_d[D]) + return TRUE diff --git a/code/modules/overmap/ships/engines/engine.dm b/code/modules/overmap/ships/engines/engine.dm index a5d3bc70164..5f8ef4f3be7 100644 --- a/code/modules/overmap/ships/engines/engine.dm +++ b/code/modules/overmap/ships/engines/engine.dm @@ -19,7 +19,7 @@ var/list/ship_engines = list() //Returns status string for this engine /datum/ship_engine/proc/get_status() - return "All systems nominal" + return list("All systems nominal") /datum/ship_engine/proc/get_thrust() return 1 diff --git a/code/modules/overmap/ships/engines/gas_thruster.dm b/code/modules/overmap/ships/engines/gas_thruster.dm index fd689fb9907..667cbae441b 100644 --- a/code/modules/overmap/ships/engines/gas_thruster.dm +++ b/code/modules/overmap/ships/engines/gas_thruster.dm @@ -103,18 +103,17 @@ . = list() .+= "Location: [get_area(src)]." if(stat & NOPOWER) - .+= "Insufficient power to operate." + .+= list(list("Insufficient power to operate.", "bad")) if(!check_fuel()) - .+= "Insufficient fuel for a burn." + .+= list(list("Insufficient fuel for a burn.", "bad")) if(stat & BROKEN) - .+= "Inoperable engine configuration." + .+= list(list("Inoperable engine configuration.", "bad")) if(blockage) - .+= "Obstruction of airflow detected." + .+= list(list("Obstruction of airflow detected.", "bad")) .+= "Propellant total mass: [round(air_contents.get_mass(),0.01)] kg." .+= "Propellant used per burn: [round(air_contents.get_mass() * volume_per_burn * thrust_limit / air_contents.volume,0.01)] kg." .+= "Propellant pressure: [round(air_contents.return_pressure()/1000,0.1)] MPa." - . = jointext(.,"
") /obj/machinery/atmospherics/unary/engine/power_change() . = ..() diff --git a/code/modules/overmap/ships/engines/ion_thruster.dm b/code/modules/overmap/ships/engines/ion_thruster.dm index 32521593910..222c801611c 100644 --- a/code/modules/overmap/ships/engines/ion_thruster.dm +++ b/code/modules/overmap/ships/engines/ion_thruster.dm @@ -61,9 +61,7 @@ . = list() .+= "Location: [get_area(src)]." if(!powered()) - .+= "Insufficient power to operate." - - . = jointext(.,"
") + .+= list(list("Insufficient power to operate.", "bad")) /obj/machinery/ion_engine/proc/burn() if(!on && !powered()) diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index 5618257494c..c749871815c 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -34,6 +34,8 @@ var/spam_flag = 0 var/age = 0 var/last_modified_ckey + + var/was_maploaded = FALSE // This tracks if the paper was created on mapload. var/const/deffont = "Verdana" var/const/signfont = "Times New Roman" @@ -103,6 +105,12 @@ //lipstick wiping is in code/game/objects/items/weapons/cosmetics.dm! +/obj/item/weapon/paper/Initialize(mapload) + . = ..() + + if(mapload) // Jank, but we do this to prevent maploaded papers from somehow stacking across rounds if re-added to the board by a player. + was_maploaded = TRUE + /obj/item/weapon/paper/New(var/newloc, var/text, var/title) ..() pixel_y = rand(-8, 8) @@ -444,8 +452,12 @@ // if paper is not in usr, then it must be near them, or in a clipboard or folder, which must be in or near usr - if(src.loc != usr && !src.Adjacent(usr) && !((istype(src.loc, /obj/item/weapon/clipboard) || istype(src.loc, /obj/item/weapon/folder)) && (src.loc.loc == usr || src.loc.Adjacent(usr)) ) ) + if(istype(loc, /obj/item/weapon/clipboard) || istype(loc, /obj/structure/noticeboard) || istype(loc, /obj/item/weapon/folder)) + if(loc.loc != usr && !in_range(loc, usr)) + return + else if(loc != usr && !Adjacent(usr)) return + /* t = checkhtml(t) @@ -463,6 +475,7 @@ //t = html_encode(t) t = replacetext(t, "\n", "
") t = parsepencode(t, i, usr, iscrayon) // Encode everything from pencode to html + was_maploaded = FALSE // Set this to FALSE because a user has written on us. This is for persistence purposes. if(fields > 50)//large amount of fields creates a heavy load on the server, see updateinfolinks() and addtofield() diff --git a/code/modules/persistence/datum/datum_filth.dm b/code/modules/persistence/datum/datum_filth.dm index f41fffcfb7f..10b304e18ee 100644 --- a/code/modules/persistence/datum/datum_filth.dm +++ b/code/modules/persistence/datum/datum_filth.dm @@ -1,7 +1,7 @@ /datum/persistent/filth name = "filth" tokens_per_line = 5 - entries_expire_at = 5 + entries_expire_at = 4 // 4 rounds, 24 hours. /datum/persistent/filth/LabelTokens(var/list/tokens) var/list/labelled_tokens = ..() diff --git a/code/modules/persistence/datum/datum_graffiti.dm b/code/modules/persistence/datum/datum_graffiti.dm index b70b7f94751..6ca1bbf32f9 100644 --- a/code/modules/persistence/datum/datum_graffiti.dm +++ b/code/modules/persistence/datum/datum_graffiti.dm @@ -1,7 +1,7 @@ /datum/persistent/graffiti name = "graffiti" tokens_per_line = 6 - entries_expire_at = 50 + entries_expire_at = 4 // This previously was at 50 rounds??? Over 10 days. has_admin_data = TRUE /datum/persistent/graffiti/LabelTokens(var/list/tokens) diff --git a/code/modules/persistence/datum/datum_paper.dm b/code/modules/persistence/datum/datum_paper.dm index e572faea013..fe2ef813681 100644 --- a/code/modules/persistence/datum/datum_paper.dm +++ b/code/modules/persistence/datum/datum_paper.dm @@ -24,11 +24,13 @@ if(requires_noticeboard && LAZYLEN(board.notices) >= board.max_notices) return var/obj/item/weapon/paper/paper = new paper_type(creating) - paper.set_content(tokens["message"], tokens["title"]) + paper.info = tokens["message"] + paper.name = tokens["title"] paper.last_modified_ckey = tokens["author"] if(requires_noticeboard) board.add_paper(paper) - SSpersistence.track_value(paper, type) + if(!paper.was_maploaded) // If we were created/loaded when the map was made, skip us! + SSpersistence.track_value(paper, type) return paper /datum/persistent/paper/GetEntryAge(var/atom/entry) diff --git a/code/modules/persistence/datum/persistence_datum.dm b/code/modules/persistence/datum/persistence_datum.dm index 8a409404cd6..e001e12e302 100644 --- a/code/modules/persistence/datum/persistence_datum.dm +++ b/code/modules/persistence/datum/persistence_datum.dm @@ -6,8 +6,8 @@ var/name var/filename var/tokens_per_line - var/entries_expire_at - var/entries_decay_at + var/entries_expire_at // Set in rounds, this controls when the item is finally removed permanently regardless if cleaned or not. + var/entries_decay_at // Set in rounds. This controls when item messages start getting scrambled. var/entry_decay_weight = 0.5 var/file_entry_split_character = "\t" var/file_entry_substitute_character = " " diff --git a/code/modules/persistence/graffiti.dm b/code/modules/persistence/graffiti.dm index ee1a1b7fce8..2780c3b9a4e 100644 --- a/code/modules/persistence/graffiti.dm +++ b/code/modules/persistence/graffiti.dm @@ -21,13 +21,14 @@ if(!isnull(author)) author = _author -/obj/effect/decal/writing/Initialize() +/obj/effect/decal/writing/Initialize(mapload) var/list/random_icon_states = icon_states(icon) for(var/obj/effect/decal/writing/W in loc) random_icon_states.Remove(W.icon_state) if(random_icon_states.len) icon_state = pick(random_icon_states) - SSpersistence.track_value(src, /datum/persistent/graffiti) + if(!mapload || !config.persistence_ignore_mapload) + SSpersistence.track_value(src, /datum/persistent/graffiti) . = ..() /obj/effect/decal/writing/Destroy() diff --git a/code/modules/persistence/noticeboard.dm b/code/modules/persistence/noticeboard.dm index ad8cfef590b..046972ee365 100644 --- a/code/modules/persistence/noticeboard.dm +++ b/code/modules/persistence/noticeboard.dm @@ -20,36 +20,6 @@ if(LAZYLEN(notices) >= max_notices) break - // Automatically place noticeboards that aren't mapped to specific positions. - if(pixel_x == 0 && pixel_y == 0) - - var/turf/here = get_turf(src) - var/placing = 0 - for(var/checkdir in GLOB.cardinal) - var/turf/T = get_step(here, checkdir) - if(T.density) - placing = checkdir - break - for(var/thing in T) - var/atom/A = thing - if(A.simulated && !A.CanPass(src, T)) - placing = checkdir - break - - switch(placing) - if(NORTH) - pixel_x = 0 - pixel_y = 32 - if(SOUTH) - pixel_x = 0 - pixel_y = -32 - if(EAST) - pixel_x = 32 - pixel_y = 0 - if(WEST) - pixel_x = -32 - pixel_y = 0 - update_icon() /obj/structure/noticeboard/proc/add_paper(var/atom/movable/paper, var/skip_icon_update) @@ -77,16 +47,16 @@ QDEL_NULL_LIST(notices) . = ..() -/obj/structure/noticeboard/ex_act(var/severity) +/obj/structure/noticeboard/ex_act(severity) dismantle() /obj/structure/noticeboard/update_icon() icon_state = "[base_icon_state][LAZYLEN(notices)]" -/obj/structure/noticeboard/attackby(var/obj/item/weapon/thing, var/mob/user) - if(thing.is_screwdriver()) - var/choice = input("Which direction do you wish to place the noticeboard?", "Noticeboard Offset") as null|anything in list("North", "South", "East", "West") - if(choice && Adjacent(user) && thing.loc == user && !user.incapacitated()) +/obj/structure/noticeboard/attackby(obj/item/I, mob/user) + if(I.is_screwdriver()) + var/choice = input("Which direction do you wish to place the noticeboard?", "Noticeboard Offset") as null|anything in list("North", "South", "East", "West", "No Offset") + if(choice && Adjacent(user) && I.loc == user && !user.incapacitated()) playsound(loc, 'sound/items/Screwdriver.ogg', 50, 1) switch(choice) if("North") @@ -101,27 +71,29 @@ if("West") pixel_x = -32 pixel_y = 0 + if("No Offset") + return return - else if(thing.is_wrench()) - visible_message(SPAN_WARNING("\The [user] begins dismantling \the [src].")) + else if(I.is_wrench()) + visible_message("[user] begins dismantling [src].") playsound(loc, 'sound/items/Ratchet.ogg', 50, 1) if(do_after(user, 50, src)) - visible_message(SPAN_DANGER("\The [user] has dismantled \the [src]!")) + visible_message("[user] has dismantled [src]!") dismantle() return - else if(istype(thing, /obj/item/weapon/paper) || istype(thing, /obj/item/weapon/photo)) + else if(istype(I, /obj/item/weapon/paper) || istype(I, /obj/item/weapon/photo)) if(jobban_isbanned(user, "Graffiti")) - to_chat(user, SPAN_WARNING("You are banned from leaving persistent information across rounds.")) + to_chat(user, "You are banned from leaving persistent information across rounds.") else - if(LAZYLEN(notices) < max_notices && user.unEquip(thing, src)) + if(LAZYLEN(notices) < max_notices && user.unEquip(I, src)) add_fingerprint(user) - add_paper(thing) - to_chat(user, SPAN_NOTICE("You pin \the [thing] to \the [src].")) - SSpersistence.track_value(thing, /datum/persistent/paper) + add_paper(I) + to_chat(user, "You pin [I] to [src].") + SSpersistence.track_value(I, /datum/persistent/paper) else - to_chat(user, SPAN_WARNING("You hesitate, certain \the [thing] will not be seen among the many others already attached to \the [src].")) + to_chat(user, "You hesitate, certain [I] will not be seen among the many others already attached to \the [src].") return - ..() + return ..() /obj/structure/noticeboard/attack_ai(var/mob/user) examine(user) @@ -129,56 +101,71 @@ /obj/structure/noticeboard/attack_hand(var/mob/user) examine(user) -/obj/structure/noticeboard/examine(var/mob/user) - . = ..() - if(.) - var/list/dat = list("") - for(var/thing in notices) - LAZYADD(dat, "") - var/datum/browser/popup = new(user, "noticeboard-\ref[src]", "Noticeboard") - popup.set_content(jointext(dat, null)) - popup.open() +/obj/structure/noticeboard/examine(mob/user) + tgui_interact(user) + return list() -/obj/structure/noticeboard/Topic(var/mob/user, var/list/href_list) - if(href_list["read"]) - var/obj/item/weapon/paper/P = locate(href_list["read"]) - if(P && P.loc == src) - P.show_content(user) - . = TOPIC_HANDLED +/obj/structure/noticeboard/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "NoticeBoard", name) + ui.open() - if(href_list["look"]) - var/obj/item/weapon/photo/P = locate(href_list["look"]) - if(P && P.loc == src) - P.show(user) - . = TOPIC_HANDLED +/obj/structure/noticeboard/tgui_data(mob/user) + var/list/data = ..() + + data["notices"] = list() + for(var/obj/item/I in notices) + data["notices"].Add(list(list( + "ispaper" = istype(I, /obj/item/weapon/paper), + "isphoto" = istype(I, /obj/item/weapon/photo), + "name" = I.name, + "ref" = "\ref[I]", + ))) - if(href_list["remove"]) - remove_paper(locate(href_list["remove"])) - add_fingerprint(user) - . = TOPIC_REFRESH + return data - if(href_list["write"]) - if((usr.stat || usr.restrained())) //For when a player is handcuffed while they have the notice window open - return - var/obj/item/P = locate(href_list["write"]) - if((P && P.loc == src)) //ifthe paper's on the board - var/mob/living/M = usr - if(istype(M)) - var/obj/item/weapon/pen/E = M.get_type_in_hands(/obj/item/weapon/pen) - if(E) - add_fingerprint(M) - P.attackby(E, usr) - else - to_chat(M, "You'll need something to write with!") - . = TOPIC_REFRESH +/obj/structure/noticeboard/tgui_act(action, params) + if(..()) + return TRUE - if(. == TOPIC_REFRESH) - interact(user) + switch(action) + if("read") + var/obj/item/weapon/paper/P = locate(params["ref"]) + if(P && P.loc == src) + P.show_content(usr) + . = TRUE + + if("look") + var/obj/item/weapon/photo/P = locate(params["ref"]) + if(P && P.loc == src) + P.show(usr) + . = TRUE + + if("remove") + if(!in_range(src, usr)) + return FALSE + var/obj/item/I = locate(params["ref"]) + remove_paper(I) + if(istype(I)) + usr.put_in_hands(I) + add_fingerprint(usr) + . = TRUE + + if("write") + if(!in_range(src, usr)) + return FALSE + var/obj/item/P = locate(params["ref"]) + if((P && P.loc == src)) //if the paper's on the board + var/mob/living/M = usr + if(istype(M)) + var/obj/item/weapon/pen/E = M.get_type_in_hands(/obj/item/weapon/pen) + if(E) + add_fingerprint(M) + P.attackby(E, usr) + else + to_chat(M, "You'll need something to write with!") + . = TRUE /obj/structure/noticeboard/anomaly notices = 5 @@ -190,32 +177,32 @@ P.info = "
We keep test dummies in pens here for a reason, so standard procedure should be to activate newfound alien artifacts and place the two in close proximity. Promising items I might even approve monkey testing on." P.stamped = list(/obj/item/weapon/stamp/rd) P.overlays = list("paper_stamped_rd") - src.contents += P + contents += P P = new() P.name = "Memo RE: materials gathering" P.info = "Corasang,
the hands-on approach to gathering our samples may very well be slow at times, but it's safer than allowing the blundering miners to roll willy-nilly over our dig sites in their mechs, destroying everything in the process. And don't forget the escavation tools on your way out there!
- R.W" P.stamped = list(/obj/item/weapon/stamp/rd) P.overlays = list("paper_stamped_rd") - src.contents += P + contents += P P = new() P.name = "Memo RE: ethical quandaries" P.info = "Darion-

I don't care what his rank is, our business is that of science and knowledge - questions of moral application do not come into this. Sure, so there are those who would employ the energy-wave particles my modified device has managed to abscond for their own personal gain, but I can hardly see the practical benefits of some of these artifacts our benefactors left behind. Ward--" P.stamped = list(/obj/item/weapon/stamp/rd) P.overlays = list("paper_stamped_rd") - src.contents += P + contents += P P = new() P.name = "READ ME! Before you people destroy any more samples" P.info = "how many times do i have to tell you people, these xeno-arch samples are del-i-cate, and should be handled so! careful application of a focussed, concentrated heat or some corrosive liquids should clear away the extraneous carbon matter, while application of an energy beam will most decidedly destroy it entirely - like someone did to the chemical dispenser! W, the one who signs your paychecks" P.stamped = list(/obj/item/weapon/stamp/rd) P.overlays = list("paper_stamped_rd") - src.contents += P + contents += P P = new() P.name = "Reminder regarding the anomalous material suits" P.info = "Do you people think the anomaly suits are cheap to come by? I'm about a hair trigger away from instituting a log book for the damn things. Only wear them if you're going out for a dig, and for god's sake don't go tramping around in them unless you're field testing something, R" P.stamped = list(/obj/item/weapon/stamp/rd) P.overlays = list("paper_stamped_rd") - src.contents += P \ No newline at end of file + contents += P \ No newline at end of file diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index 1ab2d6a5ea9..183956e5629 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -110,17 +110,10 @@ var/list/possible_cable_coil_colours = list( cable_list -= src //remove it from global cable list return ..() // then go ahead and delete the cable -// Ghost examining the cable -> tells him the power -/obj/structure/cable/attack_ghost(mob/user) - if(user.client && user.client.inquisitive_ghost) - user.examinate(src) - // following code taken from attackby (multitool) - if(powernet && (powernet.avail > 0)) - to_chat(user, "[DisplayPower(powernet.avail)] in power network.") - else - to_chat(user, "The cable is not powered.") - return - +/obj/structure/cable/examine(mob/user) + . = ..() + if(isobserver(user)) + . += "[powernet?.avail > 0 ? "[DisplayPower(powernet.avail)] in power network." : "The cable is not powered."]" // Rotating cables requires d1 and d2 to be rotated /obj/structure/cable/set_dir(new_dir) diff --git a/code/modules/reagents/Chemistry-Holder.dm b/code/modules/reagents/Chemistry-Holder.dm index 11f6d01cdb9..8598d541155 100644 --- a/code/modules/reagents/Chemistry-Holder.dm +++ b/code/modules/reagents/Chemistry-Holder.dm @@ -114,6 +114,10 @@ for(var/datum/reagent/current in reagent_list) if(current.id == id) + if(current.id == "blood") + if(!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) diff --git a/code/modules/reagents/Chemistry-Reagents.dm b/code/modules/reagents/Chemistry-Reagents.dm index a7239281c28..1f850098369 100644 --- a/code/modules/reagents/Chemistry-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents.dm @@ -22,7 +22,10 @@ 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 + + var/affects_dead = 0 // Does this chem process inside a corpse? + var/affects_robots = 0 // Does this chem process inside a Synth? + var/cup_icon_state = null var/cup_name = null var/cup_desc = null @@ -55,6 +58,8 @@ return if(!affects_dead && M.stat == DEAD) return + if(!affects_robots && M.isSynthetic()) + return if(!istype(location)) return @@ -79,28 +84,55 @@ if(ishuman(M)) var/mob/living/carbon/human/H = M - 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.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_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 + 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) diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm index cd011cc362e..b8f8732bf28 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm @@ -18,6 +18,7 @@ ..() if(data && data["blood_colour"]) color = data["blood_colour"] + return /datum/reagent/blood/get_data() // Just in case you have a reagent that handles data differently. @@ -49,6 +50,11 @@ H.adjust_nutrition(removed) is_vampire = 1 //VOREStation Edit END if(alien == IS_SLIME) // Treat it like nutriment for the jello, but not equivalent. + if(data["species"] == M.species.name) // Unless it's Promethean goo, then refill this one's goo. + M.inject_blood(src, volume * volume_mod) + remove_self(volume) + return + M.heal_organ_damage(0.2 * removed * volume_mod, 0) // More 'effective' blood means more usable material. M.adjust_nutrition(20 * removed * volume_mod) M.add_chemical_effect(CE_BLOODRESTORE, 4 * removed) @@ -91,6 +97,23 @@ if(alien == IS_SLIME) //They don't have blood, so it seems weird that they would instantly 'process' the chemical like another species does. affect_ingest(M, alien, removed) return + + if(M.isSynthetic()) + return + + if(ishuman(M)) + var/mob/living/carbon/human/H = M + + var/datum/reagent/blood/recipient = H.get_blood(H.vessel) + + if(recipient && blood_incompatible(data["blood_type"], recipient.data["blood_type"], data["species"], recipient.data["species"])) + H.inject_blood(src, removed * volume_mod) + + if(!H.isSynthetic() && data["species"] == "synthetic") // Remember not to inject oil into your veins, it's bad for you. + H.reagents.add_reagent("toxin", removed * 1.5) + + return + M.inject_blood(src, volume * volume_mod) remove_self(volume) diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm index 7743e184d53..15f846706b8 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm @@ -66,6 +66,10 @@ taste_description = "pennies" color = "#6E3B08" +/datum/reagent/copper/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed) + if(alien == IS_SKRELL) + M.add_chemical_effect(CE_BLOODRESTORE, 8 * removed) + /datum/reagent/ethanol name = "Ethanol" //Parent class for all alcoholic reagents. id = "ethanol" @@ -228,7 +232,7 @@ color = "#353535" /datum/reagent/iron/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed) - if(alien != IS_DIONA) + if(alien != IS_DIONA && alien != IS_SKRELL) M.add_chemical_effect(CE_BLOODRESTORE, 8 * removed) /datum/reagent/lithium diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm index 43a3bf269c7..b15c84e9a98 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm @@ -152,7 +152,7 @@ /datum/reagent/nutriment/triglyceride/oil/touch_turf(var/turf/simulated/T) if(!istype(T)) return - + var/hotspot = (locate(/obj/fire) in T) if(hotspot && !istype(T, /turf/space)) var/datum/gas_mixture/lowertemp = T.remove_air(T:air:total_moles) @@ -224,7 +224,7 @@ taste_description = "oil" taste_mult = 0.1 reagent_state = LIQUID - + /datum/reagent/nutriment/triglyceride/oil/peanut name = "Peanut Oil" id = "peanutoil" @@ -584,7 +584,7 @@ reagent_state = LIQUID color = "#365E30" overdose = REAGENTS_OVERDOSE - + //SYNNONO MEME FOODS EXPANSION - Credit to Synnono /datum/reagent/spacespice @@ -619,6 +619,28 @@ M.emote("shiver") holder.remove_reagent("capsaicin", 5) +/datum/reagent/frostoil/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed) // Eating frostoil now acts like capsaicin. Wee! + if(alien == IS_DIONA) + return + if(alien == IS_ALRAUNE) // VOREStation Edit: It wouldn't affect plants that much. + if(prob(5)) + to_chat(M, "You feel a chilly, tingling sensation in your mouth.") + M.bodytemperature -= rand(10, 25) + return + if(ishuman(M)) + var/mob/living/carbon/human/H = M + if(!H.can_feel_pain()) + return + var/effective_dose = (dose * M.species.spice_mod) + if((effective_dose < 5) && (dose == metabolism || prob(5))) + to_chat(M, "Your insides suddenly feel a spreading chill!") + if(effective_dose >= 5) + M.apply_effect(2 * M.species.spice_mod, AGONY, 0) + M.bodytemperature -= rand(1, 5) * M.species.spice_mod // Really fucks you up, cause it makes you cold. + if(prob(5)) + M.visible_message("[M] [pick("dry heaves!","coughs!","splutters!")]", pick("You feel like your insides are freezing!", "Your insides feel like they're turning to ice!")) + // holder.remove_reagent("capsaicin", 5) // VOREStation Edit: Nop, we don't instadelete spices for free. + /datum/reagent/frostoil/cryotoxin //A longer lasting version of frost oil. name = "Cryotoxin" id = "cryotoxin" @@ -654,14 +676,16 @@ var/mob/living/carbon/human/H = M if(!H.can_feel_pain()) return - - if(dose < 5 && (dose == metabolism || prob(5))) + + var/effective_dose = (dose * M.species.spice_mod) + if((effective_dose < 5) && (dose == metabolism || prob(5))) to_chat(M, "Your insides feel uncomfortably hot!") - if(dose >= 5) - M.apply_effect(2, AGONY, 0) + if(effective_dose >= 5) + M.apply_effect(2 * M.species.spice_mod, AGONY, 0) + M.bodytemperature += rand(1, 5) * M.species.spice_mod // Really fucks you up, cause it makes you overheat, too. if(prob(5)) - M.visible_message("[M] [pick("dry heaves!","coughs!","splutters!")]", "You feel like your insides are burning!") - holder.remove_reagent("frostoil", 5) + M.visible_message("[M] [pick("dry heaves!","coughs!","splutters!")]", pick("You feel like your insides are burning!", "You feel like your insides are on fire!", "You feel like your belly is full of lava!")) + // holder.remove_reagent("frostoil", 5) // VOREStation Edit: Nop, we don't instadelete spices for free. /datum/reagent/condensedcapsaicin name = "Condensed Capsaicin" @@ -805,7 +829,7 @@ M.apply_effect(4, AGONY, 0) if(prob(5)) M.visible_message("[M] [pick("dry heaves!","coughs!","splutters!")]", "You feel like your insides are burning!") - holder.remove_reagent("frostoil", 5) + // holder.remove_reagent("frostoil", 5) // VOREStation Edit: Nop, we don't instadelete spices for free. /* Drinks */ @@ -1218,6 +1242,32 @@ cup_name = "cup of berry tea" cup_desc = "A tasty mixture of berries and tea. It's apparently good for you!" +/datum/reagent/drink/greentea + name = "Green Tea" + id = "greentea" + description = "A subtle blend of green tea. It's apparently good for you!" + color = "#A8442C" + taste_description = "green tea" + + glass_name = "green tea" + glass_desc = "A subtle blend of green tea. It's apparently good for you!" + + cup_name = "cup of green tea" + cup_desc = "A subtle blend of green tea. It's apparently good for you!" + +/datum/reagent/drink/chaitea + name = "Chai Tea" + id = "chaitea" + description = "A tea spiced with cinnamon and cloves." + color = "#A8442C" + taste_description = "creamy cinnamon and spice" + + glass_name = "chai tea" + glass_desc = "A tea spiced with cinnamon and cloves." + + cup_name = "cup of chai tea" + cup_desc = "A tea spiced with cinnamon and cloves." + /datum/reagent/drink/coffee name = "Coffee" id = "coffee" @@ -1659,7 +1709,7 @@ glass_special = list(DRINK_FIZZ) /datum/reagent/drink/soda/lemon_lime - name = "Lemon Lime" + name = "Lemon-Lime" id = "lemon_lime" description = "A tangy substance made of 0.5% natural citrus!" taste_description = "tangy lime and lemon soda" @@ -1682,6 +1732,26 @@ glass_desc = "The original, refreshing not-actually-ale." glass_special = list(DRINK_FIZZ) +/datum/reagent/drink/root_beer + name = "R&D Root Beer" + id = "rootbeer" + color = "#211100" + adj_drowsy = -6 + taste_description = "sassafras and anise soda" + + glass_name = "glass of R&D Root Beer" + glass_desc = "A glass of bubbly R&D Root Beer." + +/datum/reagent/drink/dr_gibb_diet + name = "Diet Dr. Gibb" + id = "diet_dr_gibb" + color = "#102000" + taste_description = "watered down cherry soda" + + glass_name = "glass of Diet Dr. Gibb" + glass_desc = "Regular Dr.Gibb is probably healthier than this cocktail of artificial flavors." + glass_special = list(DRINK_FIZZ) + /datum/reagent/drink/shirley_temple name = "Shirley Temple" id = "shirley_temple" @@ -2049,6 +2119,7 @@ glass_icon = DRINK_ICON_NOISY glass_special = list(DRINK_FIZZ) + /* Alcohol */ // Basic @@ -2094,6 +2165,18 @@ return M.jitteriness = max(M.jitteriness - 3, 0) +/datum/reagent/ethanol/beer/lite + name = "Lite Beer" + id = "litebeer" + description = "An alcoholic beverage made from malted grains, hops, yeast, water, and water." + taste_description = "bad beer" + color = "#FFD300" + strength = 75 + nutriment_factor = 1 + + glass_name = "lite beer" + glass_desc = "A freezing pint of lite beer" + /datum/reagent/ethanol/bluecuracao name = "Blue Curacao" id = "bluecuracao" diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm index 681929691ae..ea23d01a0a6 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm @@ -1481,6 +1481,7 @@ color = "#555555" metabolism = REM * 4 // Nanomachines gotta go fast. scannable = 1 + affects_robots = TRUE /datum/reagent/healing_nanites/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) M.heal_organ_damage(2 * removed, 2 * removed) diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Modifiers.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Modifiers.dm index cd2e6767b4f..bed5da5f477 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Modifiers.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Modifiers.dm @@ -57,3 +57,14 @@ var/turf/simulated/S = T S.freeze_floor() return + +/datum/reagent/modapplying/vatstabilizer + name = "clone growth inhibitor" + id = "vatstabilizer" + description = "A compound produced by NanoTrasen using a secret blend of phoron and toxins to stop the rampant growth of a clone beyond intended states." + taste_description = "sour glue" + color = "#060501" + metabolism = REM * 0.2 + + modifier_to_add = /datum/modifier/clone_stabilizer + modifier_duration = 30 SECONDS diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Other.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Other.dm index ba7dc93d639..683e6be93a7 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Other.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Other.dm @@ -487,6 +487,24 @@ reagent_state = LIQUID color = "#C8A5DC" + affects_robots = TRUE + +/datum/reagent/coolant/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) + if(M.isSynthetic() && ishuman(M)) + var/mob/living/carbon/human/H = M + + var/datum/reagent/blood/coolant = H.get_blood(H.vessel) + + if(coolant) + H.vessel.add_reagent("blood", removed, coolant.data) + + else + H.vessel.add_reagent("blood", removed) + H.fixblood() + + else + ..() + /datum/reagent/ultraglue name = "Ultra Glue" id = "glue" @@ -524,6 +542,14 @@ reagent_state = LIQUID color = "#DF9FBF" +/datum/reagent/mineralfluid + name = "Mineral-Rich Fluid" + id = "mineralizedfluid" + description = "A warm, mineral-rich fluid." + taste_description = "salt" + reagent_state = LIQUID + color = "#ff205255" + // The opposite to healing nanites, exists to make unidentified hypos implied to have nanites not be 100% safe. /datum/reagent/defective_nanites name = "Defective Nanites" diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm index e18c2e56d9f..6b41160d7a3 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm @@ -120,6 +120,13 @@ spawn(rand(30, 60)) M.IgniteMob() +/datum/reagent/toxin/lead + name = "lead" + id = "lead" + description = "Elemental Lead." + color = "#273956" + strength = 4 + /datum/reagent/toxin/spidertoxin name = "Spidertoxin" id = "spidertoxin" @@ -1013,6 +1020,7 @@ datum/reagent/talum_quem/affect_blood(var/mob/living/carbon/M, var/alien, var/re reagent_state = SOLID color = "#555555" metabolism = REM * 4 // Nanomachines. Fast. + affects_robots = TRUE /datum/reagent/shredding_nanites/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) M.adjustBruteLoss(4 * removed) @@ -1026,6 +1034,7 @@ datum/reagent/talum_quem/affect_blood(var/mob/living/carbon/M, var/alien, var/re reagent_state = SOLID color = "#555555" metabolism = REM * 4 + affects_robots = TRUE /datum/reagent/irradiated_nanites/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) SSradiation.radiate(get_turf(M), 20) // Irradiate people around you. @@ -1040,6 +1049,7 @@ datum/reagent/talum_quem/affect_blood(var/mob/living/carbon/M, var/alien, var/re color = "#555555" metabolism = REM * 4 filtered_organs = list(O_SPLEEN) + affects_robots = TRUE /datum/reagent/neurophage_nanites/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) M.adjustBrainLoss(2 * removed) // Their job is to give you a bad time. diff --git a/code/modules/reagents/dispenser/cartridge_presets.dm b/code/modules/reagents/dispenser/cartridge_presets.dm index 3aee4cde7de..eea22fff7ea 100644 --- a/code/modules/reagents/dispenser/cartridge_presets.dm +++ b/code/modules/reagents/dispenser/cartridge_presets.dm @@ -73,6 +73,7 @@ cream spawn_reagent = "cream" mint spawn_reagent = "mint" berry spawn_reagent = "berryjuice" + greentea spawn_reagent = "greentea" decaf spawn_reagent = "decaf" // ERT diff --git a/code/modules/reagents/dispenser/dispenser_presets.dm b/code/modules/reagents/dispenser/dispenser_presets.dm index 9a774dee24e..69169030486 100644 --- a/code/modules/reagents/dispenser/dispenser_presets.dm +++ b/code/modules/reagents/dispenser/dispenser_presets.dm @@ -139,5 +139,6 @@ /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/hoses/connector.dm b/code/modules/reagents/hoses/connector.dm new file mode 100644 index 00000000000..bac7fc7c6af --- /dev/null +++ b/code/modules/reagents/hoses/connector.dm @@ -0,0 +1,138 @@ + +/obj/attackby(var/obj/item/O, var/mob/user) + . = ..() + + if(locate(/obj/item/hose_connector) in src) + if(O.is_wirecutter()) + var/list/available_sockets = list() + + for(var/obj/item/hose_connector/HC in src) + if(HC.my_hose) + available_sockets |= HC + + if(LAZYLEN(available_sockets)) + if(available_sockets.len == 1) + var/obj/item/hose_connector/AC = available_sockets[1] + var/choice = alert("Are you sure you want to disconnect [AC]?", "Confirm", "Yes", "No") + + if(choice == "Yes" && Adjacent(user)) + visible_message("[user] disconnects \the hose from \the [src].") + AC.my_hose.disconnect() + return + + else + + var/choice = input("Select a target hose connector.", "Socket Disconnect", null) as null|anything in available_sockets + + if(choice) + var/obj/item/hose_connector/AC = choice + var/confirm = alert("Are you sure you want to disconnect [AC]?", "Confirm", "Yes", "No") + + if(confirm == "Yes" && Adjacent(user)) + visible_message("[user] disconnects \the hose from \the [src].") + AC.my_hose.disconnect() + + return + +/obj/item/hose_connector + name = "hose connector" + desc = "A socket for a hose. It.. doesn't do anything on its own." + + var/obj/carrier = null + + var/flow_direction = HOSE_NEUTRAL + + var/datum/hose/my_hose = null + +/obj/item/hose_connector/Destroy() + if(my_hose) + my_hose.disconnect() + my_hose = null + if(carrier) + carrier = null + ..() + +/obj/item/hose_connector/Initialize() + ..() + + create_reagents(100) + + if(!istype(loc, /turf)) + name = "[flow_direction] hose connector ([loc])" + +/obj/item/hose_connector/proc/valid_connection(var/obj/item/hose_connector/C) + if(istype(C)) + if(C.my_hose) + return FALSE + + if(C.flow_direction in list(HOSE_INPUT, HOSE_OUTPUT) - flow_direction) + return TRUE + + return FALSE + +/obj/item/hose_connector/proc/disconnect() + my_hose = null + +/obj/item/hose_connector/proc/connect(var/datum/hose/H = null) + if(istype(H)) + my_hose = H + +/obj/item/hose_connector/proc/setup_hoses(var/obj/item/hose_connector/target) + if(target) + var/datum/hose/H = new() + + H.set_hose(src, target) + +/obj/item/hose_connector/proc/get_pairing() + if(my_hose) + return my_hose.get_pairing(src) + + return + +/* + * Subtypes + */ + +/obj/item/hose_connector/input + name = "hose input" + flow_direction = HOSE_INPUT + +/obj/item/hose_connector/input/active + name = "active hose" + +/obj/item/hose_connector/input/active/Destroy() + STOP_PROCESSING(SSobj, src) + ..() + +/obj/item/hose_connector/input/active/Initialize() + ..() + START_PROCESSING(SSobj, src) + + if(!isturf(loc)) + carrier = loc + +/obj/item/hose_connector/input/active/process() + if(carrier) + reagents.trans_to_obj(carrier, reagents.maximum_volume) + +/obj/item/hose_connector/output + name = "hose output" + flow_direction = HOSE_OUTPUT + +/obj/item/hose_connector/output/active + name = "active hose" + +/obj/item/hose_connector/output/active/Destroy() + STOP_PROCESSING(SSobj, src) + ..() + +/obj/item/hose_connector/output/active/Initialize() + ..() + START_PROCESSING(SSobj, src) + + if(!isturf(loc)) + carrier = loc + +/obj/item/hose_connector/output/active/process() + if(carrier) + carrier.reagents.trans_to_holder(reagents, reagents.maximum_volume) diff --git a/code/modules/reagents/hoses/hose.dm b/code/modules/reagents/hoses/hose.dm new file mode 100644 index 00000000000..dfe0eade792 --- /dev/null +++ b/code/modules/reagents/hoses/hose.dm @@ -0,0 +1,113 @@ + +GLOBAL_LIST_EMPTY(hoses) + +/obj/effect/ebeam/hose + plane = OBJ_PLANE + layer = STAIRS_LAYER + +/datum/hose + var/name = "hose" + + var/obj/item/hose_connector/node1 = null + var/obj/item/hose_connector/node2 = null + + var/hose_color = "#ffffff" + + var/initial_distance = 7 + + var/datum/beam/hose = null + +/datum/hose/proc/get_pairing(var/obj/item/hose_connector/target) + if(target) + if(target == node1) + return node2 + else if(target == node2) + return node1 + + return + +/datum/hose/proc/disconnect() + if(node1) + node1.disconnect() + node1 = null + if(node2) + node2.disconnect() + node2 = null + +/datum/hose/proc/set_hose(var/obj/item/hose_connector/target1, var/obj/item/hose_connector/target2) + if(target1 && target2) + node1 = target1 + node2 = target2 + + node1.connect(src) + node2.connect(src) + + name = "[name] ([node1],[node2])" + + initial_distance = get_dist(get_turf(node1), get_turf(node2)) + + GLOB.hoses |= src + START_PROCESSING(SSobj, src) + +/datum/hose/process() + if(node1 && node2) + if(get_dist(get_turf(node1), get_turf(node2)) > 0) + hose = node1.loc.Beam(node2.loc, icon_state = "hose", beam_color = hose_color, maxdistance = world.view, beam_type = /obj/effect/ebeam/hose) + + if(!hose || get_dist(get_turf(node1), get_turf(node2)) > initial_distance) // The hose didn't form. Something's fucky. + disconnect() + return + + var/datum/reagents/reagent_node1 = node1.reagents + var/datum/reagents/reagent_node2 = node2.reagents + + switch(node1.flow_direction) // Node 1 is the default 'master', interactions are considered in all current possible states in regards to it, however. + if(HOSE_INPUT) + if(node2.flow_direction == HOSE_NEUTRAL) // We're input, they're neutral. Take half of our volume. + reagent_node2.trans_to_holder(reagent_node1, reagent_node1.maximum_volume / 2) + else if(node2.flow_direction == HOSE_OUTPUT) // We're input, they're output. Take all of our volume. + reagent_node2.trans_to_holder(reagent_node1, reagent_node1.maximum_volume) + + if(HOSE_OUTPUT) // We're output, give all of their maximum volume. + reagent_node1.trans_to_holder(reagent_node2, reagent_node2.maximum_volume) + + if(HOSE_NEUTRAL) + switch(node2.flow_direction) + if(HOSE_INPUT) // We're neutral, they're input. Give them half of their volume. + reagent_node1.trans_to_holder(reagent_node2, reagent_node2.maximum_volume / 2) + + if(HOSE_NEUTRAL) // We're neutral, they're neutral. Balance our values. + var/volume_difference_perc = (reagent_node1.total_volume / reagent_node1.maximum_volume) - (reagent_node2.total_volume / reagent_node2.maximum_volume) + var/volume_difference = 0 + + var/pulling = FALSE + if(volume_difference_perc > 0) // They are smaller, so they determine the transfer amount. Half of the difference will equalize. + volume_difference = reagent_node2.maximum_volume * volume_difference_perc / 2 + + else if(volume_difference_perc < 0) // We're smaller, so we determine the transfer amount. Half of the difference will equalize. + volume_difference_perc *= -1 + + pulling = TRUE + + volume_difference = reagent_node1.maximum_volume * volume_difference_perc / 2 + + if(volume_difference) + if(pulling) + reagent_node2.trans_to_holder(reagent_node1, volume_difference) + else + reagent_node1.trans_to_holder(reagent_node2, volume_difference) + + if(HOSE_OUTPUT) + reagent_node2.trans_to_holder(reagent_node1, reagent_node2.maximum_volume) + + else + if(node1) + node1.disconnect() + node1 = null + if(node2) + node2.disconnect() + node2 = null + + STOP_PROCESSING(SSobj, src) + GLOB.hoses -= src + qdel(src) diff --git a/code/modules/reagents/hoses/hose_connector.dm b/code/modules/reagents/hoses/hose_connector.dm new file mode 100644 index 00000000000..332b780db9e --- /dev/null +++ b/code/modules/reagents/hoses/hose_connector.dm @@ -0,0 +1,93 @@ + +/obj/item/stack/hose + name = "plastic tubing" + singular_name = "plastic tube" + desc = "A non-reusable plastic tube for moving reagents to and fro. It looks flimsy." + + description_info = "This tubing may be used to join two hose sockets, if able.
\ + Clicking on an object with a connector, such as a water tank, will display a list of possible sockets.
\ + Neutral can link to all socket types, and Input/Output sockets can link to all but their own type.

\ + This hose does not stretch. The maximum distance you can move two objects from eachother\ + without snapping the tube is determined by distance upon connection." + + icon = 'icons/obj/machines/reagent.dmi' + icon_state = "hose" + origin_tech = list(TECH_MATERIAL = 2, TECH_ENGINEERING = 1) + amount = 1 + w_class = ITEMSIZE_SMALL + no_variants = TRUE + + var/obj/item/hose_connector/remembered = null + +/obj/item/stack/hose/Destroy() + remembered = null + ..() + +/obj/item/stack/hose/CtrlClick(mob/user) + if(remembered) + to_chat(user, "You wind \the [src] back up.") + remembered = null + return + +/obj/item/stack/hose/afterattack(var/atom/target, var/mob/living/user, proximity, params) + if(!proximity) + return + + var/list/available_sockets = list() + + for(var/obj/item/hose_connector/HC in target.contents) + if(!HC.my_hose) + if(remembered) + if(HC.flow_direction == HOSE_NEUTRAL || HC.flow_direction != remembered.flow_direction) + available_sockets |= HC + + else + available_sockets |= HC + + if(LAZYLEN(available_sockets)) + if(available_sockets.len == 1) + var/obj/item/hose_connector/AC = available_sockets[1] + if(remembered && remembered.valid_connection(AC)) + var/distancetonode = get_dist(remembered,AC) + if(distancetonode > world.view) + to_chat(user, "\The [src] would probably burst if it were this long.") + else if(distancetonode <= amount) + to_chat(user, "You join \the [remembered] to \the [AC]") + remembered.setup_hoses(AC) + use(distancetonode) + remembered = null + else + to_chat(user, "You do not have enough tubing to connect the sockets.") + + else + remembered = AC + to_chat(user, "You connect one end of tubing to \the [AC].") + + else + var/choice = input("Select a target hose connector.", "Socket Selection", null) as null|anything in available_sockets + + if(choice) + var/obj/item/hose_connector/CC = choice + if(remembered) + if(remembered.valid_connection(CC)) + var/distancetonode = get_dist(remembered, CC) + if(distancetonode > world.view) + to_chat(user, "\The [src] would probably burst if it were this long.") + else if(distancetonode <= amount) + to_chat(user, "You join \the [remembered] to \the [CC]") + + remembered.setup_hoses(CC) + use(distancetonode) + remembered = null + + else + to_chat(user, "You do not have enough tubing to connect the sockets.") + + else + remembered = CC + to_chat(user, "You connect one end of tubing to \the [CC].") + + return + + else + ..() diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm index 2a89067e8a0..a83c9615469 100644 --- a/code/modules/reagents/reagent_containers/spray.dm +++ b/code/modules/reagents/reagent_containers/spray.dm @@ -204,4 +204,97 @@ /obj/item/weapon/reagent_containers/spray/plantbgone/Initialize() . = ..() - reagents.add_reagent("plantbgone", 100) \ No newline at end of file + reagents.add_reagent("plantbgone", 100) + +/obj/item/weapon/reagent_containers/spray/chemsprayer/hosed + name = "hose nozzle" + desc = "A heavy spray nozzle that must be attached to a hose." + icon = 'icons/obj/janitor.dmi' + icon_state = "cleaner-industrial" + item_state = "cleaner" + center_of_mass = list("x" = 16,"y" = 10) + + possible_transfer_amounts = list(5,10,20) + + var/heavy_spray = FALSE + var/spray_particles = 3 + + var/icon/hose_overlay + + var/obj/item/hose_connector/input/active/InputSocket + +/obj/item/weapon/reagent_containers/spray/chemsprayer/hosed/Initialize() + ..() + + InputSocket = new(src) + +/obj/item/weapon/reagent_containers/spray/chemsprayer/hosed/update_icon() + ..() + + overlays.Cut() + + if(!hose_overlay) + hose_overlay = new icon(icon, "[icon_state]+hose") + + if(InputSocket.get_pairing()) + add_overlay(hose_overlay) + +/obj/item/weapon/reagent_containers/spray/chemsprayer/hosed/AltClick(mob/living/carbon/user) + if(++spray_particles > 3) spray_particles = 1 + + to_chat(user, "You turn the dial on \the [src] to [spray_particles].") + return + +/obj/item/weapon/reagent_containers/spray/chemsprayer/hosed/CtrlClick(var/mob/user) + if(loc != get_turf(src)) + heavy_spray = !heavy_spray + else + . = ..() + +/obj/item/weapon/reagent_containers/spray/chemsprayer/hosed/Spray_at(atom/A as mob|obj) + update_icon() + + var/direction = get_dir(src, A) + var/turf/T = get_turf(A) + var/turf/T1 = get_step(T,turn(direction, 90)) + var/turf/T2 = get_step(T,turn(direction, -90)) + var/list/the_targets = list(T, T1, T2) + + if(src.reagents.total_volume < 1) + to_chat(usr, "\The [src] is empty.") + return + + if(!heavy_spray) + for(var/a = 1 to 3) + spawn(0) + if(reagents.total_volume < 1) break + playsound(src, 'sound/effects/spray2.ogg', 50, 1, -6) + var/obj/effect/effect/water/chempuff/D = new/obj/effect/effect/water/chempuff(get_turf(src)) + var/turf/my_target = the_targets[a] + D.create_reagents(amount_per_transfer_from_this) + if(!src) + return + reagents.trans_to_obj(D, amount_per_transfer_from_this) + D.set_color() + D.set_up(my_target, rand(6, 8), 2) + return + + else + playsound(src, 'sound/effects/extinguish.ogg', 75, 1, -3) + + for(var/a = 1 to spray_particles) + spawn(0) + if(!src || !reagents.total_volume) return + + var/obj/effect/effect/water/W = new /obj/effect/effect/water(get_turf(src)) + var/turf/my_target + if(a <= the_targets.len) + my_target = the_targets[a] + else + my_target = pick(the_targets) + W.create_reagents(amount_per_transfer_from_this) + reagents.trans_to_obj(W, amount_per_transfer_from_this) + W.set_color() + W.set_up(my_target) + + return diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm index 742f89734c5..bf9c53840a4 100644 --- a/code/modules/reagents/reagent_dispenser.dm +++ b/code/modules/reagents/reagent_dispenser.dm @@ -10,18 +10,33 @@ 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) - attackby(obj/item/weapon/W as obj, mob/user as mob) +/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) diff --git a/code/modules/recycling/disposal.dm b/code/modules/recycling/disposal.dm index 3437c8b5827..1d46e16ce52 100644 --- a/code/modules/recycling/disposal.dm +++ b/code/modules/recycling/disposal.dm @@ -1210,7 +1210,7 @@ New() . = ..() dpdir = dir | turn(dir, 180) - if(sort_tag) tagger_locations |= sort_tag + if(sort_tag) GLOB.tagger_locations |= sort_tag updatename() updatedesc() update() @@ -1276,7 +1276,7 @@ New() . = ..() - if(sortType) tagger_locations |= sortType + if(sortType) GLOB.tagger_locations |= sortType updatedir() updatename() diff --git a/code/modules/recycling/sortingmachinery.dm b/code/modules/recycling/sortingmachinery.dm index 315b492e6b7..a97c2894c29 100755 --- a/code/modules/recycling/sortingmachinery.dm +++ b/code/modules/recycling/sortingmachinery.dm @@ -14,100 +14,100 @@ var/label_x var/tag_x - attack_hand(mob/user as mob) - unwrap() +/obj/structure/bigDelivery/attack_hand(mob/user as mob) + unwrap() - proc/unwrap() - playsound(src, 'sound/items/package_unwrap.ogg', 50, 1) - // Destroy will drop our wrapped object on the turf, so let it. - qdel(src) +/obj/structure/bigDelivery/proc/unwrap() + playsound(src, 'sound/items/package_unwrap.ogg', 50, 1) + // Destroy will drop our wrapped object on the turf, so let it. + qdel(src) - attackby(obj/item/W as obj, mob/user as mob) - if(istype(W, /obj/item/device/destTagger)) - var/obj/item/device/destTagger/O = W - if(O.currTag) - if(src.sortTag != O.currTag) - to_chat(user, "You have labeled the destination as [O.currTag].") - if(!src.sortTag) - src.sortTag = O.currTag - update_icon() - else - src.sortTag = O.currTag - playsound(src, 'sound/machines/twobeep.ogg', 50, 1) +/obj/structure/bigDelivery/attackby(obj/item/W as obj, mob/user as mob) + if(istype(W, /obj/item/device/destTagger)) + var/obj/item/device/destTagger/O = W + if(O.currTag) + if(src.sortTag != O.currTag) + to_chat(user, "You have labeled the destination as [O.currTag].") + if(!src.sortTag) + src.sortTag = O.currTag + update_icon() else - to_chat(user, "The package is already labeled for [O.currTag].") + src.sortTag = O.currTag + playsound(src, 'sound/machines/twobeep.ogg', 50, 1) else - to_chat(user, "You need to set a destination first!") + to_chat(user, "The package is already labeled for [O.currTag].") + else + to_chat(user, "You need to set a destination first!") - else if(istype(W, /obj/item/weapon/pen)) - switch(alert("What would you like to alter?",,"Title","Description", "Cancel")) - if("Title") - var/str = sanitizeSafe(input(usr,"Label text?","Set label",""), MAX_NAME_LEN) - if(!str || !length(str)) - to_chat(user, " Invalid text.") - return - user.visible_message("\The [user] titles \the [src] with \a [W], marking down: \"[str]\"",\ - "You title \the [src]: \"[str]\"",\ - "You hear someone scribbling a note.") - playsound(src, pick('sound/bureaucracy/pen1.ogg','sound/bureaucracy/pen2.ogg'), 20) - name = "[name] ([str])" - if(!examtext && !nameset) - nameset = 1 - update_icon() - else - nameset = 1 - if("Description") - var/str = sanitize(input(usr,"Label text?","Set label","")) - if(!str || !length(str)) - to_chat(user, "Invalid text.") - return - if(!examtext && !nameset) - examtext = str - update_icon() - else - examtext = str - user.visible_message("\The [user] labels \the [src] with \a [W], scribbling down: \"[examtext]\"",\ - "You label \the [src]: \"[examtext]\"",\ - "You hear someone scribbling a note.") - playsound(src, pick('sound/bureaucracy/pen1.ogg','sound/bureaucracy/pen2.ogg'), 20) - return + else if(istype(W, /obj/item/weapon/pen)) + switch(alert("What would you like to alter?",,"Title","Description", "Cancel")) + if("Title") + var/str = sanitizeSafe(input(usr,"Label text?","Set label",""), MAX_NAME_LEN) + if(!str || !length(str)) + to_chat(user, " Invalid text.") + return + user.visible_message("\The [user] titles \the [src] with \a [W], marking down: \"[str]\"",\ + "You title \the [src]: \"[str]\"",\ + "You hear someone scribbling a note.") + playsound(src, pick('sound/bureaucracy/pen1.ogg','sound/bureaucracy/pen2.ogg'), 20) + name = "[name] ([str])" + if(!examtext && !nameset) + nameset = 1 + update_icon() + else + nameset = 1 + if("Description") + var/str = sanitize(input(usr,"Label text?","Set label","")) + if(!str || !length(str)) + to_chat(user, "Invalid text.") + return + if(!examtext && !nameset) + examtext = str + update_icon() + else + examtext = str + user.visible_message("\The [user] labels \the [src] with \a [W], scribbling down: \"[examtext]\"",\ + "You label \the [src]: \"[examtext]\"",\ + "You hear someone scribbling a note.") + playsound(src, pick('sound/bureaucracy/pen1.ogg','sound/bureaucracy/pen2.ogg'), 20) + return - update_icon() - overlays = new() - if(nameset || examtext) - var/image/I = new/image('icons/obj/storage.dmi',"delivery_label") - if(icon_state == "deliverycloset") - I.pixel_x = 2 - if(label_y == null) - label_y = rand(-6, 11) - I.pixel_y = label_y - else if(icon_state == "deliverycrate") - if(label_x == null) - label_x = rand(-8, 6) - I.pixel_x = label_x - I.pixel_y = -3 - overlays += I - if(src.sortTag) - var/image/I = new/image('icons/obj/storage.dmi',"delivery_tag") - if(icon_state == "deliverycloset") - if(tag_x == null) - tag_x = rand(-2, 3) - I.pixel_x = tag_x - I.pixel_y = 9 - else if(icon_state == "deliverycrate") - if(tag_x == null) - tag_x = rand(-8, 6) - I.pixel_x = tag_x - I.pixel_y = -3 - overlays += I +/obj/structure/bigDelivery/update_icon() + overlays = new() + if(nameset || examtext) + var/image/I = new/image('icons/obj/storage.dmi',"delivery_label") + if(icon_state == "deliverycloset") + I.pixel_x = 2 + if(label_y == null) + label_y = rand(-6, 11) + I.pixel_y = label_y + else if(icon_state == "deliverycrate") + if(label_x == null) + label_x = rand(-8, 6) + I.pixel_x = label_x + I.pixel_y = -3 + overlays += I + if(src.sortTag) + var/image/I = new/image('icons/obj/storage.dmi',"delivery_tag") + if(icon_state == "deliverycloset") + if(tag_x == null) + tag_x = rand(-2, 3) + I.pixel_x = tag_x + I.pixel_y = 9 + else if(icon_state == "deliverycrate") + if(tag_x == null) + tag_x = rand(-8, 6) + I.pixel_x = tag_x + I.pixel_y = -3 + overlays += I - examine(mob/user) - . = ..() - if(get_dist(user, src) <= 4) - if(sortTag) - . += "It is labeled \"[sortTag]\"" - if(examtext) - . += "It has a note attached which reads, \"[examtext]\"" +/obj/structure/bigDelivery/examine(mob/user) + . = ..() + if(get_dist(user, src) <= 4) + if(sortTag) + . += "It is labeled \"[sortTag]\"" + if(examtext) + . += "It has a note attached which reads, \"[examtext]\"" /obj/item/smallDelivery desc = "A small wrapped package." @@ -121,100 +121,100 @@ var/nameset = 0 var/tag_x - attack_self(mob/user as mob) - if (src.wrapped) //sometimes items can disappear. For example, bombs. --rastaf0 - wrapped.loc = user.loc - if(ishuman(user)) - user.put_in_hands(wrapped) - else - wrapped.loc = get_turf(src) +/obj/item/smallDelivery/attack_self(mob/user as mob) + if (src.wrapped) //sometimes items can disappear. For example, bombs. --rastaf0 + wrapped.loc = user.loc + if(ishuman(user)) + user.put_in_hands(wrapped) + else + wrapped.loc = get_turf(src) - qdel(src) - return + qdel(src) + return - attackby(obj/item/W as obj, mob/user as mob) - if(istype(W, /obj/item/device/destTagger)) - var/obj/item/device/destTagger/O = W - if(O.currTag) - if(src.sortTag != O.currTag) - to_chat(user, "You have labeled the destination as [O.currTag].") - if(!src.sortTag) - src.sortTag = O.currTag - update_icon() - else - src.sortTag = O.currTag - playsound(src, 'sound/machines/twobeep.ogg', 50, 1) +/obj/item/smallDelivery/attackby(obj/item/W as obj, mob/user as mob) + if(istype(W, /obj/item/device/destTagger)) + var/obj/item/device/destTagger/O = W + if(O.currTag) + if(src.sortTag != O.currTag) + to_chat(user, "You have labeled the destination as [O.currTag].") + if(!src.sortTag) + src.sortTag = O.currTag + update_icon() else - to_chat(user, "The package is already labeled for [O.currTag].") + src.sortTag = O.currTag + playsound(src, 'sound/machines/twobeep.ogg', 50, 1) else - to_chat(user, "You need to set a destination first!") + to_chat(user, "The package is already labeled for [O.currTag].") + else + to_chat(user, "You need to set a destination first!") - else if(istype(W, /obj/item/weapon/pen)) - switch(alert("What would you like to alter?",,"Title","Description", "Cancel")) - if("Title") - var/str = sanitizeSafe(input(usr,"Label text?","Set label",""), MAX_NAME_LEN) - if(!str || !length(str)) - to_chat(user, " Invalid text.") - return - user.visible_message("\The [user] titles \the [src] with \a [W], marking down: \"[str]\"",\ - "You title \the [src]: \"[str]\"",\ - "You hear someone scribbling a note.") - playsound(src, pick('sound/bureaucracy/pen1.ogg','sound/bureaucracy/pen2.ogg'), 20) - name = "[name] ([str])" - if(!examtext && !nameset) - nameset = 1 - update_icon() - else - nameset = 1 + else if(istype(W, /obj/item/weapon/pen)) + switch(alert("What would you like to alter?",,"Title","Description", "Cancel")) + if("Title") + var/str = sanitizeSafe(input(usr,"Label text?","Set label",""), MAX_NAME_LEN) + if(!str || !length(str)) + to_chat(user, " Invalid text.") + return + user.visible_message("\The [user] titles \the [src] with \a [W], marking down: \"[str]\"",\ + "You title \the [src]: \"[str]\"",\ + "You hear someone scribbling a note.") + playsound(src, pick('sound/bureaucracy/pen1.ogg','sound/bureaucracy/pen2.ogg'), 20) + name = "[name] ([str])" + if(!examtext && !nameset) + nameset = 1 + update_icon() + else + nameset = 1 - if("Description") - var/str = sanitize(input(usr,"Label text?","Set label","")) - if(!str || !length(str)) - to_chat(user, "Invalid text.") - return - if(!examtext && !nameset) - examtext = str - update_icon() - else - examtext = str - user.visible_message("\The [user] labels \the [src] with \a [W], scribbling down: \"[examtext]\"",\ - "You label \the [src]: \"[examtext]\"",\ - "You hear someone scribbling a note.") - playsound(src, pick('sound/bureaucracy/pen1.ogg','sound/bureaucracy/pen2.ogg'), 20) - return + if("Description") + var/str = sanitize(input(usr,"Label text?","Set label","")) + if(!str || !length(str)) + to_chat(user, "Invalid text.") + return + if(!examtext && !nameset) + examtext = str + update_icon() + else + examtext = str + user.visible_message("\The [user] labels \the [src] with \a [W], scribbling down: \"[examtext]\"",\ + "You label \the [src]: \"[examtext]\"",\ + "You hear someone scribbling a note.") + playsound(src, pick('sound/bureaucracy/pen1.ogg','sound/bureaucracy/pen2.ogg'), 20) + return - update_icon() - overlays = new() - if((nameset || examtext) && icon_state != "deliverycrate1") - var/image/I = new/image('icons/obj/storage.dmi',"delivery_label") - if(icon_state == "deliverycrate5") - I.pixel_y = -1 - overlays += I - if(src.sortTag) - var/image/I = new/image('icons/obj/storage.dmi',"delivery_tag") - switch(icon_state) - if("deliverycrate1") - I.pixel_y = -5 - if("deliverycrate2") - I.pixel_y = -2 - if("deliverycrate3") - I.pixel_y = 0 - if("deliverycrate4") - if(tag_x == null) - tag_x = rand(0,5) - I.pixel_x = tag_x - I.pixel_y = 3 - if("deliverycrate5") - I.pixel_y = -3 - overlays += I +/obj/item/smallDelivery/update_icon() + overlays = new() + if((nameset || examtext) && icon_state != "deliverycrate1") + var/image/I = new/image('icons/obj/storage.dmi',"delivery_label") + if(icon_state == "deliverycrate5") + I.pixel_y = -1 + overlays += I + if(src.sortTag) + var/image/I = new/image('icons/obj/storage.dmi',"delivery_tag") + switch(icon_state) + if("deliverycrate1") + I.pixel_y = -5 + if("deliverycrate2") + I.pixel_y = -2 + if("deliverycrate3") + I.pixel_y = 0 + if("deliverycrate4") + if(tag_x == null) + tag_x = rand(0,5) + I.pixel_x = tag_x + I.pixel_y = 3 + if("deliverycrate5") + I.pixel_y = -3 + overlays += I - examine(mob/user) - . = ..() - if(get_dist(user, src) <= 4) - if(sortTag) - . += "It is labeled \"[sortTag]\"" - if(examtext) - . += "It has a note attached which reads, \"[examtext]\"" +/obj/item/smallDelivery/examine(mob/user) + . = ..() + if(get_dist(user, src) <= 4) + if(sortTag) + . += "It is labeled \"[sortTag]\"" + if(examtext) + . += "It has a note attached which reads, \"[examtext]\"" /obj/item/weapon/packageWrap name = "package wrapper" @@ -226,95 +226,95 @@ drop_sound = 'sound/items/drop/wrapper.ogg' - afterattack(var/obj/target as obj, mob/user as mob, proximity) - if(!proximity) return - if(!istype(target)) //this really shouldn't be necessary (but it is). -Pete - return - if(istype(target, /obj/item/smallDelivery) || istype(target,/obj/structure/bigDelivery) \ - || istype(target, /obj/item/weapon/gift) || istype(target, /obj/item/weapon/evidencebag)) - return - if(target.anchored) - return - if(target in user) - return - if(user in target) //no wrapping closets that you are inside - it's not physically possible - return - - user.attack_log += text("\[[time_stamp()]\] Has used [src.name] on \ref[target]") - - - if (istype(target, /obj/item) && !(istype(target, /obj/item/weapon/storage) && !istype(target,/obj/item/weapon/storage/box))) - var/obj/item/O = target - if (src.amount > 1) - var/obj/item/smallDelivery/P = new /obj/item/smallDelivery(get_turf(O.loc)) //Aaannd wrap it up! - if(!istype(O.loc, /turf)) - if(user.client) - user.client.screen -= O - P.wrapped = O - O.forceMove(P) - P.w_class = O.w_class - var/i = round(O.w_class) - if(i in list(1,2,3,4,5)) - P.icon_state = "deliverycrate[i]" - switch(i) - if(1) P.name = "tiny parcel" - if(3) P.name = "normal-sized parcel" - if(4) P.name = "large parcel" - if(5) P.name = "huge parcel" - if(i < 1) - P.icon_state = "deliverycrate1" - P.name = "tiny parcel" - if(i > 5) - P.icon_state = "deliverycrate5" - P.name = "huge parcel" - P.add_fingerprint(usr) - O.add_fingerprint(usr) - src.add_fingerprint(usr) - src.amount -= 1 - user.visible_message("\The [user] wraps \a [target] with \a [src].",\ - "You wrap \the [target], leaving [amount] units of paper on \the [src].",\ - "You hear someone taping paper around a small object.") - playsound(src, 'sound/items/package_wrap.ogg', 50, 1) - else if (istype(target, /obj/structure/closet/crate)) - var/obj/structure/closet/crate/O = target - if (src.amount > 3 && !O.opened) - var/obj/structure/bigDelivery/P = new /obj/structure/bigDelivery(get_turf(O.loc)) - P.icon_state = "deliverycrate" - P.wrapped = O - O.loc = P - src.amount -= 3 - user.visible_message("\The [user] wraps \a [target] with \a [src].",\ - "You wrap \the [target], leaving [amount] units of paper on \the [src].",\ - "You hear someone taping paper around a large object.") - playsound(src, 'sound/items/package_wrap.ogg', 50, 1) - else if(src.amount < 3) - to_chat(user, "You need more paper.") - else if (istype (target, /obj/structure/closet)) - var/obj/structure/closet/O = target - if (src.amount > 3 && !O.opened) - var/obj/structure/bigDelivery/P = new /obj/structure/bigDelivery(get_turf(O.loc)) - P.wrapped = O - O.sealed = 1 - O.loc = P - src.amount -= 3 - user.visible_message("\The [user] wraps \a [target] with \a [src].",\ - "You wrap \the [target], leaving [amount] units of paper on \the [src].",\ - "You hear someone taping paper around a large object.") - playsound(src, 'sound/items/package_wrap.ogg', 50, 1) - else if(src.amount < 3) - to_chat(user, "You need more paper.") - else - to_chat(user, "The object you are trying to wrap is unsuitable for the sorting machinery!") - if (src.amount <= 0) - new /obj/item/weapon/c_tube( src.loc ) - qdel(src) - return +/obj/item/weapon/packageWrap/afterattack(var/obj/target as obj, mob/user as mob, proximity) + if(!proximity) return + if(!istype(target)) //this really shouldn't be necessary (but it is). -Pete + return + if(istype(target, /obj/item/smallDelivery) || istype(target,/obj/structure/bigDelivery) \ + || istype(target, /obj/item/weapon/gift) || istype(target, /obj/item/weapon/evidencebag)) + return + if(target.anchored) + return + if(target in user) + return + if(user in target) //no wrapping closets that you are inside - it's not physically possible return - examine(mob/user) - . = ..() - if(get_dist(user, src) <= 0) - . += "There are [amount] units of package wrap left!" + user.attack_log += text("\[[time_stamp()]\] Has used [src.name] on \ref[target]") + + + if (istype(target, /obj/item) && !(istype(target, /obj/item/weapon/storage) && !istype(target,/obj/item/weapon/storage/box))) + var/obj/item/O = target + if (src.amount > 1) + var/obj/item/smallDelivery/P = new /obj/item/smallDelivery(get_turf(O.loc)) //Aaannd wrap it up! + if(!istype(O.loc, /turf)) + if(user.client) + user.client.screen -= O + P.wrapped = O + O.forceMove(P) + P.w_class = O.w_class + var/i = round(O.w_class) + if(i in list(1,2,3,4,5)) + P.icon_state = "deliverycrate[i]" + switch(i) + if(1) P.name = "tiny parcel" + if(3) P.name = "normal-sized parcel" + if(4) P.name = "large parcel" + if(5) P.name = "huge parcel" + if(i < 1) + P.icon_state = "deliverycrate1" + P.name = "tiny parcel" + if(i > 5) + P.icon_state = "deliverycrate5" + P.name = "huge parcel" + P.add_fingerprint(usr) + O.add_fingerprint(usr) + src.add_fingerprint(usr) + src.amount -= 1 + user.visible_message("\The [user] wraps \a [target] with \a [src].",\ + "You wrap \the [target], leaving [amount] units of paper on \the [src].",\ + "You hear someone taping paper around a small object.") + playsound(src, 'sound/items/package_wrap.ogg', 50, 1) + else if (istype(target, /obj/structure/closet/crate)) + var/obj/structure/closet/crate/O = target + if (src.amount > 3 && !O.opened) + var/obj/structure/bigDelivery/P = new /obj/structure/bigDelivery(get_turf(O.loc)) + P.icon_state = "deliverycrate" + P.wrapped = O + O.loc = P + src.amount -= 3 + user.visible_message("\The [user] wraps \a [target] with \a [src].",\ + "You wrap \the [target], leaving [amount] units of paper on \the [src].",\ + "You hear someone taping paper around a large object.") + playsound(src, 'sound/items/package_wrap.ogg', 50, 1) + else if(src.amount < 3) + to_chat(user, "You need more paper.") + else if (istype (target, /obj/structure/closet)) + var/obj/structure/closet/O = target + if (src.amount > 3 && !O.opened) + var/obj/structure/bigDelivery/P = new /obj/structure/bigDelivery(get_turf(O.loc)) + P.wrapped = O + O.sealed = 1 + O.loc = P + src.amount -= 3 + user.visible_message("\The [user] wraps \a [target] with \a [src].",\ + "You wrap \the [target], leaving [amount] units of paper on \the [src].",\ + "You hear someone taping paper around a large object.") + playsound(src, 'sound/items/package_wrap.ogg', 50, 1) + else if(src.amount < 3) + to_chat(user, "You need more paper.") + else + to_chat(user, "The object you are trying to wrap is unsuitable for the sorting machinery!") + if (src.amount <= 0) + new /obj/item/weapon/c_tube( src.loc ) + qdel(src) + return + return + +/obj/item/weapon/packageWrap/examine(mob/user) + . = ..() + if(get_dist(user, src) <= 0) + . += "There are [amount] units of package wrap left!" /obj/structure/bigDelivery/Destroy() if(wrapped) //sometimes items can disappear. For example, bombs. --rastaf0 @@ -338,30 +338,34 @@ item_state = "electronic" slot_flags = SLOT_BELT - proc/openwindow(mob/user as mob) - var/dat = "

TagMaster 2.3

" +/obj/item/device/destTagger/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "DestinationTagger", name) + ui.open() - dat += "
[thing]") - if(istype(thing, /obj/item/weapon/paper)) - LAZYADD(dat, "ReadWrite") - else if(istype(thing, /obj/item/weapon/photo)) - LAZYADD(dat, "Look") - LAZYADD(dat, "Remove
" - for(var/i = 1, i <= tagger_locations.len, i++) - dat += "" +/obj/item/device/destTagger/tgui_data(mob/user, datum/tgui/ui) + var/list/data = ..() - if (i%4==0) - dat += "" + data["currTag"] = currTag + data["taggerLocs"] = GLOB.tagger_locations - dat += "
[tagger_locations[i]]

Current Selection: [currTag ? currTag : "None"]
" + return data - user << browse(dat, "window=destTagScreen;size=450x350") - onclose(user, "destTagScreen") +/obj/item/device/destTagger/attack_self(mob/user as mob) + tgui_interact(user) - attack_self(mob/user as mob) - openwindow(user) - return - - Topic(href, href_list) - src.add_fingerprint(usr) - if(href_list["nextTag"] && href_list["nextTag"] in tagger_locations) - src.currTag = href_list["nextTag"] - openwindow(usr) +/obj/item/device/destTagger/tgui_act(action, params) + if(..()) + return TRUE + add_fingerprint(usr) + switch(action) + if("set_tag") + var/new_tag = params["tag"] + if(!(new_tag in GLOB.tagger_locations)) + return FALSE + currTag = new_tag + . = TRUE /obj/machinery/disposal/deliveryChute name = "Delivery chute" @@ -371,94 +375,94 @@ var/c_mode = 0 - New() - ..() - spawn(5) - trunk = locate() in src.loc - if(trunk) - trunk.linked = src // link the pipe trunk to self +/obj/machinery/disposal/deliveryChute/New() + ..() + spawn(5) + trunk = locate() in src.loc + if(trunk) + trunk.linked = src // link the pipe trunk to self - interact() - return +/obj/machinery/disposal/deliveryChute/interact() + return +/obj/machinery/disposal/deliveryChute/update() + return + +/obj/machinery/disposal/deliveryChute/Bumped(var/atom/movable/AM) //Go straight into the chute + if(istype(AM, /obj/item/projectile) || istype(AM, /obj/effect) || istype(AM, /obj/mecha)) return + switch(dir) + if(NORTH) + if(AM.loc.y != src.loc.y+1) return + if(EAST) + if(AM.loc.x != src.loc.x+1) return + if(SOUTH) + if(AM.loc.y != src.loc.y-1) return + if(WEST) + if(AM.loc.x != src.loc.x-1) return + + if(istype(AM, /obj)) + var/obj/O = AM + O.loc = src + else if(istype(AM, /mob)) + var/mob/M = AM + M.loc = src + src.flush() + +/obj/machinery/disposal/deliveryChute/flush() + flushing = 1 + flick("intake-closing", src) + var/obj/structure/disposalholder/H = new() // virtual holder object which actually + // travels through the pipes. + air_contents = new() // new empty gas resv. + + sleep(10) + playsound(src, 'sound/machines/disposalflush.ogg', 50, 0, 0) + sleep(5) // wait for animation to finish + + H.init(src) // copy the contents of disposer to holder + + H.start(src) // start the holder processing movement + flushing = 0 + // now reset disposal state + flush = 0 + if(mode == 2) // if was ready, + mode = 1 // switch to charging update() + return + +/obj/machinery/disposal/deliveryChute/attackby(var/obj/item/I, var/mob/user) + if(!I || !user) return - Bumped(var/atom/movable/AM) //Go straight into the chute - if(istype(AM, /obj/item/projectile) || istype(AM, /obj/effect) || istype(AM, /obj/mecha)) return - switch(dir) - if(NORTH) - if(AM.loc.y != src.loc.y+1) return - if(EAST) - if(AM.loc.x != src.loc.x+1) return - if(SOUTH) - if(AM.loc.y != src.loc.y-1) return - if(WEST) - if(AM.loc.x != src.loc.x-1) return - - if(istype(AM, /obj)) - var/obj/O = AM - O.loc = src - else if(istype(AM, /mob)) - var/mob/M = AM - M.loc = src - src.flush() - - flush() - flushing = 1 - flick("intake-closing", src) - var/obj/structure/disposalholder/H = new() // virtual holder object which actually - // travels through the pipes. - air_contents = new() // new empty gas resv. - - sleep(10) - playsound(src, 'sound/machines/disposalflush.ogg', 50, 0, 0) - sleep(5) // wait for animation to finish - - H.init(src) // copy the contents of disposer to holder - - H.start(src) // start the holder processing movement - flushing = 0 - // now reset disposal state - flush = 0 - if(mode == 2) // if was ready, - mode = 1 // switch to charging - update() - return - - attackby(var/obj/item/I, var/mob/user) - if(!I || !user) + if(I.is_screwdriver()) + if(c_mode==0) + c_mode=1 + playsound(src, I.usesound, 50, 1) + to_chat(user, "You remove the screws around the power connection.") + return + else if(c_mode==1) + c_mode=0 + playsound(src, I.usesound, 50, 1) + to_chat(user, "You attach the screws around the power connection.") + return + else if(istype(I, /obj/item/weapon/weldingtool) && c_mode==1) + var/obj/item/weapon/weldingtool/W = I + if(W.remove_fuel(0,user)) + playsound(src, W.usesound, 50, 1) + to_chat(user, "You start slicing the floorweld off the delivery chute.") + if(do_after(user,20 * W.toolspeed)) + if(!src || !W.isOn()) return + to_chat(user, "You sliced the floorweld off the delivery chute.") + var/obj/structure/disposalconstruct/C = new (src.loc) + C.ptype = 8 // 8 = Delivery chute + C.update() + C.anchored = 1 + C.density = 1 + qdel(src) + return + else + to_chat(user, "You need more welding fuel to complete this task.") return - - if(I.is_screwdriver()) - if(c_mode==0) - c_mode=1 - playsound(src, I.usesound, 50, 1) - to_chat(user, "You remove the screws around the power connection.") - return - else if(c_mode==1) - c_mode=0 - playsound(src, I.usesound, 50, 1) - to_chat(user, "You attach the screws around the power connection.") - return - else if(istype(I, /obj/item/weapon/weldingtool) && c_mode==1) - var/obj/item/weapon/weldingtool/W = I - if(W.remove_fuel(0,user)) - playsound(src, W.usesound, 50, 1) - to_chat(user, "You start slicing the floorweld off the delivery chute.") - if(do_after(user,20 * W.toolspeed)) - if(!src || !W.isOn()) return - to_chat(user, "You sliced the floorweld off the delivery chute.") - var/obj/structure/disposalconstruct/C = new (src.loc) - C.ptype = 8 // 8 = Delivery chute - C.update() - C.anchored = 1 - C.density = 1 - qdel(src) - return - else - to_chat(user, "You need more welding fuel to complete this task.") - return /obj/machinery/disposal/deliveryChute/Destroy() if(trunk) diff --git a/code/modules/research/designs/circuits/circuits.dm b/code/modules/research/designs/circuits/circuits.dm index 425223ffe7a..008d1f486b5 100644 --- a/code/modules/research/designs/circuits/circuits.dm +++ b/code/modules/research/designs/circuits/circuits.dm @@ -494,7 +494,7 @@ CIRCUITS BELOW id = "durand_main" req_tech = list(TECH_DATA = 4) materials = list("glass" = 2000, MAT_GRAPHITE = 1250) - chemicals = list("pacid" = 20) + chemicals = list("sacid" = 20) build_path = /obj/item/weapon/circuitboard/mecha/durand/main sort_string = "NAADA" @@ -503,7 +503,7 @@ CIRCUITS BELOW id = "durand_peri" req_tech = list(TECH_DATA = 4) materials = list("glass" = 2000, MAT_GRAPHITE = 1250) - chemicals = list("pacid" = 20) + chemicals = list("sacid" = 20) build_path = /obj/item/weapon/circuitboard/mecha/durand/peripherals sort_string = "NAADB" @@ -512,7 +512,7 @@ CIRCUITS BELOW id = "durand_targ" req_tech = list(TECH_DATA = 4, TECH_COMBAT = 2) materials = list("glass" = 2000, MAT_GRAPHITE = 1250) - chemicals = list("pacid" = 20) + chemicals = list("sacid" = 20) build_path = /obj/item/weapon/circuitboard/mecha/durand/targeting sort_string = "NAADC" diff --git a/code/modules/research/mechfab_designs.dm b/code/modules/research/mechfab_designs.dm index a5031055c34..8e7f31b7319 100644 --- a/code/modules/research/mechfab_designs.dm +++ b/code/modules/research/mechfab_designs.dm @@ -184,49 +184,49 @@ name = "Durand Torso" id = "durand_torso" build_path = /obj/item/mecha_parts/part/durand_torso - time = 60 + time = 30 materials = list(DEFAULT_WALL_MATERIAL = 41250, MAT_PLASTEEL = 15000, "silver" = 7500) /datum/design/item/mechfab/durand/head name = "Durand Head" id = "durand_head" build_path = /obj/item/mecha_parts/part/durand_head - time = 40 + time = 20 materials = list(DEFAULT_WALL_MATERIAL = 18750, "glass" = 7500, "silver" = 2250) /datum/design/item/mechfab/durand/left_arm name = "Durand Left Arm" id = "durand_left_arm" build_path = /obj/item/mecha_parts/part/durand_left_arm - time = 40 + time = 20 materials = list(DEFAULT_WALL_MATERIAL = 26250, "silver" = 2250) /datum/design/item/mechfab/durand/right_arm name = "Durand Right Arm" id = "durand_right_arm" build_path = /obj/item/mecha_parts/part/durand_right_arm - time = 40 + time = 20 materials = list(DEFAULT_WALL_MATERIAL = 26250, "silver" = 2250) /datum/design/item/mechfab/durand/left_leg name = "Durand Left Leg" id = "durand_left_leg" build_path = /obj/item/mecha_parts/part/durand_left_leg - time = 40 + time = 20 materials = list(DEFAULT_WALL_MATERIAL = 30000, "silver" = 2250) /datum/design/item/mechfab/durand/right_leg name = "Durand Right Leg" id = "durand_right_leg" build_path = /obj/item/mecha_parts/part/durand_right_leg - time = 40 + time = 20 materials = list(DEFAULT_WALL_MATERIAL = 30000, "silver" = 2250) /datum/design/item/mechfab/durand/armour name = "Durand Armour Plates" id = "durand_armour" build_path = /obj/item/mecha_parts/part/durand_armour - time = 90 + time = 60 materials = list(DEFAULT_WALL_MATERIAL = 27500, MAT_PLASTEEL = 10000, "uranium" = 7500) /datum/design/item/mechfab/janus @@ -1043,7 +1043,7 @@ /datum/design/item/mechfab/exointernal category = "Exosuit Internals" - time = 120 + time = 30 req_tech = list(TECH_MATERIAL = 3, TECH_ENGINEERING = 3) /datum/design/item/mechfab/exointernal/stan_armor diff --git a/code/modules/research/message_server.dm b/code/modules/research/message_server.dm index bbcda60927d..81f888155d1 100644 --- a/code/modules/research/message_server.dm +++ b/code/modules/research/message_server.dm @@ -113,15 +113,15 @@ var/global/list/obj/machinery/message_server/message_servers = list() /obj/machinery/message_server/proc/send_rc_message(var/recipient = "",var/sender = "",var/message = "",var/stamp = "", var/id_auth = "", var/priority = 1) rc_msgs += new/datum/data_rc_msg(recipient,sender,message,stamp,id_auth) - var/authmsg = "[message]
" + var/authmsg = "[message]\n" if (id_auth) - authmsg += "[id_auth]
" + authmsg += "([id_auth])\n" if (stamp) - authmsg += "[stamp]
" + authmsg += "([stamp])\n" for (var/obj/machinery/requests_console/Console in allConsoles) if (ckey(Console.department) == ckey(recipient)) if(Console.inoperable()) - Console.message_log += "Message lost due to console failure.
Please contact [station_name()] system adminsitrator or AI for technical assistance.
" + Console.message_log += list(list("Message lost due to console failure.","Please contact [station_name()] system adminsitrator or AI for technical assistance.")) continue if(Console.newmessagepriority < priority) Console.newmessagepriority = priority @@ -131,12 +131,12 @@ var/global/list/obj/machinery/message_server/message_servers = list() if(!Console.silent) playsound(Console, 'sound/machines/twobeep.ogg', 50, 1) Console.audible_message(text("[bicon(Console)] *The Requests Console beeps: 'PRIORITY Alert in [sender]'"),,5) - Console.message_log += "High Priority message from [sender]
[authmsg]" + Console.message_log += list(list("High Priority message from [sender]", "[authmsg]")) else if(!Console.silent) playsound(Console, 'sound/machines/twobeep.ogg', 50, 1) Console.audible_message(text("[bicon(Console)] *The Requests Console beeps: 'Message from [sender]'"),,4) - Console.message_log += "Message from [sender]
[authmsg]" + Console.message_log += list(list("Message from [sender]", "[authmsg]")) Console.set_light(2) diff --git a/code/modules/research/prosfab_designs.dm b/code/modules/research/prosfab_designs.dm index da9cc055091..7882be40b50 100644 --- a/code/modules/research/prosfab_designs.dm +++ b/code/modules/research/prosfab_designs.dm @@ -193,6 +193,34 @@ materials = list(DEFAULT_WALL_MATERIAL = 5625, "glass" = 5625) // req_tech = list(TECH_ENGINEERING = 2, TECH_MATERIAL = 2) +/datum/design/item/prosfab/pros/internal/hydraulic + name = "Hydraulic Hub" + id = "pros_hydraulic" + build_path = /obj/item/organ/internal/heart/machine + time = 15 + materials = list(DEFAULT_WALL_MATERIAL = 7500, MAT_PLASTIC = 3000) + +/datum/design/item/prosfab/pros/internal/reagcycler + name = "Reagent Cycler" + id = "pros_reagcycler" + build_path = /obj/item/organ/internal/stomach/machine + time = 15 + materials = list(DEFAULT_WALL_MATERIAL = 7500, MAT_PLASTIC = 3000) + +/datum/design/item/prosfab/pros/internal/heatsink + name = "Heatsink" + id = "pros_heatsink" + build_path = /obj/item/organ/internal/robotic/heatsink + time = 15 + materials = list(DEFAULT_WALL_MATERIAL = 7500, MAT_PLASTIC = 3000) + +/datum/design/item/prosfab/pros/internal/diagnostic + name = "Diagnostic Controller" + id = "pros_diagnostic" + build_path = /obj/item/organ/internal/robotic/diagnostic + time = 15 + materials = list(DEFAULT_WALL_MATERIAL = 7500, MAT_PLASTIC = 3000) + /datum/design/item/prosfab/pros/internal/heart name = "Prosthetic Heart" id = "pros_heart" diff --git a/code/modules/rogueminer_vr/zone_console.dm b/code/modules/rogueminer_vr/zone_console.dm index be367629ca5..56544479a3f 100644 --- a/code/modules/rogueminer_vr/zone_console.dm +++ b/code/modules/rogueminer_vr/zone_console.dm @@ -36,17 +36,19 @@ add_fingerprint(user) if(stat & (BROKEN|NOPOWER)) return - user.set_machine(src) - ui_interact(user) - -/obj/machinery/computer/roguezones/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - user.set_machine(src) + tgui_interact(user) +/obj/machinery/computer/roguezones/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "RogueZones", name) + ui.open() +/obj/machinery/computer/roguezones/tgui_data(mob/user) var/chargePercent = min(100, ((((world.time - rm_controller.last_scan) / 10) / 60) / rm_controller.scan_wait) * 100) var/curZoneOccupied = rm_controller.current_zone ? rm_controller.current_zone.is_occupied() : 0 - var/list/data = list() + var/list/data = ..() data["timeout_percent"] = chargePercent data["diffstep"] = rm_controller.diffstep data["difficulty"] = rm_controller.diffstep_strs[rm_controller.diffstep] @@ -80,32 +82,24 @@ // Permit emergency recall of the shuttle if its stranded in a zone with just dead people. data["can_recall_shuttle"] = (shuttle_control && (shuttle_control.z in using_map.belter_belt_z) && !curZoneOccupied) + return data - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "zone_console.tmpl", src.name, 600, 400) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(5) - -/obj/machinery/computer/roguezones/Topic(href, href_list) +/obj/machinery/computer/roguezones/tgui_act(action, list/params) if(..()) - return 1 - usr.set_machine(src) - if (href_list["action"]) - switch(href_list["action"]) - if ("scan_for_new") - scan_for_new_zone() - if ("point_at_old") - point_at_old_zone() - if ("recall_shuttle") - failsafe_shuttle_recall() + return TRUE + switch(action) + if("scan_for_new") + scan_for_new_zone() + . = TRUE + if("recall_shuttle") + failsafe_shuttle_recall() + . = TRUE - src.add_fingerprint(usr) - SSnanoui.update_uis(src) + add_fingerprint(usr) /obj/machinery/computer/roguezones/proc/scan_for_new_zone() - if(scanning) return + if(scanning) + return //Set some kinda scanning var to pause UI input on console rm_controller.last_scan = world.time @@ -137,9 +131,6 @@ return -/obj/machinery/computer/roguezones/proc/point_at_old_zone() - - return /obj/machinery/computer/roguezones/proc/failsafe_shuttle_recall() if(!shuttle_control) diff --git a/code/modules/shieldgen/emergency_shield.dm b/code/modules/shieldgen/emergency_shield.dm index 4920ffb5131..a66c62750a1 100644 --- a/code/modules/shieldgen/emergency_shield.dm +++ b/code/modules/shieldgen/emergency_shield.dm @@ -1,5 +1,5 @@ /obj/machinery/shield - name = "Emergency energy shield" + name = "emergency energy shield" desc = "An energy shield used to contain hull breaches." icon = 'icons/effects/effects.dmi' icon_state = "shield-old" diff --git a/code/modules/shieldgen/sheldwallgen.dm b/code/modules/shieldgen/sheldwallgen.dm index 2a6a859c43e..b510c8b36b2 100644 --- a/code/modules/shieldgen/sheldwallgen.dm +++ b/code/modules/shieldgen/sheldwallgen.dm @@ -1,6 +1,6 @@ ////FIELD GEN START //shameless copypasta from fieldgen, powersink, and grille /obj/machinery/shieldwallgen - name = "Shield Generator" + name = "shield generator" desc = "A shield generator." icon = 'icons/obj/stationobjs.dmi' icon_state = "Shield_Gen" diff --git a/code/modules/shieldgen/shield_generator.dm b/code/modules/shieldgen/shield_generator.dm index 824eb86f66f..cc3d2f1b25b 100644 --- a/code/modules/shieldgen/shield_generator.dm +++ b/code/modules/shieldgen/shield_generator.dm @@ -400,8 +400,14 @@ spinup_counter = round(spinup_delay / idle_multiplier) update_icon() -/obj/machinery/power/shield_generator/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - var/data[0] +/obj/machinery/power/shield_generator/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "OvermapShieldGenerator", name) // 500, 800 + ui.open() + +/obj/machinery/power/shield_generator/tgui_data(mob/user) + var/list/data = list() data["running"] = running data["modes"] = get_flag_descriptions() @@ -427,12 +433,7 @@ data["idle_valid_values"] = idle_valid_values data["spinup_counter"] = spinup_counter - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "shield_generator.tmpl", src.name, 500, 800) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) + return data /obj/machinery/power/shield_generator/attack_hand(mob/user) if((. = ..())) @@ -440,99 +441,99 @@ if(panel_open && Adjacent(user)) wires.Interact(user) return - if(CanUseTopic(user, global.default_state) > STATUS_CLOSE) - ui_interact(user) - return TRUE + tgui_interact(user) -/obj/machinery/power/shield_generator/CanUseTopic(var/mob/user) +/obj/machinery/power/shield_generator/tgui_status(mob/user) if(issilicon(user) && !Adjacent(user) && ai_control_disabled) return STATUS_UPDATE if(panel_open) return min(..(), STATUS_DISABLED) return ..() -/obj/machinery/power/shield_generator/Topic(href, href_list, datum/topic_state/state = default_state) - if((. = ..())) - return +/obj/machinery/power/shield_generator/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) + if(..()) + return TRUE - if(href_list["begin_shutdown"]) - if(running < SHIELD_RUNNING) // Discharging or off - return - var/alert = alert(usr, "Are you sure you wish to do this? It will drain the power inside the internal storage rapidly.", "Are you sure?", "Yes", "No") - if(!CanInteract(usr, state)) - return - if(running < SHIELD_RUNNING) - return - if(alert == "Yes") - set_idle(TRUE) // do this first to clear the field - running = SHIELD_DISCHARGING - return TOPIC_REFRESH + switch(action) + if("begin_shutdown") + if(running < SHIELD_RUNNING) // Discharging or off + return + var/alert = alert(usr, "Are you sure you wish to do this? It will drain the power inside the internal storage rapidly.", "Are you sure?", "Yes", "No") + if(tgui_status(usr, state) != STATUS_INTERACTIVE) + return + if(running < SHIELD_RUNNING) + return + if(alert == "Yes") + set_idle(TRUE) // do this first to clear the field + running = SHIELD_DISCHARGING + return TRUE - if(href_list["start_generator"]) - if(offline_for) - return - set_idle(TRUE) - return TOPIC_REFRESH + if("start_generator") + if(offline_for) + return + set_idle(TRUE) + return TRUE - if(href_list["toggle_idle"]) - if(running < SHIELD_RUNNING) - return TOPIC_HANDLED - set_idle(text2num(href_list["toggle_idle"])) - return TOPIC_REFRESH + if("toggle_idle") + if(running < SHIELD_RUNNING) + return TRUE + set_idle(text2num(params["toggle_idle"])) + return TRUE - // Instantly drops the shield, but causes a cooldown before it may be started again. Also carries a risk of EMP at high charge. - if(href_list["emergency_shutdown"]) - if(!running) - return TOPIC_HANDLED + // Instantly drops the shield, but causes a cooldown before it may be started again. Also carries a risk of EMP at high charge. + if("emergency_shutdown") + if(!running) + return TRUE - var/choice = input(usr, "Are you sure that you want to initiate an emergency shield shutdown? This will instantly drop the shield, and may result in unstable release of stored electromagnetic energy. Proceed at your own risk.") in list("Yes", "No") - if((choice != "Yes") || !running) - return TOPIC_HANDLED + var/choice = input(usr, "Are you sure that you want to initiate an emergency shield shutdown? This will instantly drop the shield, and may result in unstable release of stored electromagnetic energy. Proceed at your own risk.") in list("Yes", "No") + if((choice != "Yes") || !running) + return TRUE - // If the shield would take 5 minutes to disperse and shut down using regular methods, it will take x1.5 (7 minutes and 30 seconds) of this time to cool down after emergency shutdown - offline_for = round(current_energy / (SHIELD_SHUTDOWN_DISPERSION_RATE / 1.5)) - var/old_energy = current_energy - shutdown_field() - log_and_message_admins("has triggered \the [src]'s emergency shutdown!", usr) - spawn() - empulse(src, old_energy / 60000000, old_energy / 32000000, 1) // If shields are charged at 450 MJ, the EMP will be 7.5, 14.0625. 90 MJ, 1.5, 2.8125 - old_energy = 0 + // If the shield would take 5 minutes to disperse and shut down using regular methods, it will take x1.5 (7 minutes and 30 seconds) of this time to cool down after emergency shutdown + offline_for = round(current_energy / (SHIELD_SHUTDOWN_DISPERSION_RATE / 1.5)) + var/old_energy = current_energy + shutdown_field() + log_and_message_admins("has triggered \the [src]'s emergency shutdown!", usr) + spawn() + empulse(src, old_energy / 60000000, old_energy / 32000000, 1) // If shields are charged at 450 MJ, the EMP will be 7.5, 14.0625. 90 MJ, 1.5, 2.8125 + old_energy = 0 - return TOPIC_REFRESH + return TRUE if(mode_changes_locked) - return TOPIC_REFRESH + return TRUE - if(href_list["set_range"]) - var/new_range = input(usr, "Enter new field range (1-[world.maxx]). Leave blank to cancel.", "Field Radius Control", field_radius) as num - if(!new_range) - return TOPIC_HANDLED - target_radius = between(1, new_range, world.maxx) - return TOPIC_REFRESH + switch(action) + if("set_range") + var/new_range = input(usr, "Enter new field range (1-[world.maxx]). Leave blank to cancel.", "Field Radius Control", field_radius) as num + if(!new_range) + return TRUE + target_radius = between(1, new_range, world.maxx) + return TRUE - if(href_list["set_input_cap"]) - var/new_cap = round(input(usr, "Enter new input cap (in kW). Enter 0 or nothing to disable input cap.", "Generator Power Control", round(input_cap / 1000)) as num) - if(!new_cap) - input_cap = 0 - return - input_cap = max(0, new_cap) * 1000 - return TOPIC_REFRESH + if("set_input_cap") + var/new_cap = round(input(usr, "Enter new input cap (in kW). Enter 0 or nothing to disable input cap.", "Generator Power Control", round(input_cap / 1000)) as num) + if(!new_cap) + input_cap = 0 + return + input_cap = max(0, new_cap) * 1000 + return TRUE - if(href_list["toggle_mode"]) - // Toggling hacked-only modes requires the hacked var to be set to 1 - if((text2num(href_list["toggle_mode"]) & (MODEFLAG_BYPASS | MODEFLAG_OVERCHARGE)) && !hacked) - return TOPIC_HANDLED + if("toggle_mode") + // Toggling hacked-only modes requires the hacked var to be set to 1 + if((text2num(params["toggle_mode"]) & (MODEFLAG_BYPASS | MODEFLAG_OVERCHARGE)) && !hacked) + return TRUE - toggle_flag(text2num(href_list["toggle_mode"])) - return TOPIC_REFRESH + toggle_flag(text2num(params["toggle_mode"])) + return TRUE - if(href_list["switch_idle"]) - if(running == SHIELD_SPINNING_UP) - return TOPIC_REFRESH - var/new_idle = text2num(href_list["switch_idle"]) - if(new_idle in idle_valid_values) - idle_multiplier = new_idle - return TOPIC_REFRESH + if("switch_idle") + if(running == SHIELD_SPINNING_UP) + return TRUE + var/new_idle = text2num(params["switch_idle"]) + if(new_idle in idle_valid_values) + idle_multiplier = new_idle + return TRUE /obj/machinery/power/shield_generator/proc/field_integrity() if(full_shield_strength) diff --git a/code/modules/shuttles/shuttle_console.dm b/code/modules/shuttles/shuttle_console.dm index 3e3655ca5aa..93688365c0b 100644 --- a/code/modules/shuttles/shuttle_console.dm +++ b/code/modules/shuttles/shuttle_console.dm @@ -8,8 +8,8 @@ var/shuttle_tag // Used to coordinate data in shuttle controller. var/hacked = 0 // Has been emagged, no access restrictions. - var/ui_template = "shuttle_control_console.tmpl" - + var/skip_act = FALSE + var/tgui_subtemplate = "ShuttleControlConsoleDefault" /obj/machinery/computer/shuttle_control/attack_hand(user as mob) if(..(user)) @@ -19,9 +19,9 @@ to_chat(user, "Access Denied.") return 1 - ui_interact(user) + tgui_interact(user) -/obj/machinery/computer/shuttle_control/proc/get_ui_data(var/datum/shuttle/autodock/shuttle) +/obj/machinery/computer/shuttle_control/proc/shuttlerich_tgui_data(var/datum/shuttle/autodock/shuttle) var/shuttle_state switch(shuttle.moving_status) if(SHUTTLE_IDLE) shuttle_state = "idle" @@ -29,7 +29,7 @@ if(SHUTTLE_INTRANSIT) shuttle_state = "in_transit" var/shuttle_status - switch (shuttle.process_state) + switch(shuttle.process_state) if(IDLE_STATE) var/cannot_depart = shuttle.current_location.cannot_depart(shuttle) if (shuttle.in_use) @@ -55,7 +55,8 @@ "can_launch" = shuttle.can_launch(), "can_cancel" = shuttle.can_cancel(), "can_force" = shuttle.can_force(), - "docking_codes" = shuttle.docking_codes + "docking_codes" = shuttle.docking_codes, + "subtemplate" = tgui_subtemplate, ) // This is a subset of the actual checks; contains those that give messages to the user. @@ -74,59 +75,54 @@ return FALSE return TRUE -/obj/machinery/computer/shuttle_control/Topic(href, href_list) - if((. = ..())) +/obj/machinery/computer/shuttle_control/tgui_act(action, list/params) + if(..()) + return TRUE + if(skip_act) return - usr.set_machine(src) - src.add_fingerprint(usr) + add_fingerprint(usr) var/datum/shuttle/autodock/shuttle = SSshuttles.shuttles[shuttle_tag] - if(!shuttle) - to_chat(usr, "Unable to establish link with the shuttle.") - return handle_topic_href(shuttle, href_list, usr) - -/obj/machinery/computer/shuttle_control/proc/handle_topic_href(var/datum/shuttle/autodock/shuttle, var/list/href_list, var/user) if(!istype(shuttle)) - return TOPIC_NOACTION + to_chat(usr, "Unable to establish link with the shuttle.") + return TRUE - if(href_list["move"]) - if(can_move(shuttle, user)) - shuttle.launch(src) - return TOPIC_REFRESH - return TOPIC_HANDLED + switch(action) + if("move") + if(can_move(shuttle, usr)) + shuttle.launch(src) + return TRUE - if(href_list["force"]) - if(can_move(shuttle, user)) - shuttle.force_launch(src) - return TOPIC_REFRESH - return TOPIC_HANDLED + if("force") + if(can_move(shuttle, usr)) + shuttle.force_launch(src) + return TRUE - if(href_list["cancel"]) - shuttle.cancel_launch(src) - return TOPIC_REFRESH + if("cancel") + shuttle.cancel_launch(src) + return TRUE - if(href_list["set_codes"]) - var/newcode = input("Input new docking codes", "Docking codes", shuttle.docking_codes) as text|null - if (newcode && CanInteract(usr, global.default_state)) - shuttle.set_docking_codes(uppertext(newcode)) - return TOPIC_REFRESH + if("set_codes") + var/newcode = input("Input new docking codes", "Docking codes", shuttle.docking_codes) as text|null + if(newcode && !..()) + shuttle.set_docking_codes(uppertext(newcode)) + return TRUE + +/obj/machinery/computer/shuttle_control/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "ShuttleControl", "[shuttle_tag] Shuttle Control") // 470, 360 + ui.open() // We delegate populating data to another proc to make it easier for overriding types to add their data. -/obj/machinery/computer/shuttle_control/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) +/obj/machinery/computer/shuttle_control/tgui_data(mob/user) var/datum/shuttle/autodock/shuttle = SSshuttles.shuttles[shuttle_tag] - if (!istype(shuttle)) + if(!istype(shuttle)) to_chat(user, "Unable to establish link with the shuttle.") return - var/list/data = get_ui_data(shuttle) - - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, ui_template, "[shuttle_tag] Shuttle Control", 470, 360) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) + return shuttlerich_tgui_data(shuttle) // Call to set the linked shuttle tag; override to add behaviour to shuttle tag changes /obj/machinery/computer/shuttle_control/proc/set_shuttle_tag(var/new_shuttle_tag) diff --git a/code/modules/shuttles/shuttle_console_multi.dm b/code/modules/shuttles/shuttle_console_multi.dm index 9a724a9ab75..9226caebfb7 100644 --- a/code/modules/shuttles/shuttle_console_multi.dm +++ b/code/modules/shuttles/shuttle_console_multi.dm @@ -1,8 +1,8 @@ /obj/machinery/computer/shuttle_control/multi circuit = /obj/item/weapon/circuitboard/shuttle_console/multi - ui_template = "shuttle_control_console_multi.tmpl" + tgui_subtemplate = "ShuttleControlConsoleMulti" -/obj/machinery/computer/shuttle_control/multi/get_ui_data(var/datum/shuttle/autodock/multi/shuttle) +/obj/machinery/computer/shuttle_control/multi/shuttlerich_tgui_data(var/datum/shuttle/autodock/multi/shuttle) . = ..() if(istype(shuttle)) . += list( @@ -14,22 +14,28 @@ // "engines_charging" = ((shuttle.last_move + (shuttle.cooldown SECONDS)) > world.time), // Replaced by longer warmup_time ) -/obj/machinery/computer/shuttle_control/multi/handle_topic_href(var/datum/shuttle/autodock/multi/shuttle, var/list/href_list) - if((. = ..()) != null) - return +/obj/machinery/computer/shuttle_control/multi/tgui_act(action, list/params) + if(..()) + return TRUE - if(href_list["pick"]) - var/dest_key = input("Choose shuttle destination", "Shuttle Destination") as null|anything in shuttle.get_destinations() - if(dest_key && CanInteract(usr, global.default_state)) - shuttle.set_destination(dest_key, usr) - return TOPIC_REFRESH + var/datum/shuttle/autodock/multi/shuttle = SSshuttles.shuttles[shuttle_tag] + if(!istype(shuttle)) + to_chat(usr, "Unable to establish link with the shuttle.") + return TRUE - if(href_list["toggle_cloaked"]) - if(!shuttle.can_cloak) - return TOPIC_HANDLED - shuttle.cloaked = !shuttle.cloaked - if(shuttle.legit) - to_chat(usr, "Ship ATC inhibitor systems have been [(shuttle.cloaked ? "activated. The station will not" : "deactivated. The station will")] be notified of our arrival.") - else - to_chat(usr, "Ship stealth systems have been [(shuttle.cloaked ? "activated. The station will not" : "deactivated. The station will")] be warned of our arrival.") - return TOPIC_REFRESH + switch(action) + if("pick") + var/dest_key = input("Choose shuttle destination", "Shuttle Destination") as null|anything in shuttle.get_destinations() + if(dest_key && CanInteract(usr, global.default_state)) + shuttle.set_destination(dest_key, usr) + return TRUE + + if("toggle_cloaked") + if(!shuttle.can_cloak) + return TRUE + shuttle.cloaked = !shuttle.cloaked + if(shuttle.legit) + to_chat(usr, "Ship ATC inhibitor systems have been [(shuttle.cloaked ? "activated. The station will not" : "deactivated. The station will")] be notified of our arrival.") + else + to_chat(usr, "Ship stealth systems have been [(shuttle.cloaked ? "activated. The station will not" : "deactivated. The station will")] be warned of our arrival.") + return TRUE diff --git a/code/modules/shuttles/shuttles_web.dm b/code/modules/shuttles/shuttles_web.dm index 00d9344b004..acc7dc34616 100644 --- a/code/modules/shuttles/shuttles_web.dm +++ b/code/modules/shuttles/shuttles_web.dm @@ -167,6 +167,8 @@ icon_screen = "flight_center" var/list/my_doors //Should be list("id_tag" = "Pretty Door Name", ...) var/list/my_sensors //Should be list("id_tag" = "Pretty Sensor Name", ...) + tgui_subtemplate = "ShuttleControlConsoleWeb" + skip_act = TRUE // Note - Searching own area for doors/sensors is fine for legacy web shuttles as they are single-area. // However if this code is copied to future multi-area shuttles, should search in all shuttle areas @@ -205,80 +207,9 @@ return ..() - -// Fairly copypasta-y. -/obj/machinery/computer/shuttle_control/web/attack_hand(mob/user) - if(..(user)) - return - src.add_fingerprint(user) - - ui_interact(user) - - /* - // If nanoUI falls over and you want a non-nanoUI UI, feel free to uncomment this section. - var/datum/shuttle/autodock/web_shuttle/WS = shuttle_controller.shuttles[shuttle_tag] - if(!istype(WS)) - message_admins("ERROR: Shuttle computer ([src]) ([shuttle_tag]) could not find their shuttle in the shuttles list.") - return - - var/list/dat = list() - dat += "
[shuttle_tag] Ship Control
" - - if(WS.moving_status != SHUTTLE_IDLE) - dat += "Location: Moving
" - else - var/area/areacheck = get_area(src) - dat += "Location: [areacheck.name]
" - - if((WS.last_move + WS.cooldown) > world.time) - dat += "Engines charging.
" - else - dat += "Engines ready.
" - - if(WS.can_cloak) - dat += "
Toggle cloaking field
" - - for(var/datum/shuttle_route/route in WS.current_destination.routes) - dat += "[route.display_route(WS.current_destination)]
" - - - //Docking - dat += "

" - if(WS.skip_docking_checks()) - dat += "Docking Status: Not in use." - else - var/override_en = WS.docking_controller.override_enabled - var/docking_status = WS.docking_controller.get_docking_status() - - dat += "Docking Status: " - switch(docking_status) - if("undocked") - dat += "Undocked" - if("docking") - dat += "Docking" - if("undocking") - dat += "Undocking" - if("docked") - dat += "Docked" - - if(override_en) - dat += " (Override Enabled)" - - dat += ". \[Refresh\]

" - - switch(docking_status) - if("undocked") - dat += "Dock" - if("docked") - dat += "Undock" - dat += "
" - - user << browse(dat.Join(), "window=[shuttle_tag]shuttlecontrol;size=300x300") - */ - - -/obj/machinery/computer/shuttle_control/web/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - var/data[0] +/obj/machinery/computer/shuttle_control/web/tgui_data(mob/user) + var/list/data = list() + var/list/routes[0] var/datum/shuttle/autodock/web_shuttle/shuttle = SSshuttles.shuttles[shuttle_tag] if(!istype(shuttle)) @@ -286,7 +217,7 @@ return var/list/R = shuttle.web_master.get_available_routes() - for (var/i = 1 to length(R)) + for(var/i = 1 to length(R)) var/datum/shuttle_route/route = R[i] var/travel_time = null var/travel_modifier = shuttle.flight_time_modifier @@ -313,7 +244,6 @@ if(SHUTTLE_INTRANSIT) shuttle_state = "in_transit" - // For the progress bar. var/elapsed_time = world.time - shuttle.depart_time var/total_time = shuttle.arrive_time - shuttle.depart_time @@ -322,7 +252,6 @@ if(total_time) // Need to check or we might divide by zero. percent_finished = (elapsed_time / total_time) * 100 - var/list/doors = list() if(my_doors) for(var/doorname in my_doors) @@ -356,111 +285,90 @@ "autopilot" = shuttle.autopilot ? 1 : 0, "can_rename" = shuttle.can_rename ? 1 : 0, "doors" = doors, - "sensors" = sensors + "sensors" = sensors, + "subtemplate" = tgui_subtemplate, ) - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) + return data - if(!ui) - ui = new(user, src, ui_key, "flight.tmpl", "[shuttle.visible_name] Flight Computer", 500, 500) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) - - -/obj/machinery/computer/shuttle_control/web/Topic(href, href_list) - if((. = ..())) - return - - usr.set_machine(src) - src.add_fingerprint(usr) +/obj/machinery/computer/shuttle_control/web/tgui_act(action, list/params) + if(..()) + return TRUE var/datum/shuttle/autodock/web_shuttle/WS = SSshuttles.shuttles[shuttle_tag] if(!istype(WS)) message_admins("ERROR: Shuttle computer ([src]) ([shuttle_tag]) could not find their shuttle in the shuttles list.") return - if(href_list["refresh"]) - ui_interact(usr) - - if (WS.moving_status != SHUTTLE_IDLE) + if(WS.moving_status != SHUTTLE_IDLE) to_chat(usr, "[WS.visible_name] is busy moving.") return - if(href_list["rename_command"]) - WS.rename_shuttle(usr) + switch(action) + if("rename_command") + WS.rename_shuttle(usr) - if(href_list["dock_command"]) - if(WS.autopilot) - to_chat(usr, "The autopilot must be disabled before you can control the vessel manually.") - return - WS.dock() + if("dock_command") + if(WS.autopilot) + to_chat(usr, "The autopilot must be disabled before you can control the vessel manually.") + return + WS.dock() - if(href_list["undock_command"]) - if(WS.autopilot) - to_chat(usr, "The autopilot must be disabled before you can control the vessel manually.") - return - WS.undock() + if("undock_command") + if(WS.autopilot) + to_chat(usr, "The autopilot must be disabled before you can control the vessel manually.") + return + WS.undock() - if(href_list["cloak_command"]) - if(!WS.can_cloak) - return - WS.cloaked = TRUE - to_chat(usr, "Ship stealth systems have been activated. The station will not be warned of our arrival.") + if("toggle_cloaking") + if(!WS.can_cloak) + return + WS.cloaked = !WS.cloaked + if(WS.cloaked) + to_chat(usr, "Ship stealth systems have been activated. The station will not be warned of our arrival.") + else + to_chat(usr, "Ship stealth systems have been deactivated. The station will be warned of our arrival.") - if(href_list["uncloak_command"]) - if(!WS.can_cloak) - return - WS.cloaked = FALSE - to_chat(usr, "Ship stealth systems have been deactivated. The station will be warned of our arrival.") + if("toggle_autopilot") + WS.adjust_autopilot(!WS.autopilot) - if(href_list["autopilot_on_command"]) - WS.adjust_autopilot(TRUE) + if("traverse") + if(WS.autopilot) + to_chat(usr, "The autopilot must be disabled before you can control the vessel manually.") + return - if(href_list["autopilot_off_command"]) - WS.adjust_autopilot(FALSE) + if((WS.last_move + WS.cooldown) > world.time) + to_chat(usr, "The ship's drive is inoperable while the engines are charging.") + return - if(href_list["traverse"]) - if(WS.autopilot) - to_chat(usr, "The autopilot must be disabled before you can control the vessel manually.") - return + var/index = text2num(params["traverse"]) + var/datum/shuttle_route/new_route = WS.web_master.current_destination.routes[index] + if(!istype(new_route)) + message_admins("ERROR: Shuttle computer was asked to traverse a nonexistant route.") + return - if((WS.last_move + WS.cooldown) > world.time) - to_chat(usr, "The ship's drive is inoperable while the engines are charging.") - return + if(!check_docking(WS)) + return TRUE - var/index = text2num(href_list["traverse"]) - var/datum/shuttle_route/new_route = WS.web_master.current_destination.routes[index] - if(!istype(new_route)) - message_admins("ERROR: Shuttle computer was asked to traverse a nonexistant route.") - return + var/datum/shuttle_destination/target_destination = new_route.get_other_side(WS.web_master.current_destination) + if(!istype(target_destination)) + message_admins("ERROR: Shuttle computer was asked to travel to a nonexistant destination.") + return - if(!check_docking(WS)) - // updateUsrDialog() - ui_interact(usr) - return + WS.next_location = target_destination.my_landmark + if(!can_move(WS, usr)) + return - var/datum/shuttle_destination/target_destination = new_route.get_other_side(WS.web_master.current_destination) - if(!istype(target_destination)) - message_admins("ERROR: Shuttle computer was asked to travel to a nonexistant destination.") - return + WS.web_master.future_destination = target_destination + to_chat(usr, "[WS.visible_name] flight computer received command.") + WS.web_master.reset_autopath() // Deviating from the path will almost certainly confuse the autopilot, so lets just reset its memory. - WS.next_location = target_destination.my_landmark - if(!can_move(WS, usr)) - return - - WS.web_master.future_destination = target_destination - to_chat(usr, "[WS.visible_name] flight computer received command.") - WS.web_master.reset_autopath() // Deviating from the path will almost certainly confuse the autopilot, so lets just reset its memory. - - var/travel_time = new_route.travel_time * WS.flight_time_modifier - // TODO - Leshana - Change this to use proccess stuff of autodock! - if(new_route.interim && new_route.travel_time) - WS.long_jump(target_destination.my_landmark, new_route.interim, travel_time / 10) - else - WS.short_jump(target_destination.my_landmark) - - ui_interact(usr) + var/travel_time = new_route.travel_time * WS.flight_time_modifier + // TODO - Leshana - Change this to use proccess stuff of autodock! + if(new_route.interim && new_route.travel_time) + WS.long_jump(target_destination.my_landmark, new_route.interim, travel_time / 10) + else + WS.short_jump(target_destination.my_landmark) //check if we're undocked, give option to force launch /obj/machinery/computer/shuttle_control/web/proc/check_docking(datum/shuttle/autodock/MS) diff --git a/code/modules/tgui/external.dm b/code/modules/tgui/external.dm index 19f039869e3..bb39c721d0d 100644 --- a/code/modules/tgui/external.dm +++ b/code/modules/tgui/external.dm @@ -141,6 +141,26 @@ */ /datum/proc/tgui_close(mob/user) +/** + * verb + * + * Used by a client to fix broken TGUI windows caused by opening a UI window before assets load. + * Probably not very performant and forcibly destroys a bunch of windows, so it has some warnings attached. + * Conveniently, also allows devs to force a dev server reattach without relogging, since it yeets windows. + */ +/client/verb/tgui_fix_white() + set desc = "Only use this if you have a broken TGUI window occupying your screen!" + set name = "Fix TGUI" + set category = "OOC" + + if(alert(src, "Only use this verb if you have a white TGUI window stuck on your screen.", "Fix TGUI", "Continue", "Nevermind") != "Continue") + return + + SStgui.close_user_uis(mob) + if(alert(src, "Did that fix the problem?", "Fix TGUI", "Yes", "No") == "No") + SStgui.force_close_all_windows(mob) + alert(src, "UIs should be fixed now. If not, please cry to your nearest coder.", "Fix TGUI") + /** * verb * diff --git a/code/modules/tgui/modules/_base.dm b/code/modules/tgui/modules/_base.dm index cefe49230f8..1a1027072d9 100644 --- a/code/modules/tgui/modules/_base.dm +++ b/code/modules/tgui/modules/_base.dm @@ -26,6 +26,9 @@ Code is pretty much ripped verbatim from nano modules, but with un-needed stuff if(host) host.tgui_close(user) +/datum/tgui_module/proc/check_eye(mob/user) + return -1 + /datum/tgui_module/proc/can_still_topic(mob/user, datum/tgui_state/state) return (tgui_status(user, state) == STATUS_INTERACTIVE) @@ -112,4 +115,12 @@ Code is pretty much ripped verbatim from nano modules, but with un-needed stuff . += new /obj/screen/plane_master/main{plane = TURF_PLANE} . += new /obj/screen/plane_master/main{plane = OBJ_PLANE} . += new /obj/screen/plane_master/main{plane = MOB_PLANE} - . += new /obj/screen/plane_master/cloaked //Cloaked atoms! \ No newline at end of file + . += new /obj/screen/plane_master/cloaked //Cloaked atoms! + + //VOREStation Add - Random other plane masters + . += new /obj/screen/plane_master{plane = PLANE_CH_STATUS_R} //Right-side status icon + . += new /obj/screen/plane_master{plane = PLANE_CH_HEALTH_VR} //Health bar but transparent at 100 + . += new /obj/screen/plane_master{plane = PLANE_CH_BACKUP} //Backup implant status + . += new /obj/screen/plane_master{plane = PLANE_CH_VANTAG} //Vore Antags + . += new /obj/screen/plane_master{plane = PLANE_AUGMENTED} //Augmented reality + //VOREStation Add End \ No newline at end of file diff --git a/code/modules/tgui/modules/alarm.dm b/code/modules/tgui/modules/alarm.dm index 2c0c75a6e8b..b9de22c7e69 100644 --- a/code/modules/tgui/modules/alarm.dm +++ b/code/modules/tgui/modules/alarm.dm @@ -13,6 +13,11 @@ ..() alarm_handlers = SSalarm.all_handlers +// Subtype for glasses_state +/datum/tgui_module/alarm_monitor/all/glasses +/datum/tgui_module/alarm_monitor/all/glasses/tgui_state(mob/user) + return GLOB.tgui_glasses_state + /datum/tgui_module/alarm_monitor/all/robot /datum/tgui_module/alarm_monitor/all/robot/tgui_state(mob/user) return GLOB.tgui_self_state diff --git a/code/modules/tgui/modules/camera.dm b/code/modules/tgui/modules/camera.dm index d9ac311ee36..dbb3c7ae976 100644 --- a/code/modules/tgui/modules/camera.dm +++ b/code/modules/tgui/modules/camera.dm @@ -141,11 +141,33 @@ var/obj/machinery/camera/C = cameras["[ckey(c_tag)]"] active_camera = C playsound(tgui_host(), get_sfx("terminal_type"), 25, FALSE) - reload_cameraview() - return TRUE + if(action == "pan") + var/dir = params["dir"] + var/turf/T = get_turf(active_camera) + for(var/i in 1 to 10) + T = get_step(T, dir) + if(T) + var/obj/machinery/camera/target + var/best_dist = INFINITY + + var/list/possible_cameras = get_available_cameras(usr) + for(var/obj/machinery/camera/C in get_area(T)) + if(!possible_cameras["[ckey(C.c_tag)]"]) + continue + var/dist = get_dist(C, T) + if(dist < best_dist) + best_dist = dist + target = C + + if(target) + active_camera = target + playsound(tgui_host(), get_sfx("terminal_type"), 25, FALSE) + reload_cameraview() + . = TRUE + /datum/tgui_module/camera/proc/differential_check() var/turf/T = get_turf(active_camera) if(T) diff --git a/code/modules/tgui/modules/overmap.dm b/code/modules/tgui/modules/overmap.dm new file mode 100644 index 00000000000..3b157fc0c22 --- /dev/null +++ b/code/modules/tgui/modules/overmap.dm @@ -0,0 +1,137 @@ +/datum/tgui_module/ship + var/obj/effect/overmap/visitable/ship/linked + var/list/viewers + var/extra_view = 0 + +/datum/tgui_module/ship/New() + . = ..() + sync_linked() + if(linked) + name = "[linked.name] [name]" + +/datum/tgui_module/ship/Destroy() + if(LAZYLEN(viewers)) + for(var/weakref/W in viewers) + var/M = W.resolve() + if(M) + unlook(M) + . = ..() + +/datum/tgui_module/ship/tgui_status(mob/user) + . = ..() + if(. > STATUS_DISABLED) + if(viewing_overmap(user)) + look(user) + return + unlook(user) + +/datum/tgui_module/ship/tgui_close(mob/user) + . = ..() + user.unset_machine() + unlook(user) + +/datum/tgui_module/ship/proc/sync_linked() + var/obj/effect/overmap/visitable/ship/sector = get_overmap_sector(get_z(tgui_host())) + if(!sector) + return + return attempt_hook_up_recursive(sector) + +/datum/tgui_module/ship/proc/attempt_hook_up_recursive(obj/effect/overmap/visitable/ship/sector) + if(attempt_hook_up(sector)) + return sector + for(var/obj/effect/overmap/visitable/ship/candidate in sector) + if((. = .(candidate))) + return + +/datum/tgui_module/ship/proc/attempt_hook_up(obj/effect/overmap/visitable/ship/sector) + if(!istype(sector)) + return + if(sector.check_ownership(tgui_host())) + linked = sector + return 1 + +/datum/tgui_module/ship/proc/look(var/mob/user) + if(linked) + user.set_machine(tgui_host()) + user.reset_view(linked) + user.set_viewsize(world.view + extra_view) + GLOB.moved_event.register(user, src, /datum/tgui_module/ship/proc/unlook) + LAZYDISTINCTADD(viewers, weakref(user)) + +/datum/tgui_module/ship/proc/unlook(var/mob/user) + user.reset_view() + user.set_viewsize() // reset to default + GLOB.moved_event.unregister(user, src, /datum/tgui_module/ship/proc/unlook) + LAZYREMOVE(viewers, weakref(user)) + +/datum/tgui_module/ship/proc/viewing_overmap(mob/user) + return (weakref(user) in viewers) + +/datum/tgui_module/ship/check_eye(var/mob/user) + if(!get_dist(user, tgui_host()) > 1 || user.blinded || !linked) + unlook(user) + return -1 + else + return 0 + +// Navigation +/datum/tgui_module/ship/nav + name = "Navigation Display" + tgui_id = "OvermapNavigation" + +/datum/tgui_module/ship/nav/tgui_interact(mob/user, datum/tgui/ui) + if(!linked) + var/obj/machinery/computer/ship/navigation/host = tgui_host() + if(istype(host)) + // Real Computer path + host.display_reconnect_dialog(user, "Navigation") + return + + // NTOS Path + if(!sync_linked()) + to_chat(user, "You don't appear to be on a spaceship...") + if(ui) + ui.close(can_be_suspended = FALSE) + if(ntos) + var/obj/item/modular_computer/M = tgui_host() + if(istype(M)) + M.kill_program() + return + + . = ..() + +/datum/tgui_module/ship/nav/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() + + var/turf/T = get_turf(linked) + var/obj/effect/overmap/visitable/sector/current_sector = locate() in T + + data["sector"] = current_sector ? current_sector.name : "Deep Space" + data["sector_info"] = current_sector ? current_sector.desc : "Not Available" + data["s_x"] = linked.x + data["s_y"] = linked.y + data["speed"] = round(linked.get_speed()*1000, 0.01) + data["accel"] = round(linked.get_acceleration()*1000, 0.01) + data["heading"] = linked.get_heading_degrees() + data["viewing"] = viewing_overmap(user) + + if(linked.get_speed()) + data["ETAnext"] = "[round(linked.ETA()/10)] seconds" + else + data["ETAnext"] = "N/A" + + return data + +/datum/tgui_module/ship/nav/tgui_act(action, params) + if(..()) + return TRUE + + if(!linked) + return FALSE + + if(action == "viewing") + viewing_overmap(usr) ? unlook(usr) : look(usr) + return TRUE + +/datum/tgui_module/ship/nav/ntos + ntos = TRUE \ No newline at end of file diff --git a/code/modules/turbolift/turbolift_console.dm b/code/modules/turbolift/turbolift_console.dm index 9d8b90f8027..4d300bcfc26 100644 --- a/code/modules/turbolift/turbolift_console.dm +++ b/code/modules/turbolift/turbolift_console.dm @@ -131,7 +131,7 @@ lift.update_fire_mode(!lift.fire_mode) if(lift.fire_mode) audible_message("Firefighter Mode Activated. Door safeties disabled. Manual control engaged.") - playsound(src, 'sound/machines/airalarm.ogg', 25, 0, 4) + playsound(src, 'sound/machines/airalarm.ogg', 25, 0, 4, volume_channel = VOLUME_CHANNEL_ALARMS) else audible_message("Firefighter Mode Deactivated. Door safeties enabled. Automatic control engaged.") return diff --git a/code/modules/ventcrawl/ventcrawl.dm b/code/modules/ventcrawl/ventcrawl.dm index 9f472102fdb..44bb57e18c0 100644 --- a/code/modules/ventcrawl/ventcrawl.dm +++ b/code/modules/ventcrawl/ventcrawl.dm @@ -33,6 +33,9 @@ var/list/ventcrawl_machinery = list( if(incapacitated()) to_chat(src, "You cannot ventcrawl in your current state!") return FALSE + if(buckled) + to_chat(src, "You cannot ventcrawl while buckled!") + return FALSE return ventcrawl_carry() /mob/living/Login() @@ -201,4 +204,4 @@ var/list/ventcrawl_machinery = list( client.screen -= global_hud.centermarker client.eye = src - pipes_shown.len = 0 \ No newline at end of file + pipes_shown.len = 0 diff --git a/code/modules/vore/eating/belly_obj_vr.dm b/code/modules/vore/eating/belly_obj_vr.dm index e929b177e4d..ef8b3d282ec 100644 --- a/code/modules/vore/eating/belly_obj_vr.dm +++ b/code/modules/vore/eating/belly_obj_vr.dm @@ -194,7 +194,7 @@ else soundfile = fancy_vore_sounds[vore_sound] if(soundfile) - playsound(src, soundfile, vol = 100, vary = 1, falloff = VORE_SOUND_FALLOFF, preference = /datum/client_preference/eating_noises) + playsound(src, soundfile, vol = 100, vary = 1, falloff = VORE_SOUND_FALLOFF, preference = /datum/client_preference/eating_noises, volume_channel = VOLUME_CHANNEL_VORE) recent_sound = TRUE //Messages if it's a mob @@ -275,7 +275,7 @@ else soundfile = fancy_release_sounds[release_sound] if(soundfile) - playsound(src, soundfile, vol = 100, vary = 1, falloff = VORE_SOUND_FALLOFF, preference = /datum/client_preference/eating_noises) + playsound(src, soundfile, vol = 100, vary = 1, falloff = VORE_SOUND_FALLOFF, preference = /datum/client_preference/eating_noises, volume_channel = VOLUME_CHANNEL_VORE) return count @@ -323,7 +323,7 @@ else soundfile = fancy_release_sounds[release_sound] if(soundfile) - playsound(src, soundfile, vol = 100, vary = 1, falloff = VORE_SOUND_FALLOFF, preference = /datum/client_preference/eating_noises) + playsound(src, soundfile, vol = 100, vary = 1, falloff = VORE_SOUND_FALLOFF, preference = /datum/client_preference/eating_noises, volume_channel = VOLUME_CHANNEL_VORE) return 1 @@ -589,9 +589,9 @@ struggle_snuggle = sound(get_sfx("classic_struggle_sounds")) else struggle_snuggle = sound(get_sfx("fancy_prey_struggle")) - playsound(src, struggle_snuggle, vary = 1, vol = 75, falloff = VORE_SOUND_FALLOFF, preference = /datum/client_preference/digestion_noises) + playsound(src, struggle_snuggle, vary = 1, vol = 75, falloff = VORE_SOUND_FALLOFF, preference = /datum/client_preference/digestion_noises, volume_channel = VOLUME_CHANNEL_VORE) else - playsound(src, struggle_rustle, vary = 1, vol = 75, falloff = VORE_SOUND_FALLOFF, preference = /datum/client_preference/digestion_noises) + playsound(src, struggle_rustle, vary = 1, vol = 75, falloff = VORE_SOUND_FALLOFF, preference = /datum/client_preference/digestion_noises, volume_channel = VOLUME_CHANNEL_VORE) if(escapable) //If the stomach has escapable enabled. if(prob(escapechance)) //Let's have it check to see if the prey escapes first. diff --git a/code/modules/vore/fluffstuff/custom_clothes_vr.dm b/code/modules/vore/fluffstuff/custom_clothes_vr.dm index 2f05ab268fd..3df20d6a2bf 100644 --- a/code/modules/vore/fluffstuff/custom_clothes_vr.dm +++ b/code/modules/vore/fluffstuff/custom_clothes_vr.dm @@ -1987,4 +1987,17 @@ Departamental Swimsuits, for general use icon_override = 'icons/vore/custom_clothes_vr.dmi' item_state = "zenasuit_mob" - species_restricted = null \ No newline at end of file + species_restricted = null + +/obj/item/clothing/suit/storage/flintlock + name = "green jacket" + desc = "Flintlock's green jacket. It seems to be made of rather high quality leather." + icon = 'icons/vore/custom_clothes_vr.dmi' + icon_state = "flintlock" + item_state_slots = list(slot_r_hand_str = "item_greensuit", slot_l_hand_str = "item_greensuit") + blood_overlay_type = "coat" + body_parts_covered = UPPER_TORSO|ARMS + flags_inv = HIDEHOLSTER + + icon_override = 'icons/vore/custom_clothes_vr.dmi' + item_state = "flintlock_mob" \ No newline at end of file diff --git a/code/modules/xenoarcheaology/artifacts/replicator.dm b/code/modules/xenoarcheaology/artifacts/replicator.dm index da5b123c166..49e24f8a977 100644 --- a/code/modules/xenoarcheaology/artifacts/replicator.dm +++ b/code/modules/xenoarcheaology/artifacts/replicator.dm @@ -42,8 +42,8 @@ /obj/item/weapon/bikehorn, /obj/item/weapon/surgical/bonesetter, /obj/item/weapon/material/knife/butch, - /obj/item/weapon/caution, - /obj/item/weapon/caution/cone, + /obj/item/clothing/suit/caution, + /obj/item/clothing/head/cone, /obj/item/weapon/tool/crowbar, /obj/item/weapon/clipboard, /obj/item/weapon/cell, diff --git a/config/alienwhitelist.txt b/config/alienwhitelist.txt index 37f35cba960..c87dcf2bd4b 100644 --- a/config/alienwhitelist.txt +++ b/config/alienwhitelist.txt @@ -14,6 +14,7 @@ bricker98 - Protean crossexonar - Protean chillyfang - Black-Eyed Shadekin cgr - Protean +draycu - Vox flaktual - Vox funnyman2003 - Xenochimera flurriee - Protean @@ -24,11 +25,13 @@ jademanique - Xenochimera jemli - Gutter ktccd - Diona khanivore - Protean +lunarfleet - Gutter mewchild - Diona mewchild - Vox mrsebbi - Xenochimera natje - Xenochimera nerdass - Protean +ontejbjoav - Diona oreganovulgaris - Xenochimera paradoxspace - Xenochimera pearlprophet - Protean diff --git a/config/custom_sprites.txt b/config/custom_sprites.txt index db3930a4ae2..b99307d173f 100644 --- a/config/custom_sprites.txt +++ b/config/custom_sprites.txt @@ -1 +1,3 @@ -ckey-state \ No newline at end of file +ckey|state +lunarfleet|Clea-Nor +jademanique|B.A.U-Kingside \ No newline at end of file diff --git a/config/example/config.txt b/config/example/config.txt index 50ee910f8d2..d56d60a5ae9 100644 --- a/config/example/config.txt +++ b/config/example/config.txt @@ -151,6 +151,12 @@ TRAITOR_SCALING ## If security is prohibited from being most antagonists #PROTECT_ROLES_FROM_ANTAGONIST +## Uncomment this to DISABLE persistence +#PERSISTENCE_DISABLED + +## Uncomment this to DISABLE maploaded trash/paper/etc from being saved by the persistence system. +#PERSISTENCE_IGNORE_MAPLOAD + ## Comment this out to stop admins being able to choose their personal ooccolor ALLOW_ADMIN_OOCCOLOR diff --git a/html/changelog.html b/html/changelog.html index 39c9522a1d7..7153910a42e 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -53,6 +53,78 @@ -->
+

20 August 2020

+

Atermonera updated:

+
    +
  • Mapped Overmap sensors onto the Southern Cross. Deck 2, central ring, starboard side. Departmental sensor installations and dedicated rooms may be added in the future.
  • +
  • To use the new sensors, you first have to click on them, hit 'Reconnect' on the window, close the window, then reopen it to get the console to link up with the sensors properly.
  • +
  • Enabled overmap event generation. This doesn't really do anything yet because the shuttles haven't been upgraded, but it's very pretty!
  • +
+

BlinsKot updated:

+
    +
  • You can now alt-click to turn on the washing machine.
  • +
  • You can now alt-click on a mech while piloting it to toggle strafing.
  • +
+

Cerebulon updated:

+
    +
  • Added extended flavour text to most things related to commercial vending machines and their contents.
  • +
  • Added chewing gum, lollipops and chewing tobacco. Unwrap it and place it in your mask slot like a cigarette.
  • +
  • Added snack food, vending drink and beer brand variety.
  • +
  • New booze bottle, coffee, juice, snack and cigarette packet sprites.
  • +
+

Lorilili updated:

+
    +
  • Skrellian blood is now hemocyanin-based and regenerates with copper, not iron.
  • +
  • You can now wear caution signs and warning cones.
  • +
  • You can now point using shift and middle mouse button.
  • +
+

Mechoid updated:

+
    +
  • Mortiferin added in place of old Necroxadone as a normal chem recipe.
  • +
  • Necroxadone changed to a more powerful alternative to Mortiferin which works even on corpses without bloodflow.
  • +
  • Added reagent pumps. You can refill water tanks planetside!
  • +
  • Added reagent hoses. Only used player-side by tanks, pumps, and spray nozzles to move reagents from one container to another.
  • +
+

Meghan Rossi updated:

+
    +
  • Cyborgs can now put things into oven dishes with their grippers
  • +
  • Cyborgs can now put oven dishes in the oven with their grippers
  • +
  • Bots that are idle in doorways (including firedoors and blastdoors) will move out of the way.
  • +
  • Multiple cleanbots will no longer attempt to clean the same tile at the same time.
  • +
  • Cleanbots will now clean tiles closer to them first.
  • +
  • You can now use duct tape on yourself.
  • +
  • Ghosts now have a toggleable security HUD. Use the 'Toggle Security HUD' verb in the ghost tab to enable it
  • +
  • Ghosts can now shift-click things to examine them.
  • +
  • Ghosts can now alt-click adjacent things to open the turf tab.
  • +
  • You can now build plating on grass with floor tiles.
  • +
  • Improved descriptions for some floors.
  • +
  • The rapid service fabricator (found on service borgs) can now produce metamorphic pint glasses.
  • +
  • The party supplies and bar supplies crates orderable from cargo now contain metamorphic pint glasses.
  • +
  • The autolathe can now produce metamorphic pint and half-pint glasses.
  • +
  • The autolathe can now produce all drinking glasses in batches of 5 or 10.
  • +
+

Nyria updated:

+
    +
  • Added volume settings, available in character setup or from the Preferences tab.
  • +
  • More settings and affected sounds may be added at a later date.
  • +
  • Added a TGui window to control the new settings with shiny sliders.
  • +
+

Rykka Stormheart updated:

+
    +
  • Adds a mech vs mech combat system for the toy mechs earned from arcades and found around the station.
  • +
  • You can initiate combat with yourself by hitting a toy mech with another toy mech, or fight another player if you attack a player holding a mech toy with your own mech toy while not on harm intent.
  • +
  • Each mech has its own health stat and special ability that they'll use in combat against each other.
  • +
+

SplinterGP updated:

+
    +
  • Added verb for FBP's to change their monitor display.
  • +
  • Removed monitor mask item(replaced by verb).
  • +
+

Subber updated:

+
    +
  • Added a new prosthetic sprite set: Cyber Solutions - Outdated.
  • +
+

06 August 2020

Cerebulon updated:

    diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index 0ca89eb0666..3a86bfb6b7d 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -5240,3 +5240,78 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. reviewed, and will likely be adjusted after sufficient feedback is gathered. - rscadd: Blast doors and shutters (the types that go on bar/kitchen/etc) will also throw items on their tiles. +2020-08-20: + Atermonera: + - maptweak: Mapped Overmap sensors onto the Southern Cross. Deck 2, central ring, + starboard side. Departmental sensor installations and dedicated rooms may be + added in the future. + - wip: To use the new sensors, you first have to click on them, hit 'Reconnect' + on the window, close the window, then reopen it to get the console to link up + with the sensors properly. + - wip: Enabled overmap event generation. This doesn't really do anything yet because + the shuttles haven't been upgraded, but it's very pretty! + BlinsKot: + - rscadd: You can now alt-click to turn on the washing machine. + - rscadd: You can now alt-click on a mech while piloting it to toggle strafing. + Blinskot: + - rscadd: You can now alt-click on a mech while piloting it to toggle strafing. + - rscadd: You can now alt-click to turn on the washing machine. + Cerebulon: + - rscadd: Added extended flavour text to most things related to commercial vending + machines and their contents. + - rscadd: Added chewing gum, lollipops and chewing tobacco. Unwrap it and place + it in your mask slot like a cigarette. + - rscadd: Added snack food, vending drink and beer brand variety. + - imageadd: New booze bottle, coffee, juice, snack and cigarette packet sprites. + Lorilili: + - tweak: Skrellian blood is now hemocyanin-based and regenerates with copper, not + iron. + - rscadd: You can now wear caution signs and warning cones. + - rscadd: You can now point using shift and middle mouse button. + Mechoid: + - rscadd: Mortiferin added in place of old Necroxadone as a normal chem recipe. + - tweak: Necroxadone changed to a more powerful alternative to Mortiferin which + works even on corpses without bloodflow. + - rscadd: Added reagent pumps. You can refill water tanks planetside! + - rscadd: Added reagent hoses. Only used player-side by tanks, pumps, and spray + nozzles to move reagents from one container to another. + Meghan Rossi: + - bugfix: Cyborgs can now put things into oven dishes with their grippers + - bugfix: Cyborgs can now put oven dishes in the oven with their grippers + - tweak: Bots that are idle in doorways (including firedoors and blastdoors) will + move out of the way. + - rscadd: Multiple cleanbots will no longer attempt to clean the same tile at the + same time. + - rscadd: Cleanbots will now clean tiles closer to them first. + - bugfix: You can now use duct tape on yourself. + - rscadd: Ghosts now have a toggleable security HUD. Use the 'Toggle Security HUD' + verb in the ghost tab to enable it + - rscadd: Ghosts can now shift-click things to examine them. + - rscadd: Ghosts can now alt-click adjacent things to open the turf tab. + - bugfix: You can now build plating on grass with floor tiles. + - rscadd: Improved descriptions for some floors. + - rscadd: The rapid service fabricator (found on service borgs) can now produce + metamorphic pint glasses. + - rscadd: The party supplies and bar supplies crates orderable from cargo now contain + metamorphic pint glasses. + - rscadd: The autolathe can now produce metamorphic pint and half-pint glasses. + - rscadd: The autolathe can now produce all drinking glasses in batches of 5 or + 10. + Nyria: + - rscadd: Added volume settings, available in character setup or from the Preferences + tab. + - rscadd: More settings and affected sounds may be added at a later date. + - rscadd: Added a TGui window to control the new settings with shiny sliders. + Rykka Stormheart: + - rscadd: Adds a mech vs mech combat system for the toy mechs earned from arcades + and found around the station. + - rscadd: You can initiate combat with yourself by hitting a toy mech with another + toy mech, or fight another player if you attack a player holding a mech toy + with your own mech toy while not on harm intent. + - rscadd: Each mech has its own health stat and special ability that they'll use + in combat against each other. + SplinterGP: + - rscadd: Added verb for FBP's to change their monitor display. + - rscdel: Removed monitor mask item(replaced by verb). + Subber: + - rscadd: 'Added a new prosthetic sprite set: Cyber Solutions - Outdated.' diff --git a/html/changelogs/Lorilili - borgpet.yml b/html/changelogs/Lorilili - borgpet.yml new file mode 100644 index 00000000000..6af4fa0c255 --- /dev/null +++ b/html/changelogs/Lorilili - borgpet.yml @@ -0,0 +1,5 @@ +author: Lorilili +delete-after: True +changes: + - rscadd: "You can now pet borgs on help intent and punch on hurt intent. Old behavior is now grab intent." + diff --git a/html/changelogs/Kot-Washing.yml b/html/changelogs/rykka-stormheart - ambience prefs.yml similarity index 70% rename from html/changelogs/Kot-Washing.yml rename to html/changelogs/rykka-stormheart - ambience prefs.yml index 0da4b507c5d..c55ec992d7b 100644 --- a/html/changelogs/Kot-Washing.yml +++ b/html/changelogs/rykka-stormheart - ambience prefs.yml @@ -22,7 +22,7 @@ ################################# # Your name. -author: BlinsKot +author: Rykka Stormheart # Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. delete-after: True @@ -33,4 +33,6 @@ delete-after: True # Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. # Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. changes: - - rscadd: "You pansies can now alt click to turn on the washing machine." \ No newline at end of file + - rscadd: "Adds Ambience Chance and Repeating Ambience Preferences into Globals, underneath Client FPS" + - rscadd: "Random-Ambience-Frequency controls how long before it checks if it can play ambience to you again. Setting it to 0 disables the random re-play of ambience." + - rscadd: "Ambience Chance affects the % chance to play ambience to your client. It defaults to 35%, but can be set from 0 to 100 to disable it or always play every time you move into an area or have the Random Ambience check called." diff --git a/html/changelogs/mechoid - mortiferin.yml b/html/changelogs/rykka-stormheart - toy mechs.yml similarity index 75% rename from html/changelogs/mechoid - mortiferin.yml rename to html/changelogs/rykka-stormheart - toy mechs.yml index 00ce2ca033a..5967df1bfae 100644 --- a/html/changelogs/mechoid - mortiferin.yml +++ b/html/changelogs/rykka-stormheart - toy mechs.yml @@ -22,7 +22,7 @@ ################################# # Your name. -author: Mechoid +author: Rykka Stormheart # Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. delete-after: True @@ -33,5 +33,6 @@ delete-after: True # Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. # Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. changes: - - rscadd: "Mortiferin added in place of old Necroxadone as a normal chem recipe." - - tweak: "Necroxadone changed to a more powerful alternative to Mortiferin which works even on corpses without bloodflow." + - rscadd: "Adds a mech vs mech combat system for the toy mechs earned from arcades and found around the station." + - rscadd: "You can initiate combat with yourself by hitting a toy mech with another toy mech, or fight another player if you attack a player holding a mech with a mech." + - rscadd: "Each mech has its own health stat and special ability that they'll use in combat against each other." diff --git a/html/changelogs/BlinsKot - strafing.yml b/html/changelogs/shadowlarkens - job preferences.yml similarity index 91% rename from html/changelogs/BlinsKot - strafing.yml rename to html/changelogs/shadowlarkens - job preferences.yml index f99f20e104e..75a2fe7a28e 100644 --- a/html/changelogs/BlinsKot - strafing.yml +++ b/html/changelogs/shadowlarkens - job preferences.yml @@ -22,7 +22,7 @@ ################################# # Your name. -author: Blinskot +author: Shadow Larkens # Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. delete-after: True @@ -33,4 +33,4 @@ delete-after: True # Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. # Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. changes: - - rscadd: "You can now alt click to toggle strafing in mechs." + - rscadd: "Added the ability to right click and lower preferences for jobs in the Occupation Menu." diff --git a/icons/effects/beam.dmi b/icons/effects/beam.dmi index 4115b01ef2e..4d0710885fa 100644 Binary files a/icons/effects/beam.dmi and b/icons/effects/beam.dmi differ diff --git a/icons/mob/custom_synthetic.dmi b/icons/mob/custom_synthetic.dmi index e69de29bb2d..7854fabe2bf 100644 Binary files a/icons/mob/custom_synthetic.dmi and b/icons/mob/custom_synthetic.dmi differ diff --git a/icons/mob/custom_synthetic_vr.dmi b/icons/mob/custom_synthetic_vr.dmi new file mode 100644 index 00000000000..8c9cd318f75 Binary files /dev/null and b/icons/mob/custom_synthetic_vr.dmi differ diff --git a/icons/mob/head.dmi b/icons/mob/head.dmi index f241ee11e82..d2be45594c1 100644 Binary files a/icons/mob/head.dmi and b/icons/mob/head.dmi differ diff --git a/icons/mob/human_races/cyberlimbs/cybersolutions/cybersolutions_alt2.dmi b/icons/mob/human_races/cyberlimbs/cybersolutions/cybersolutions_alt2.dmi index d2f9c44e911..a1a7a461229 100644 Binary files a/icons/mob/human_races/cyberlimbs/cybersolutions/cybersolutions_alt2.dmi and b/icons/mob/human_races/cyberlimbs/cybersolutions/cybersolutions_alt2.dmi differ diff --git a/icons/mob/human_races/cyberlimbs/cybersolutions/cybersolutions_alt3.dmi b/icons/mob/human_races/cyberlimbs/cybersolutions/cybersolutions_alt3.dmi new file mode 100644 index 00000000000..d2f9c44e911 Binary files /dev/null and b/icons/mob/human_races/cyberlimbs/cybersolutions/cybersolutions_alt3.dmi differ diff --git a/icons/mob/monitor_icons.dmi b/icons/mob/monitor_icons.dmi index cd7de49fb9a..d25c6b7832b 100644 Binary files a/icons/mob/monitor_icons.dmi and b/icons/mob/monitor_icons.dmi differ diff --git a/icons/mob/screen1_robot.dmi b/icons/mob/screen1_robot.dmi index 993c5b3eb46..ccad7e0f4a7 100644 Binary files a/icons/mob/screen1_robot.dmi and b/icons/mob/screen1_robot.dmi differ diff --git a/icons/mob/species/seromi/back.dmi b/icons/mob/species/seromi/back.dmi index b330228a40c..9de0f3544c8 100644 Binary files a/icons/mob/species/seromi/back.dmi and b/icons/mob/species/seromi/back.dmi differ diff --git a/icons/mob/species/seromi/belt_mirror.dmi b/icons/mob/species/seromi/belt_mirror.dmi index c7a8411c6a8..1038d2ad346 100644 Binary files a/icons/mob/species/seromi/belt_mirror.dmi and b/icons/mob/species/seromi/belt_mirror.dmi differ diff --git a/icons/mob/species/seromi/ears.dmi b/icons/mob/species/seromi/ears.dmi index fb2d0a13f5e..b38829b05f2 100644 Binary files a/icons/mob/species/seromi/ears.dmi and b/icons/mob/species/seromi/ears.dmi differ diff --git a/icons/mob/species/seromi/gloves.dmi b/icons/mob/species/seromi/gloves.dmi index 11ad23815d2..ee6354f8d5f 100644 Binary files a/icons/mob/species/seromi/gloves.dmi and b/icons/mob/species/seromi/gloves.dmi differ diff --git a/icons/mob/species/seromi/head.dmi b/icons/mob/species/seromi/head.dmi index bf346475d3d..849b03718c5 100644 Binary files a/icons/mob/species/seromi/head.dmi and b/icons/mob/species/seromi/head.dmi differ diff --git a/icons/mob/species/seromi/masks.dmi b/icons/mob/species/seromi/masks.dmi index 78bf615f656..83493f851a6 100644 Binary files a/icons/mob/species/seromi/masks.dmi and b/icons/mob/species/seromi/masks.dmi differ diff --git a/icons/mob/species/seromi/shoes.dmi b/icons/mob/species/seromi/shoes.dmi index b4143119e0f..66f18f37bb5 100644 Binary files a/icons/mob/species/seromi/shoes.dmi and b/icons/mob/species/seromi/shoes.dmi differ diff --git a/icons/mob/species/seromi/suit.dmi b/icons/mob/species/seromi/suit.dmi index 638e79027ad..9f6a652c4a5 100644 Binary files a/icons/mob/species/seromi/suit.dmi and b/icons/mob/species/seromi/suit.dmi differ diff --git a/icons/mob/species/seromi/ties.dmi b/icons/mob/species/seromi/ties.dmi index ad23d77e2bf..06eee815b1f 100644 Binary files a/icons/mob/species/seromi/ties.dmi and b/icons/mob/species/seromi/ties.dmi differ diff --git a/icons/mob/species/seromi/uniform.dmi b/icons/mob/species/seromi/uniform.dmi index 63acfcca494..76605857c89 100644 Binary files a/icons/mob/species/seromi/uniform.dmi and b/icons/mob/species/seromi/uniform.dmi differ diff --git a/icons/mob/suit.dmi b/icons/mob/suit.dmi index 82d26fb02e4..5fc30802065 100644 Binary files a/icons/mob/suit.dmi and b/icons/mob/suit.dmi differ diff --git a/icons/obj/aibots.dmi b/icons/obj/aibots.dmi index a7d9e3b79fd..ee7f306e2d8 100644 Binary files a/icons/obj/aibots.dmi and b/icons/obj/aibots.dmi differ diff --git a/icons/obj/cigarettes.dmi b/icons/obj/cigarettes.dmi index e9f17c391d1..922dd125086 100644 Binary files a/icons/obj/cigarettes.dmi and b/icons/obj/cigarettes.dmi differ diff --git a/icons/obj/clothing/hats.dmi b/icons/obj/clothing/hats.dmi index 19d7de134f1..6f8f14c6a22 100644 Binary files a/icons/obj/clothing/hats.dmi and b/icons/obj/clothing/hats.dmi differ diff --git a/icons/obj/clothing/masks.dmi b/icons/obj/clothing/masks.dmi index 998d31b2f8b..195662d14bb 100644 Binary files a/icons/obj/clothing/masks.dmi and b/icons/obj/clothing/masks.dmi differ diff --git a/icons/obj/clothing/species/seromi/suits.dmi b/icons/obj/clothing/species/seromi/suits.dmi index 04572626576..6679ceb22c8 100644 Binary files a/icons/obj/clothing/species/seromi/suits.dmi and b/icons/obj/clothing/species/seromi/suits.dmi differ diff --git a/icons/obj/clothing/species/seromi/uniform.dmi b/icons/obj/clothing/species/seromi/uniform.dmi index e1c6e2f464c..82d4d126da5 100644 Binary files a/icons/obj/clothing/species/seromi/uniform.dmi and b/icons/obj/clothing/species/seromi/uniform.dmi differ diff --git a/icons/obj/clothing/suits.dmi b/icons/obj/clothing/suits.dmi index 0421e0bff6c..5c1f3246d56 100644 Binary files a/icons/obj/clothing/suits.dmi and b/icons/obj/clothing/suits.dmi differ diff --git a/icons/obj/drinks.dmi b/icons/obj/drinks.dmi index acf87534892..0a112657ea0 100644 Binary files a/icons/obj/drinks.dmi and b/icons/obj/drinks.dmi differ diff --git a/icons/obj/ecig.dmi b/icons/obj/ecig.dmi new file mode 100644 index 00000000000..1b6dde8c4bf Binary files /dev/null and b/icons/obj/ecig.dmi differ diff --git a/icons/obj/food.dmi b/icons/obj/food.dmi index efe9039a410..3062f76155f 100644 Binary files a/icons/obj/food.dmi and b/icons/obj/food.dmi differ diff --git a/icons/obj/food_snacks.dmi b/icons/obj/food_snacks.dmi new file mode 100644 index 00000000000..aed34d1ee3d Binary files /dev/null and b/icons/obj/food_snacks.dmi differ diff --git a/icons/obj/janitor.dmi b/icons/obj/janitor.dmi index 3b7f9b4f603..607fef4bc76 100644 Binary files a/icons/obj/janitor.dmi and b/icons/obj/janitor.dmi differ diff --git a/icons/obj/machines/reagent.dmi b/icons/obj/machines/reagent.dmi index d11f34270d5..74954513801 100644 Binary files a/icons/obj/machines/reagent.dmi and b/icons/obj/machines/reagent.dmi differ diff --git a/icons/obj/objects.dmi b/icons/obj/objects.dmi index 5b19f0d43b8..2e213ffcc15 100644 Binary files a/icons/obj/objects.dmi and b/icons/obj/objects.dmi differ diff --git a/icons/obj/terminals.dmi b/icons/obj/terminals.dmi index ab3d80a03c4..659b22ff7a9 100644 Binary files a/icons/obj/terminals.dmi and b/icons/obj/terminals.dmi differ diff --git a/icons/obj/toy.dmi b/icons/obj/toy.dmi index 15f9143b696..21b649006c0 100644 Binary files a/icons/obj/toy.dmi and b/icons/obj/toy.dmi differ diff --git a/icons/obj/trash.dmi b/icons/obj/trash.dmi index 436ebe657d0..4836bae2ac8 100644 Binary files a/icons/obj/trash.dmi and b/icons/obj/trash.dmi differ diff --git a/icons/vore/custom_clothes_vr.dmi b/icons/vore/custom_clothes_vr.dmi index 7fe98dcec50..52ef983f10a 100644 Binary files a/icons/vore/custom_clothes_vr.dmi and b/icons/vore/custom_clothes_vr.dmi differ diff --git a/maps/RandomZLevels/Academy.dmm b/maps/RandomZLevels/Academy.dmm index 0c124407997..fc353d5b2d1 100644 --- a/maps/RandomZLevels/Academy.dmm +++ b/maps/RandomZLevels/Academy.dmm @@ -2975,7 +2975,7 @@ icon_state = "4-8"; pixel_y = 0 }, -/obj/item/weapon/caution, +/obj/item/clothing/suit/caution, /turf/simulated/floor{ icon_state = "green"; dir = 4 diff --git a/maps/RandomZLevels/blackmarketpackers.dmm b/maps/RandomZLevels/blackmarketpackers.dmm index 4515fb775ea..ef10c6addf9 100644 --- a/maps/RandomZLevels/blackmarketpackers.dmm +++ b/maps/RandomZLevels/blackmarketpackers.dmm @@ -3272,7 +3272,7 @@ }, /area/awaymission/BMPship1) "iw" = ( -/obj/item/weapon/caution, +/obj/item/clothing/suit/caution, /turf/simulated/floor/plating/airless, /area/awaymission) "ix" = ( diff --git a/maps/RandomZLevels/zoo.dmm b/maps/RandomZLevels/zoo.dmm index 057c502f5d6..e6fa264d3b0 100644 --- a/maps/RandomZLevels/zoo.dmm +++ b/maps/RandomZLevels/zoo.dmm @@ -353,7 +353,7 @@ "gO" = (/obj/structure/bed/chair{dir = 1},/turf/simulated/shuttle/floor/darkred,/area/awaymission/zoo/syndieship) "gP" = (/turf/simulated/wall,/area/awaymission/zoo) "gQ" = (/obj/machinery/door/airlock/external,/turf/simulated/floor/plating,/area/awaymission/zoo) -"gR" = (/obj/item/weapon/caution,/turf/simulated/floor/plating,/area/awaymission/zoo/pirateship) +"gR" = (/obj/item/clothing/suit/caution,/turf/simulated/floor/plating,/area/awaymission/zoo/pirateship) "gS" = (/obj/machinery/portable_atmospherics/canister/air,/turf/simulated/floor/plating,/area/awaymission/zoo/pirateship) "gT" = (/obj/structure/closet/crate,/obj/item/weapon/spacecash/c10,/obj/item/weapon/spacecash/c200,/turf/simulated/floor/tiled/steel,/area/awaymission/zoo/pirateship) "gU" = (/obj/structure/closet/crate,/obj/item/weapon/spacecash/c10,/turf/simulated/floor/tiled/steel,/area/awaymission/zoo/pirateship) diff --git a/maps/northern_star/polaris-1.dmm b/maps/northern_star/polaris-1.dmm index 8c75ee31edd..5bcaf81860e 100644 --- a/maps/northern_star/polaris-1.dmm +++ b/maps/northern_star/polaris-1.dmm @@ -32,7 +32,7 @@ "aaF" = (/obj/machinery/power/solar{id = "portsolar"; name = "Port Solar Array"},/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/airless{icon_state = "solarpanel"},/area/solar/auxstarboard) "aaG" = (/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/airless,/area/solar/auxstarboard) "aaH" = (/obj/machinery/power/solar{id = "portsolar"; name = "Port Solar Array"},/obj/structure/cable/yellow{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/airless{icon_state = "solarpanel"},/area/solar/auxstarboard) -"aaI" = (/obj/item/weapon/caution/cone,/turf/simulated/floor,/area/maintenance/locker) +"aaI" = (/obj/item/clothing/head/cone,/turf/simulated/floor,/area/maintenance/locker) "aaJ" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/airless,/area/solar/auxstarboard) "aaK" = (/turf/simulated/floor,/area/maintenance/locker) "aaL" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/maintenance/auxsolarstarboard) @@ -1600,7 +1600,7 @@ "aEN" = (/obj/effect/floor_decal/spline/plain{dir = 1},/turf/simulated/floor/water/deep/pool,/area/crew_quarters/pool) "aEO" = (/obj/effect/floor_decal/spline/plain{dir = 5},/turf/simulated/floor/water/deep/pool,/area/crew_quarters/pool) "aEP" = (/obj/structure/bed/chair{dir = 8},/turf/simulated/floor/tiled/freezer,/area/crew_quarters/pool) -"aEQ" = (/obj/item/weapon/caution/cone,/turf/simulated/floor,/area/maintenance/pool) +"aEQ" = (/obj/item/clothing/head/cone,/turf/simulated/floor,/area/maintenance/pool) "aER" = (/obj/effect/decal/cleanable/blood,/turf/simulated/floor,/area/maintenance/pool) "aES" = (/obj/machinery/light/small{dir = 4; pixel_y = 0},/turf/simulated/floor,/area/maintenance/pool) "aET" = (/obj/structure/table/rack,/obj/item/clothing/shoes/magboots,/obj/item/clothing/mask/breath,/obj/item/clothing/suit/space/void/security,/obj/item/clothing/head/helmet/space/void/security,/obj/item/device/suit_cooling_unit,/obj/item/weapon/tank/oxygen,/obj/structure/window/reinforced{dir = 2; health = 1e+006},/obj/structure/window/reinforced{dir = 8},/obj/effect/floor_decal/corner/white{icon_state = "corner_white"; dir = 1},/obj/effect/floor_decal/corner/blue{dir = 8},/obj/machinery/door/window/brigdoor/eastright{name = "EVA Suit"},/turf/simulated/floor/tiled/dark,/area/security/armoury) @@ -2414,7 +2414,7 @@ "aUv" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/crew_quarters/recreation_area_hallway) "aUw" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/crew_quarters/recreation_area_hallway) "aUx" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/crew_quarters/recreation_area_hallway) -"aUy" = (/obj/item/weapon/caution/cone,/turf/simulated/floor/tiled/dark,/area/crew_quarters/recreation_area_hallway) +"aUy" = (/obj/item/clothing/head/cone,/turf/simulated/floor/tiled/dark,/area/crew_quarters/recreation_area_hallway) "aUz" = (/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/obj/machinery/light_switch{pixel_x = -26; pixel_y = 0},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/tiled,/area/storage/tools) "aUA" = (/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -21},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/tiled,/area/storage/tools) "aUB" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/tiled,/area/storage/tools) @@ -5607,7 +5607,7 @@ "cdQ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/hallway/secondary/medical_emergency_hallway) "cdR" = (/obj/machinery/atmospherics/unary/vent_scrubber/on,/obj/effect/floor_decal/corner/pink{dir = 9},/turf/simulated/floor/tiled,/area/hallway/secondary/medical_emergency_hallway) "cdS" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/item/device/radio/intercom{dir = 4; name = "Station Intercom (General)"; pixel_x = 26},/obj/effect/floor_decal/corner/pink{dir = 6},/turf/simulated/floor/tiled,/area/hallway/secondary/medical_emergency_hallway) -"cdT" = (/obj/item/weapon/caution/cone,/turf/simulated/floor,/area/maintenance/medbay_aft) +"cdT" = (/obj/item/clothing/head/cone,/turf/simulated/floor,/area/maintenance/medbay_aft) "cdU" = (/obj/item/weapon/broken_bottle,/turf/simulated/floor,/area/maintenance/medbay_aft) "cdV" = (/obj/structure/table/woodentable,/obj/item/weapon/material/ashtray/plastic,/obj/item/weapon/cigbutt/cigarbutt,/obj/random/maintenance/clean,/obj/random/maintenance/clean,/turf/simulated/floor,/area/maintenance/medbay_aft) "cdW" = (/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "medbayquar"; name = "Medbay Emergency Lockdown Shutters"; opacity = 0},/turf/simulated/floor,/area/maintenance/medbay_aft) @@ -8515,7 +8515,7 @@ "dhM" = (/obj/machinery/light,/turf/simulated/floor/tiled,/area/hallway/secondary/entry/starboard) "dhN" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor/tiled,/area/hallway/secondary/entry/starboard) "dhO" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor/tiled,/area/hallway/secondary/entry/starboard) -"dhP" = (/obj/machinery/firealarm{dir = 1; pixel_y = -24},/obj/item/weapon/caution/cone,/turf/simulated/floor/tiled/dark,/area/hallway/secondary/entry/starboard) +"dhP" = (/obj/machinery/firealarm{dir = 1; pixel_y = -24},/obj/item/clothing/head/cone,/turf/simulated/floor/tiled/dark,/area/hallway/secondary/entry/starboard) "dhQ" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/turf/simulated/floor/tiled,/area/vacant/vacant_site2) "dhR" = (/obj/item/weapon/stool/padded,/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/tiled,/area/vacant/vacant_site2) "dhS" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/tiled,/area/vacant/vacant_site2) @@ -9017,7 +9017,7 @@ "dru" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only,/obj/structure/window/reinforced{dir = 8},/obj/structure/sign/securearea{desc = "A warning sign which reads 'KEEP CLEAR OF DOCKING AREA'."; name = "KEEP CLEAR: DOCKING AREA"; pixel_y = 0},/turf/simulated/floor/plating,/area/space) "drv" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/hallway/secondary/entry/D3) "drw" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/hallway/secondary/entry/D3) -"drx" = (/obj/machinery/atmospherics/pipe/simple/hidden,/obj/effect/floor_decal/industrial/warning/corner{icon_state = "warningcorner"; dir = 8},/obj/machinery/door/firedoor/border_only,/obj/item/weapon/caution/cone,/turf/simulated/floor/tiled,/area/hallway/secondary/entry/D3) +"drx" = (/obj/machinery/atmospherics/pipe/simple/hidden,/obj/effect/floor_decal/industrial/warning/corner{icon_state = "warningcorner"; dir = 8},/obj/machinery/door/firedoor/border_only,/obj/item/clothing/head/cone,/turf/simulated/floor/tiled,/area/hallway/secondary/entry/D3) "dry" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/tiled,/area/hallway/secondary/entry/D3) "drz" = (/obj/effect/floor_decal/industrial/warning/corner,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/tiled,/area/hallway/secondary/entry/D3) "drA" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/hallway/secondary/entry/D3) @@ -9079,7 +9079,7 @@ "dsE" = (/obj/effect/floor_decal/industrial/warning/cee{icon_state = "warningcee"; dir = 8},/turf/simulated/floor/tiled,/area/hallway/secondary/entry/D3) "dsF" = (/obj/machinery/light/small,/obj/effect/floor_decal/industrial/warning/cee{icon_state = "warningcee"; dir = 4},/turf/simulated/floor/tiled,/area/hallway/secondary/entry/D3) "dsG" = (/obj/effect/floor_decal/industrial/hatch/yellow,/obj/machinery/door/airlock/glass_external{icon_state = "door_locked"; locked = 1; name = "Arrival Airlock"},/obj/item/tape/engineering,/turf/simulated/floor/tiled/dark,/area/hallway/secondary/entry/D3) -"dsH" = (/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 8; icon_state = "map"},/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 8},/obj/item/weapon/caution/cone,/turf/simulated/floor/tiled,/area/hallway/secondary/entry/D3) +"dsH" = (/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 8; icon_state = "map"},/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 8},/obj/item/clothing/head/cone,/turf/simulated/floor/tiled,/area/hallway/secondary/entry/D3) "dsI" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden{icon_state = "intact"; dir = 4},/turf/simulated/floor/tiled,/area/hallway/secondary/entry/D3) "dsJ" = (/obj/effect/floor_decal/industrial/warning{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden{icon_state = "intact"; dir = 4},/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "dock_three_fore_airlock"; name = "interior access button"; pixel_x = 26; pixel_y = 26; req_one_access = list(13)},/turf/simulated/floor/tiled,/area/hallway/secondary/entry/D3) "dsK" = (/obj/machinery/atmospherics/pipe/simple/hidden{icon_state = "intact"; dir = 4},/obj/effect/floor_decal/industrial/hatch/yellow,/obj/machinery/door/airlock/glass_external{frequency = 1379; icon_state = "door_locked"; id_tag = "dock_three_fore_inner"; locked = 1; name = "Dock Three Internal Access"; req_access = list(13)},/turf/simulated/floor/tiled/dark,/area/hallway/secondary/entry/D3) @@ -9127,7 +9127,7 @@ "dtA" = (/obj/machinery/atmospherics/pipe/simple/hidden,/obj/effect/floor_decal/industrial/warning/corner{dir = 4},/turf/simulated/floor/tiled,/area/hallway/secondary/entry/D2) "dtB" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/hallway/secondary/entry/D2) "dtC" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/hallway/secondary/entry/D3) -"dtD" = (/obj/machinery/atmospherics/pipe/simple/hidden,/obj/effect/floor_decal/industrial/warning/corner{dir = 1},/obj/item/weapon/caution/cone,/turf/simulated/floor/tiled,/area/hallway/secondary/entry/D3) +"dtD" = (/obj/machinery/atmospherics/pipe/simple/hidden,/obj/effect/floor_decal/industrial/warning/corner{dir = 1},/obj/item/clothing/head/cone,/turf/simulated/floor/tiled,/area/hallway/secondary/entry/D3) "dtE" = (/obj/effect/floor_decal/industrial/warning{dir = 4},/turf/simulated/floor/tiled,/area/hallway/secondary/entry/D3) "dtF" = (/obj/effect/floor_decal/industrial/hatch/yellow,/obj/machinery/door/airlock/glass_external{frequency = 1379; icon_state = "door_locked"; id_tag = "dock_three_fore_inner"; locked = 1; name = "Dock Three Internal Access"; req_access = list(13)},/turf/simulated/floor/tiled/dark,/area/hallway/secondary/entry/D3) "dtG" = (/obj/effect/floor_decal/industrial/loading{dir = 4},/obj/machinery/light/small,/obj/machinery/atmospherics/pipe/simple/hidden{dir = 5; icon_state = "intact"},/turf/simulated/floor/tiled,/area/hallway/secondary/entry/D3) @@ -9139,7 +9139,7 @@ "dtM" = (/obj/effect/floor_decal/industrial/hatch/yellow,/obj/machinery/door/airlock/glass_external{frequency = 1379; icon_state = "door_locked"; id_tag = "dock_four_fore_inner"; locked = 1; name = "Dock Four Internal Access"; req_access = list(13)},/turf/simulated/floor/tiled/dark,/area/hallway/secondary/entry/D4) "dtN" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden,/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 8},/turf/simulated/floor/tiled,/area/hallway/secondary/entry/D4) "dtO" = (/obj/machinery/vending/coffee,/turf/simulated/floor/tiled/dark,/area/hallway/secondary/entry/D4) -"dtP" = (/obj/item/weapon/caution/cone,/turf/simulated/floor,/area/maintenance/atmos_control) +"dtP" = (/obj/item/clothing/head/cone,/turf/simulated/floor,/area/maintenance/atmos_control) "dtQ" = (/obj/machinery/drone_fabricator/derelict,/turf/simulated/floor/plating,/area/engineering/drone_fabrication) "dtR" = (/obj/item/weapon/storage/box/matches,/obj/item/weapon/storage/fancy/cigarettes,/obj/item/weapon/deck/cards,/obj/structure/table/steel,/obj/random/maintenance/engineering,/turf/simulated/floor/plating,/area/engineering/drone_fabrication) "dtS" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/camera/network/engineering{c_tag = "ENG - Hallway Aft"; dir = 8},/turf/simulated/floor/tiled,/area/engineering) @@ -9337,7 +9337,7 @@ "dxC" = (/obj/effect/floor_decal/industrial/loading{icon_state = "loadingarea"; dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 10; icon_state = "intact"},/obj/machinery/light/small{dir = 1},/turf/simulated/floor/tiled,/area/hallway/secondary/entry/D2) "dxD" = (/obj/effect/floor_decal/industrial/hatch/yellow,/obj/machinery/door/airlock/glass_external{frequency = 1380; icon_state = "door_locked"; id_tag = "escape_dock_south_starboard_inner"; locked = 1; name = "Docking Port Airlock"; req_access = list(13)},/turf/simulated/floor/tiled/dark,/area/hallway/secondary/entry/D2) "dxE" = (/obj/machinery/atmospherics/pipe/simple/hidden,/obj/effect/floor_decal/industrial/warning/corner,/turf/simulated/floor/tiled,/area/hallway/secondary/entry/D2) -"dxF" = (/obj/machinery/atmospherics/pipe/simple/hidden,/obj/item/weapon/caution/cone,/obj/effect/floor_decal/industrial/warning/corner{icon_state = "warningcorner"; dir = 8},/turf/simulated/floor/tiled,/area/hallway/secondary/entry/D3) +"dxF" = (/obj/machinery/atmospherics/pipe/simple/hidden,/obj/item/clothing/head/cone,/obj/effect/floor_decal/industrial/warning/corner{icon_state = "warningcorner"; dir = 8},/turf/simulated/floor/tiled,/area/hallway/secondary/entry/D3) "dxG" = (/obj/effect/floor_decal/industrial/hatch/yellow,/obj/machinery/door/airlock/glass_external{frequency = 1379; icon_state = "door_locked"; id_tag = "dock_three_mid_inner"; locked = 1; name = "Dock Three Internal Access"; req_access = list(13)},/turf/simulated/floor/tiled/dark,/area/hallway/secondary/entry/D3) "dxH" = (/obj/machinery/light/small{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 6},/turf/simulated/floor/tiled,/area/hallway/secondary/entry/D3) "dxI" = (/obj/effect/floor_decal/industrial/loading{icon_state = "loadingarea"; dir = 8},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 8; frequency = 1379; id_tag = "dock_three_mid_pump"},/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "dock_three_mid_sensor"; pixel_x = 0; pixel_y = 25},/turf/simulated/floor/tiled,/area/hallway/secondary/entry/D3) @@ -9397,7 +9397,7 @@ "dyK" = (/obj/effect/floor_decal/industrial/hatch/yellow,/obj/machinery/shield_diffuser,/obj/machinery/door/airlock/external{icon_state = "door_locked"; locked = 1; name = "Arrival Airlock"},/turf/simulated/floor/tiled/dark,/area/hallway/secondary/entry/D3) "dyL" = (/obj/machinery/light/small{dir = 1},/obj/effect/floor_decal/industrial/warning/cee{icon_state = "warningcee"; dir = 4},/turf/simulated/floor/tiled,/area/hallway/secondary/entry/D3) "dyM" = (/obj/effect/floor_decal/industrial/hatch/yellow,/obj/item/tape/engineering,/obj/machinery/door/airlock/glass_external{icon_state = "door_locked"; locked = 1; name = "Arrival Airlock"},/turf/simulated/floor/tiled/dark,/area/hallway/secondary/entry/D3) -"dyN" = (/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 8; icon_state = "map"},/obj/item/weapon/caution/cone,/obj/effect/floor_decal/industrial/warning{dir = 8},/turf/simulated/floor/tiled,/area/hallway/secondary/entry/D3) +"dyN" = (/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 8; icon_state = "map"},/obj/item/clothing/head/cone,/obj/effect/floor_decal/industrial/warning{dir = 8},/turf/simulated/floor/tiled,/area/hallway/secondary/entry/D3) "dyO" = (/obj/effect/floor_decal/industrial/warning{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden{icon_state = "intact"; dir = 4},/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "dock_three_mid_airlock"; name = "interior access button"; pixel_x = 26; pixel_y = -26; req_one_access = list(13)},/turf/simulated/floor/tiled,/area/hallway/secondary/entry/D3) "dyP" = (/obj/machinery/atmospherics/pipe/simple/hidden{icon_state = "intact"; dir = 4},/obj/effect/floor_decal/industrial/hatch/yellow,/obj/machinery/door/airlock/glass_external{frequency = 1379; icon_state = "door_locked"; id_tag = "dock_three_mid_inner"; locked = 1; name = "Dock Three Internal Access"; req_access = list(13)},/turf/simulated/floor/tiled/dark,/area/hallway/secondary/entry/D3) "dyQ" = (/obj/machinery/atmospherics/pipe/manifold/hidden,/obj/effect/floor_decal/industrial/loading{dir = 4},/obj/machinery/embedded_controller/radio/airlock/airlock_controller{frequency = 1379; id_tag = "dock_three_mid_airlock"; name = "Airlock Console"; pixel_y = -30; req_access = list(13); tag_airpump = "dock_three_mid_pump"; tag_chamber_sensor = "dock_three_mid_sensor"; tag_exterior_door = "dock_three_mid_outer"; tag_interior_door = "dock_three_mid_inner"},/turf/simulated/floor/tiled,/area/hallway/secondary/entry/D3) @@ -9449,7 +9449,7 @@ "dzK" = (/obj/machinery/atmospherics/portables_connector{dir = 8},/obj/machinery/portable_atmospherics/canister/air/airlock,/obj/effect/floor_decal/industrial/outline/yellow,/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0; pixel_y = -32},/turf/simulated/floor/tiled/steel,/area/engineering/aft_hallway) "dzL" = (/obj/effect/floor_decal/industrial/warning/corner{dir = 4},/turf/simulated/floor/tiled,/area/hallway/secondary/entry/D1) "dzM" = (/obj/effect/floor_decal/industrial/warning/corner{dir = 1},/turf/simulated/floor/tiled,/area/hallway/secondary/entry/D2) -"dzN" = (/obj/machinery/atmospherics/pipe/simple/hidden,/obj/item/weapon/caution/cone,/obj/effect/floor_decal/industrial/warning/corner{dir = 1},/turf/simulated/floor/tiled,/area/hallway/secondary/entry/D3) +"dzN" = (/obj/machinery/atmospherics/pipe/simple/hidden,/obj/item/clothing/head/cone,/obj/effect/floor_decal/industrial/warning/corner{dir = 1},/turf/simulated/floor/tiled,/area/hallway/secondary/entry/D3) "dzO" = (/obj/effect/floor_decal/industrial/warning/corner{dir = 4},/turf/simulated/floor/tiled,/area/hallway/secondary/entry/D3) "dzP" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only,/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/hallway/secondary/entry/D4) "dzQ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/hallway/secondary/entry/D4) diff --git a/maps/southern_cross/southern_cross-1.dmm b/maps/southern_cross/southern_cross-1.dmm index 1bf367399d3..4068595924c 100644 --- a/maps/southern_cross/southern_cross-1.dmm +++ b/maps/southern_cross/southern_cross-1.dmm @@ -811,7 +811,7 @@ "apE" = (/obj/structure/frame/computer,/turf/simulated/floor/tiled,/area/hangar/onecontrol) "apF" = (/obj/machinery/atmospherics/unary/vent_pump/on,/obj/machinery/firealarm{dir = 4; pixel_x = 24},/turf/simulated/floor/tiled,/area/hangar/onecontrol) "apG" = (/obj/structure/disposalpipe/up,/obj/machinery/atmospherics/pipe/zpipe/up/scrubbers,/obj/machinery/atmospherics/pipe/zpipe/up/supply,/obj/structure/cable{d2 = 2; icon_state = "0-2"; pixel_y = 0},/obj/structure/cable{d1 = 16; d2 = 0; icon_state = "16-0"},/turf/simulated/floor/plating,/area/maintenance/firstdeck/foreport) -"apH" = (/obj/item/weapon/caution/cone,/turf/simulated/floor,/area/maintenance/firstdeck/foreport) +"apH" = (/obj/item/clothing/head/cone,/turf/simulated/floor,/area/maintenance/firstdeck/foreport) "apI" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/catwalk,/turf/simulated/floor/plating,/area/maintenance/firstdeck/foreport) "apJ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/alarm{dir = 8; pixel_x = 22; pixel_y = 0},/obj/structure/catwalk,/turf/simulated/floor/plating,/area/maintenance/firstdeck/foreport) "apK" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/effect/floor_decal/borderfloor{dir = 8},/obj/effect/floor_decal/corner/green/border{dir = 8},/obj/effect/floor_decal/borderfloor/corner2{dir = 10},/obj/effect/floor_decal/corner/green/bordercorner2{dir = 10},/turf/simulated/floor/tiled,/area/hallway/primary/firstdeck/fpcenter) diff --git a/maps/submaps/engine_submaps/engine_tesla.dmm b/maps/submaps/engine_submaps/engine_tesla.dmm index 05e3a7d202e..0cbbf909669 100644 --- a/maps/submaps/engine_submaps/engine_tesla.dmm +++ b/maps/submaps/engine_submaps/engine_tesla.dmm @@ -24,7 +24,9 @@ /obj/machinery/atmospherics/portables_connector{ dir = 4 }, -/obj/machinery/portable_atmospherics/canister/air/airlock, +/obj/machinery/portable_atmospherics/canister/air/airlock{ + start_pressure = 4559.63 + }, /turf/simulated/floor, /area/engineering/engine_gas) "ah" = ( diff --git a/maps/submaps/surface_submaps/mountains/mountains.dm b/maps/submaps/surface_submaps/mountains/mountains.dm index e36bb1a5bae..f0e09d723d2 100644 --- a/maps/submaps/surface_submaps/mountains/mountains.dm +++ b/maps/submaps/surface_submaps/mountains/mountains.dm @@ -343,7 +343,7 @@ cost = 20 fixed_orientation = TRUE -/datum/map_template/surface/mountains/deep/excavation1 +/datum/map_template/surface/mountains/normal/excavation1 //VOREStation Edit name = "Excavation Site" desc = "An abandoned mining site." mappath = 'maps/submaps/surface_submaps/mountains/excavation1.dmm' diff --git a/maps/submaps/surface_submaps/mountains/quarantineshuttle.dmm b/maps/submaps/surface_submaps/mountains/quarantineshuttle.dmm index 7da857ef053..7ee0f3cfa81 100644 --- a/maps/submaps/surface_submaps/mountains/quarantineshuttle.dmm +++ b/maps/submaps/surface_submaps/mountains/quarantineshuttle.dmm @@ -1,6 +1,6 @@ "aa" = (/turf/template_noop,/area/template_noop) "ab" = (/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/qShuttle) -"ac" = (/obj/item/weapon/caution/cone,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/qShuttle) +"ac" = (/obj/item/clothing/head/cone,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/qShuttle) "ad" = (/turf/simulated/shuttle/wall,/area/submap/cave/qShuttle) "ae" = (/obj/structure/inflatable,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/qShuttle) "af" = (/obj/structure/inflatable/door,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/qShuttle) diff --git a/maps/submaps/surface_submaps/plains/hotspring.dmm b/maps/submaps/surface_submaps/plains/hotspring.dmm new file mode 100644 index 00000000000..70f5fe2d855 --- /dev/null +++ b/maps/submaps/surface_submaps/plains/hotspring.dmm @@ -0,0 +1,61 @@ +"a" = (/turf/template_noop,/area/submap/hotspring) +"c" = (/obj/structure/bonfire/sifwood,/turf/simulated/floor/outdoors/dirt,/area/submap/hotspring) +"d" = (/obj/effect/effect/steam,/turf/simulated/floor/water/shoreline/corner{dir = 4},/area/submap/hotspring) +"e" = (/obj/structure/window/reinforced{dir = 8; health = 1e+006},/obj/structure/loot_pile/maint/trash,/turf/simulated/floor/outdoors/grass/sif,/area/submap/hotspring) +"f" = (/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/wood/sif,/area/submap/hotspring) +"g" = (/turf/simulated/floor/outdoors/mud,/area/submap/hotspring) +"h" = (/obj/structure/window/reinforced{dir = 8; health = 1e+006},/turf/simulated/floor/outdoors/grass/sif,/area/submap/hotspring) +"i" = (/obj/random/trash,/turf/simulated/floor/outdoors/grass/sif,/area/submap/hotspring) +"j" = (/obj/structure/table/rack,/obj/item/weapon/storage/fancy/candle_box,/obj/item/weapon/flame/lighter/random{pixel_x = 7},/obj/item/weapon/storage/fancy/candle_box{pixel_x = -6},/obj/item/weapon/storage/firstaid{pixel_x = 4; pixel_y = -6},/obj/item/weapon/wrapping_paper,/turf/simulated/floor/wood/sif,/area/submap/hotspring) +"k" = (/obj/effect/effect/steam,/obj/effect/map_effect/interval/effect_emitter/steam,/turf/simulated/floor/water,/area/submap/hotspring) +"m" = (/obj/effect/effect/steam,/turf/simulated/floor/water/shoreline/corner,/area/submap/hotspring) +"n" = (/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/wood/sif,/area/submap/hotspring) +"o" = (/obj/structure/table/woodentable,/obj/item/weapon/material/harpoon,/obj/item/pizzabox/vegetable,/turf/simulated/floor/wood/sif,/area/submap/hotspring) +"p" = (/obj/effect/effect/steam,/turf/simulated/floor/water/shoreline{dir = 1},/area/submap/hotspring) +"r" = (/obj/item/weapon/material/shard,/obj/structure/bed/chair{dir = 1},/turf/simulated/floor/wood/sif,/area/submap/hotspring) +"s" = (/obj/random/junk,/turf/simulated/floor/outdoors/dirt,/area/submap/hotspring) +"t" = (/obj/structure/table/bench/wooden,/turf/simulated/floor/outdoors/dirt,/area/submap/hotspring) +"u" = (/obj/random/junk,/turf/simulated/floor/outdoors/mud,/area/submap/hotspring) +"v" = (/obj/effect/effect/steam,/turf/simulated/floor/water/shoreline/corner{dir = 1},/area/submap/hotspring) +"w" = (/obj/structure/closet/crate/bin,/turf/simulated/floor/wood/sif/broken,/area/submap/hotspring) +"x" = (/obj/structure/table/woodentable,/obj/item/trash/candle,/turf/simulated/floor/wood/sif,/area/submap/hotspring) +"z" = (/obj/effect/effect/steam,/turf/simulated/floor/water/shoreline/corner{dir = 8},/area/submap/hotspring) +"A" = (/obj/item/weapon/material/shard,/turf/template_noop,/area/submap/hotspring) +"C" = (/obj/effect/effect/steam,/turf/simulated/floor/water/shoreline{dir = 8},/area/submap/hotspring) +"D" = (/obj/structure/window/reinforced{dir = 4; health = 1e+006},/turf/template_noop,/area/submap/hotspring) +"E" = (/obj/effect/effect/steam,/turf/simulated/floor/water/shoreline,/area/submap/hotspring) +"F" = (/turf/simulated/floor/outdoors/dirt,/area/submap/hotspring) +"H" = (/obj/random/trash,/turf/simulated/floor/outdoors/mud,/area/submap/hotspring) +"I" = (/obj/effect/effect/steam,/turf/simulated/floor/water/shoreline{dir = 9},/area/submap/hotspring) +"J" = (/obj/structure/simple_door/sifwood,/turf/simulated/floor/wood/sif,/area/submap/hotspring) +"K" = (/turf/simulated/floor/outdoors/grass/sif,/area/submap/hotspring) +"L" = (/obj/item/weapon/inflatable_duck,/obj/effect/effect/steam,/turf/simulated/floor/water/shoreline,/area/submap/hotspring) +"M" = (/obj/random/junk,/obj/random/junk,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/wood/sif/broken,/area/submap/hotspring) +"N" = (/turf/simulated/floor/outdoors/rocks,/area/submap/hotspring) +"O" = (/obj/structure/loot_pile/maint/trash,/turf/template_noop,/area/submap/hotspring) +"P" = (/obj/structure/window/reinforced{dir = 4; health = 1e+006},/obj/item/weapon/material/shard{pixel_x = 4; pixel_y = 7},/turf/template_noop,/area/submap/hotspring) +"R" = (/obj/structure/window/reinforced{dir = 8; health = 1e+006},/obj/item/weapon/material/shard,/obj/structure/loot_pile/maint/trash,/turf/template_noop,/area/submap/hotspring) +"T" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/wood/sif/broken,/area/submap/hotspring) +"U" = (/obj/structure/table/rack,/obj/item/clothing/under/swimsuit/striped,/obj/item/clothing/under/swimsuit/stripper/stripper_pink,/turf/simulated/floor/wood/sif,/area/submap/hotspring) +"V" = (/obj/effect/effect/steam,/turf/simulated/floor/water/shoreline{dir = 6},/area/submap/hotspring) +"X" = (/obj/random/junk,/obj/random/junk,/turf/simulated/floor/outdoors/dirt,/area/submap/hotspring) +"Y" = (/turf/simulated/wall/log_sif,/area/submap/hotspring) +"Z" = (/obj/item/weapon/material/shard,/obj/item/weapon/material/shard{pixel_x = 5},/turf/template_noop,/area/submap/hotspring) + +(1,1,1) = {" +DYYYYYRaaaaFaaa +DoxwjUZaaaKFaga +ArMnfTeKKKFKKKa +PYYYJYhtttuFFKa +aOKXggFggHgNgFK +aaKKFggNmEvggKa +aatKsgmLVIdgsKa +aFcFggCkIdNFKia +aatKFgzpdgFKKKa +aaKFugNgggsKKFg +aaKKFtttFgFKFKa +aaKKiKKKKFKKFKa +aaKKFKFKKKKFKKa +aKgFaagFaaaaaKa +aaaaaaaaaaaaaaa +"} diff --git a/maps/submaps/surface_submaps/plains/lonehome.dmm b/maps/submaps/surface_submaps/plains/lonehome.dmm new file mode 100644 index 00000000000..49d75bc6240 --- /dev/null +++ b/maps/submaps/surface_submaps/plains/lonehome.dmm @@ -0,0 +1,184 @@ +"at" = (/obj/structure/bed/chair/sofa/black/right{dir = 1},/turf/simulated/floor/wood,/area/submap/lonehome) +"au" = (/obj/item/organ/internal/lungs/vox,/obj/item/weapon/beartrap/hunting{anchored = 1; deployed = 1},/obj/structure/curtain/black,/obj/random/junk,/obj/random/junk,/obj/random/junk,/turf/simulated/floor,/area/submap/lonehome) +"aw" = (/obj/structure/flora/tree/sif,/turf/template_noop,/area/submap/lonehome) +"aI" = (/obj/structure/window/reinforced{dir = 8; health = 1e+006},/obj/structure/flora/pottedplant/fern{pixel_y = 12},/obj/structure/table/bench/wooden,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/wood,/area/submap/lonehome) +"aK" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor,/area/submap/lonehome) +"bb" = (/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/wood/broken,/area/submap/lonehome) +"ck" = (/obj/machinery/light/small{dir = 8},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/wood,/area/submap/lonehome) +"cn" = (/obj/machinery/light{dir = 8},/obj/item/weapon/paper/courtroom,/obj/item/weapon/paper/courtroom,/obj/item/weapon/paper_bin,/obj/structure/table/wooden_reinforced,/turf/simulated/floor/wood,/area/submap/lonehome) +"cE" = (/obj/structure/table/marble,/obj/item/organ/internal/brain/grey,/obj/item/weapon/material/knife/plastic,/turf/simulated/floor,/area/submap/lonehome) +"cS" = (/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/wood,/area/submap/lonehome) +"dR" = (/obj/item/weapon/paper{info = "Seems to be filled with odd runes drawn with blood"; name = "Blood stained paper"},/turf/simulated/floor/carpet/sblucarpet,/area/submap/lonehome) +"ew" = (/obj/machinery/light/small{dir = 4},/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor,/area/submap/lonehome) +"eL" = (/obj/machinery/button/windowtint{id = "h_master"},/turf/simulated/wall/wood,/area/submap/lonehome) +"fl" = (/obj/structure/loot_pile/maint/trash,/turf/template_noop,/area/submap/lonehome) +"gn" = (/obj/structure/window/reinforced{dir = 4; health = 1e+006},/turf/template_noop,/area/submap/lonehome) +"gI" = (/obj/structure/table/rack,/obj/item/weapon/material/knife/ritual,/obj/structure/curtain/open/bed,/obj/item/clothing/under/suit_jacket/really_black,/obj/item/clothing/under/suit_jacket/navy,/obj/item/clothing/head/soft/solgov/veteranhat,/turf/simulated/floor/wood,/area/submap/lonehome) +"hh" = (/obj/item/weapon/reagent_containers/food/condiment/small/peppermill,/obj/item/weapon/pen,/turf/simulated/floor/wood,/area/submap/lonehome) +"hq" = (/obj/structure/table/bench/marble,/obj/structure/window/reinforced/polarized{id = "h_master"},/obj/structure/flora/pottedplant/dead{pixel_y = 7},/turf/simulated/floor/wood,/area/submap/lonehome) +"hH" = (/obj/structure/table/marble,/obj/item/weapon/material/sharpeningkit,/obj/item/weapon/reagent_containers/dropper,/turf/simulated/floor/tiled/white,/area/submap/lonehome) +"hK" = (/obj/structure/bed/chair/wood{dir = 1},/obj/structure/window/reinforced/polarized{dir = 4; id = "h_kitchen"},/turf/simulated/floor/wood,/area/submap/lonehome) +"ii" = (/obj/random/junk,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/wood,/area/submap/lonehome) +"ip" = (/obj/item/weapon/pen,/turf/simulated/floor/wood,/area/submap/lonehome) +"iw" = (/turf/simulated/floor/wood/broken,/area/submap/lonehome) +"iQ" = (/obj/structure/table/marble,/obj/item/weapon/material/knife/butch,/obj/item/weapon/material/kitchen/rollingpin,/turf/simulated/floor/tiled/white,/area/submap/lonehome) +"jt" = (/obj/structure/fence/corner{dir = 8},/turf/simulated/floor/outdoors/grass/heavy,/area/submap/lonehome) +"jy" = (/obj/item/weapon/material/shard,/obj/item/weapon/material/shard{pixel_x = 5; pixel_y = 10},/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/wood,/area/submap/lonehome) +"jH" = (/obj/item/weapon/material/kitchen/utensil/spoon{pixel_x = 2},/turf/simulated/floor/wood,/area/submap/lonehome) +"jK" = (/obj/structure/bed/chair/wood,/turf/simulated/floor/wood,/area/submap/lonehome) +"kg" = (/obj/structure/table/marble,/obj/item/weapon/material/kitchen/utensil/spoon,/turf/simulated/floor/tiled/white,/area/submap/lonehome) +"kn" = (/obj/structure/bed/chair/wood,/obj/machinery/button/windowtint{id = "h_kitchen"},/obj/structure/window/reinforced/polarized{dir = 4; id = "h_kitchen"},/turf/simulated/floor/wood,/area/submap/lonehome) +"ks" = (/obj/item/weapon/photo,/obj/item/weapon/photo{pixel_x = 4},/obj/structure/table/bench/wooden,/turf/simulated/floor/wood,/area/submap/lonehome) +"kT" = (/obj/machinery/light/small{dir = 1},/obj/structure/bed/padded,/obj/item/weapon/book/custom_library/fiction/truelovehathmyheart,/obj/item/weapon/bedsheet/clown,/turf/simulated/floor/wood,/area/submap/lonehome) +"kU" = (/obj/item/weapon/chainsaw,/obj/item/weapon/storage/box/lights/mixed,/obj/item/weapon/extinguisher,/obj/item/weapon/storage/toolbox/mechanical,/obj/structure/table/rack,/turf/simulated/floor,/area/submap/lonehome) +"ld" = (/obj/machinery/power/port_gen/pacman,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor,/area/submap/lonehome) +"lz" = (/obj/item/weapon/reagent_containers/glass/rag,/obj/item/clothing/gloves/ring/engagement,/obj/structure/table/wooden_reinforced,/turf/simulated/floor/wood,/area/submap/lonehome) +"lB" = (/obj/machinery/button/windowtint{id = "h_kitchen"},/obj/item/trash/plate,/obj/structure/table/sifwooden_reinforced,/obj/structure/window/reinforced/polarized{dir = 4; id = "h_kitchen"},/turf/simulated/floor/wood,/area/submap/lonehome) +"lJ" = (/obj/item/device/tape,/obj/structure/table/wooden_reinforced,/turf/simulated/floor/wood,/area/submap/lonehome) +"lS" = (/obj/item/organ/internal/liver,/obj/random/trash,/turf/simulated/floor,/area/submap/lonehome) +"ma" = (/turf/simulated/wall/wood,/area/submap/lonehome) +"mn" = (/obj/item/clothing/mask/muzzle,/obj/random/trash,/turf/simulated/floor,/area/submap/lonehome) +"na" = (/mob/living/simple_mob/animal/passive/cat/bones{desc = "A very odd behaved cat, their scratched name tag reads 'Felix'. They look very malnourished."; name = "Felix"},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/wood,/area/submap/lonehome) +"ni" = (/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor,/area/submap/lonehome) +"nz" = (/obj/item/device/flashlight{pixel_x = 2; pixel_y = 2},/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor,/area/submap/lonehome) +"nD" = (/obj/structure/bed/chair/sofa/black,/turf/simulated/floor/wood,/area/submap/lonehome) +"nL" = (/obj/machinery/appliance/cooker/oven,/turf/simulated/floor/tiled/white,/area/submap/lonehome) +"nT" = (/obj/item/stack/cable_coil,/turf/simulated/floor/wood/broken,/area/submap/lonehome) +"ox" = (/obj/structure/closet/cabinet,/obj/item/weapon/storage/wallet/random,/obj/item/weapon/towel/random,/obj/item/weapon/melee/umbrella/random,/obj/random/ammo,/obj/random/cigarettes,/obj/random/contraband,/obj/random/junk,/obj/random/maintenance/security,/obj/random/maintenance/medical,/obj/random/maintenance/medical,/turf/simulated/floor/wood,/area/submap/lonehome) +"oS" = (/obj/structure/closet/cabinet,/obj/random/tech_supply/component,/obj/random/tech_supply/component,/obj/random/tech_supply/component,/obj/random/tech_supply/component,/obj/random/tech_supply/component,/obj/random/toolbox,/obj/random/toolbox,/turf/simulated/floor/wood,/area/submap/lonehome) +"oZ" = (/obj/structure/bed/chair/sofa/black/left,/turf/simulated/floor/wood,/area/submap/lonehome) +"pb" = (/obj/structure/fence/cut/large{dir = 8},/turf/template_noop,/area/submap/lonehome) +"po" = (/obj/structure/sign/periodic,/turf/simulated/wall/wood,/area/submap/lonehome) +"pX" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/wood/broken,/area/submap/lonehome) +"qa" = (/obj/structure/fence,/turf/simulated/floor/outdoors/grass/heavy,/area/submap/lonehome) +"qi" = (/obj/structure/table/marble,/obj/machinery/chemical_dispenser/bar_alc/full,/turf/simulated/floor/tiled/white,/area/submap/lonehome) +"qk" = (/obj/structure/table/marble,/obj/machinery/light{dir = 1},/obj/machinery/microwave,/turf/simulated/floor/tiled/white,/area/submap/lonehome) +"qo" = (/obj/item/weapon/phone,/obj/structure/table/bench/wooden,/obj/item/weapon/paper{info = "Seems to be filled with odd runes drawn with blood"; name = "Blood stained paper"},/turf/simulated/floor/wood,/area/submap/lonehome) +"qE" = (/obj/effect/decal/cleanable/blood/gibs,/turf/simulated/floor,/area/submap/lonehome) +"qN" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/carpet/sblucarpet,/area/submap/lonehome) +"rg" = (/obj/structure/window/reinforced/polarized{dir = 8; id = "h_living"},/obj/structure/bed/chair/sofa/black{dir = 4},/turf/simulated/floor/wood,/area/submap/lonehome) +"ro" = (/obj/item/weapon/pack/cardemon,/turf/simulated/floor/carpet/bcarpet,/area/submap/lonehome) +"ru" = (/obj/structure/table/rack,/obj/item/weapon/makeover,/obj/structure/curtain/open/bed,/turf/simulated/floor/wood,/area/submap/lonehome) +"rE" = (/obj/item/weapon/material/shard,/turf/simulated/floor/outdoors/grass/heavy,/area/submap/lonehome) +"tp" = (/obj/structure/flora/pottedplant/bamboo{pixel_y = 12},/obj/structure/table/bench/wooden,/turf/simulated/floor/wood,/area/submap/lonehome) +"uc" = (/obj/structure/girder,/turf/simulated/floor,/area/submap/lonehome) +"uh" = (/obj/structure/fence/cut/medium{dir = 4},/turf/simulated/floor/outdoors/grass/heavy,/area/submap/lonehome) +"um" = (/obj/structure/window/reinforced/tinted/frosted{dir = 8},/obj/structure/table/wooden_reinforced,/obj/item/weapon/book/tome,/turf/simulated/floor/wood,/area/submap/lonehome) +"uo" = (/obj/item/weapon/material/shard,/turf/simulated/floor/outdoors/dirt,/area/submap/lonehome) +"ur" = (/obj/structure/table/marble,/obj/item/weapon/material/knife/hook,/turf/simulated/floor,/area/submap/lonehome) +"uw" = (/obj/item/seeds/random,/obj/item/weapon/reagent_containers/spray/cleaner,/obj/structure/table/wooden_reinforced,/turf/simulated/floor/wood,/area/submap/lonehome) +"uC" = (/obj/item/seeds/random,/obj/item/seeds/random,/obj/machinery/space_heater,/turf/simulated/floor/wood,/area/submap/lonehome) +"uI" = (/obj/machinery/portable_atmospherics/hydroponics/soil,/turf/simulated/floor/outdoors/grass/heavy,/area/submap/lonehome) +"uK" = (/obj/item/weapon/material/minihoe,/turf/simulated/floor/outdoors/grass/heavy,/area/submap/lonehome) +"uR" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/wood,/area/submap/lonehome) +"ve" = (/obj/structure/table/bench/glass,/turf/simulated/floor/carpet/sblucarpet,/area/submap/lonehome) +"wa" = (/turf/simulated/floor/wood,/area/submap/lonehome) +"wj" = (/obj/item/weapon/bedsheet/rddouble,/turf/simulated/floor/wood,/area/submap/lonehome) +"xr" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/carpet/bcarpet,/area/submap/lonehome) +"xM" = (/obj/structure/fence/cut/large{dir = 8},/turf/simulated/floor/outdoors/grass/heavy,/area/submap/lonehome) +"xO" = (/obj/item/clothing/suit/straight_jacket,/turf/simulated/floor,/area/submap/lonehome) +"yh" = (/turf/simulated/floor/outdoors/dirt,/area/submap/lonehome) +"yn" = (/obj/structure/window/reinforced/polarized{dir = 8; id = "h_living"},/obj/structure/bed/chair/sofa/black/corner{dir = 1},/turf/simulated/floor/wood,/area/submap/lonehome) +"yr" = (/obj/item/weapon/reagent_containers/blood,/obj/item/weapon/pack/cardemon,/obj/item/weapon/pack/cardemon,/obj/item/weapon/deck/tarot,/obj/structure/table/wooden_reinforced,/turf/simulated/floor/wood,/area/submap/lonehome) +"yt" = (/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/carpet/sblucarpet,/area/submap/lonehome) +"yF" = (/obj/structure/bed/chair/sofa/black{dir = 1},/turf/simulated/floor/wood,/area/submap/lonehome) +"yQ" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/tiled/white,/area/submap/lonehome) +"zN" = (/obj/item/weapon/paper{info = "Seems to be filled with odd runes drawn with blood"; name = "Blood stained paper"},/turf/simulated/floor/wood,/area/submap/lonehome) +"AQ" = (/obj/structure/window/reinforced{dir = 8; health = 1e+006},/obj/item/weapon/material/shard,/turf/simulated/floor/outdoors/dirt,/area/submap/lonehome) +"BH" = (/obj/item/weapon/paper{info = "F%$K this detective, I swear I can see them peeking from behind the window, these tinted glasses help but I swear I can still see them snooping around. His days are counted... I am so close to figuring this out, just need a few more days. Then Shepiffany will be part of the family once again, then our two kids and I can go back on having a normal life... a normal life..."; name = "Stained sheet of paper"},/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/carpet/sblucarpet,/area/submap/lonehome) +"Dd" = (/obj/machinery/button/windowtint{id = "h_kitchen"},/obj/item/weapon/storage/box/donkpockets,/obj/item/weapon/storage/box/condimentbottles,/obj/item/weapon/reagent_containers/food/condiment/sugar,/obj/structure/curtain/open/bed,/obj/structure/table/rack,/obj/structure/window/reinforced/polarized{dir = 4; id = "h_kitchen"},/turf/simulated/floor/tiled/white,/area/submap/lonehome) +"Dk" = (/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/tiled/white,/area/submap/lonehome) +"DE" = (/obj/structure/window/reinforced/tinted/frosted{dir = 8},/obj/item/weapon/storage/box/glasses/square{pixel_y = -2},/obj/item/weapon/storage/box/glass_extras/sticks{pixel_y = 4},/obj/item/weapon/storage/box/glass_extras/straws{pixel_y = 7},/obj/item/weapon/packageWrap,/obj/structure/curtain/open/bed,/obj/item/weapon/material/kitchen/utensil/fork,/obj/item/weapon/material/kitchen/utensil/fork,/obj/item/weapon/material/kitchen/utensil/spoon{pixel_x = 2},/obj/item/weapon/material/kitchen/utensil/spoon{pixel_x = 2},/obj/structure/table/rack,/turf/simulated/floor/tiled/white,/area/submap/lonehome) +"DG" = (/obj/structure/simple_door/wood,/turf/simulated/floor,/area/submap/lonehome) +"DL" = (/obj/structure/closet/cabinet,/obj/item/weapon/storage/wallet/random,/obj/item/weapon/towel/random,/obj/item/weapon/melee/umbrella/random,/obj/random/carp_plushie,/obj/random/curseditem,/obj/random/junk,/obj/random/maintenance/medical,/obj/random/maintenance/medical,/obj/random/maintenance/medical,/turf/simulated/floor/wood,/area/submap/lonehome) +"Ea" = (/obj/item/weapon/pack/cardemon,/turf/simulated/floor/wood,/area/submap/lonehome) +"Ek" = (/obj/structure/window/reinforced{dir = 4; health = 1e+006},/turf/simulated/floor/outdoors/dirt,/area/submap/lonehome) +"Eo" = (/obj/random/junk,/turf/simulated/floor/carpet/sblucarpet,/area/submap/lonehome) +"Ex" = (/obj/item/weapon/paper{info = "Seems to be filled with odd runes drawn with blood"; name = "Blood stained paper"},/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/wood/broken,/area/submap/lonehome) +"EZ" = (/obj/effect/decal/cleanable/blood/gibs,/obj/structure/table/marble,/obj/item/organ/internal/intestine/unathi,/obj/item/weapon/surgical/bonesetter,/obj/item/weapon/bone/ribs,/obj/item/weapon/bone/skull{pixel_x = 4; pixel_y = 6},/turf/simulated/floor,/area/submap/lonehome) +"Fh" = (/obj/structure/coatrack,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/wood,/area/submap/lonehome) +"Fu" = (/turf/simulated/floor/carpet/sblucarpet,/area/submap/lonehome) +"Fy" = (/obj/structure/window/reinforced{dir = 1},/obj/machinery/portable_atmospherics/hydroponics/soil,/turf/simulated/floor/outdoors/grass/heavy,/area/submap/lonehome) +"FN" = (/obj/machinery/button/windowtint{id = "h_living"},/turf/simulated/wall/wood,/area/submap/lonehome) +"Gm" = (/obj/machinery/button/windowtint{id = "h_kitchen"},/turf/simulated/wall/wood,/area/submap/lonehome) +"Gr" = (/obj/structure/table/bench/marble,/obj/structure/window/reinforced/polarized{id = "h_master"},/obj/structure/flora/pottedplant/bamboo{pixel_y = 7},/turf/simulated/floor/wood,/area/submap/lonehome) +"GA" = (/obj/item/weapon/reagent_containers/food/snacks/ghostmuffin/poison,/obj/structure/table/sifwooden_reinforced,/turf/simulated/floor/wood,/area/submap/lonehome) +"GS" = (/obj/structure/table/steel,/obj/item/stack/material/phoron{amount = 5},/obj/item/stack/material/phoron{amount = 5},/obj/fiftyspawner/wood,/obj/fiftyspawner/steel,/turf/simulated/floor,/area/submap/lonehome) +"Hc" = (/obj/effect/decal/cleanable/blood/gibs,/obj/structure/kitchenspike,/obj/effect/rune,/turf/simulated/floor,/area/submap/lonehome) +"Hu" = (/obj/item/frame/apc,/obj/machinery/light_switch{pixel_x = 11; pixel_y = 22},/obj/random/junk,/turf/simulated/floor,/area/submap/lonehome) +"Im" = (/obj/structure/window/reinforced/tinted/frosted{dir = 8},/turf/simulated/floor/wood,/area/submap/lonehome) +"Ji" = (/obj/structure/fence/cut/medium,/turf/simulated/floor/outdoors/grass/heavy,/area/submap/lonehome) +"Jq" = (/obj/structure/bed/double/padded,/obj/machinery/light/small{dir = 4},/turf/simulated/floor/wood,/area/submap/lonehome) +"JW" = (/obj/structure/simple_door/wood,/turf/simulated/floor/wood,/area/submap/lonehome) +"Kb" = (/obj/structure/loot_pile/maint/trash,/turf/simulated/floor/outdoors/grass/heavy,/area/submap/lonehome) +"Ki" = (/obj/structure/closet/cabinet,/obj/random/multiple,/obj/random/multiple,/obj/random/multiple,/obj/random/multiple,/obj/random/multiple,/obj/random/toy,/obj/random/toy,/obj/item/weapon/storage/mre/random,/obj/item/weapon/storage/mre/random,/turf/simulated/floor/wood,/area/submap/lonehome) +"Kr" = (/obj/machinery/portable_atmospherics/hydroponics/soil,/obj/item/weapon/material/shard,/turf/simulated/floor/outdoors/grass/heavy,/area/submap/lonehome) +"Kw" = (/obj/structure/closet/secure_closet/freezer/fridge,/obj/random/meat,/obj/random/meat,/obj/random/meat,/obj/random/meat,/obj/random/meat,/turf/simulated/floor/tiled/white,/area/submap/lonehome) +"Ll" = (/obj/machinery/space_heater,/turf/simulated/floor/wood,/area/submap/lonehome) +"LS" = (/obj/item/trash/plate,/obj/item/weapon/reagent_containers/food/condiment/small/saltshaker,/obj/structure/table/sifwooden_reinforced,/turf/simulated/floor/wood,/area/submap/lonehome) +"Mb" = (/obj/structure/bed/chair/wood{dir = 1},/turf/simulated/floor/wood,/area/submap/lonehome) +"Mn" = (/obj/machinery/button/windowtint{id = "h_kitchen"},/obj/item/weapon/reagent_containers/food/condiment/enzyme,/obj/structure/window/reinforced/polarized{dir = 4; id = "h_kitchen"},/turf/simulated/floor/tiled/white,/area/submap/lonehome) +"MM" = (/turf/simulated/floor/outdoors/grass/heavy,/area/submap/lonehome) +"Nx" = (/obj/machinery/light{dir = 4},/turf/simulated/floor/wood,/area/submap/lonehome) +"ND" = (/obj/structure/table/bench/marble,/obj/structure/window/reinforced/polarized{dir = 8; id = "h_living"},/turf/simulated/floor/wood,/area/submap/lonehome) +"NK" = (/obj/random/trash,/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/carpet/sblucarpet,/area/submap/lonehome) +"NL" = (/turf/template_noop,/area/submap/lonehome) +"Od" = (/obj/item/weapon/extinguisher{pixel_x = 8; pixel_y = 1},/obj/random/maintenance/medical,/obj/random/maintenance/medical,/obj/random/maintenance/medical,/obj/random/medical/lite,/obj/random/medical/lite,/obj/structure/mopbucket{pixel_x = -8; pixel_y = -4},/obj/item/weapon/mop,/obj/item/device/multitool,/obj/item/device/flashlight{pixel_x = 2; pixel_y = 2},/obj/random/unidentified_medicine,/obj/random/unidentified_medicine,/obj/random/unidentified_medicine,/obj/structure/table/steel,/turf/simulated/floor/tiled,/area/submap/lonehome) +"Oe" = (/obj/structure/window/reinforced{dir = 8; health = 1e+006},/turf/template_noop,/area/submap/lonehome) +"Or" = (/obj/structure/table/bench/marble,/obj/structure/window/reinforced/polarized{id = "h_master"},/obj/structure/flora/pottedplant/overgrown{pixel_y = 7},/turf/simulated/floor/wood,/area/submap/lonehome) +"OL" = (/obj/machinery/button/windowtint{id = "h_kitchen"},/obj/item/weapon/material/kitchen/utensil/spoon{pixel_x = 2},/obj/structure/table/sifwooden_reinforced,/obj/structure/window/reinforced/polarized{dir = 4; id = "h_kitchen"},/turf/simulated/floor/wood,/area/submap/lonehome) +"Pc" = (/obj/item/weapon/material/kitchen/utensil/fork,/obj/random/trash,/turf/simulated/floor/wood,/area/submap/lonehome) +"Qx" = (/obj/item/weapon/material/shard{pixel_x = 6},/obj/item/weapon/material/shard,/turf/simulated/floor/outdoors/dirt,/area/submap/lonehome) +"QU" = (/obj/effect/decal/cleanable/blood/gibs,/obj/item/clothing/gloves/yellow,/turf/simulated/floor,/area/submap/lonehome) +"QX" = (/obj/random/trash,/turf/simulated/floor/wood,/area/submap/lonehome) +"RI" = (/obj/structure/window/reinforced{dir = 8; health = 1e+006},/turf/simulated/floor/outdoors/dirt,/area/submap/lonehome) +"Sd" = (/obj/structure/fence/corner,/turf/template_noop,/area/submap/lonehome) +"Sp" = (/obj/item/weapon/material/shard,/obj/item/weapon/material/shard{pixel_x = 5; pixel_y = 3},/turf/simulated/floor/outdoors/dirt,/area/submap/lonehome) +"SN" = (/obj/structure/bed/chair/wood/wings{dir = 1},/obj/effect/gibspawner/human,/turf/simulated/floor/carpet/sblucarpet,/area/submap/lonehome) +"Tg" = (/obj/item/weapon/material/kitchen/utensil/fork,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/wood,/area/submap/lonehome) +"Tw" = (/obj/item/weapon/cell/high/empty,/turf/simulated/floor/carpet/sblucarpet,/area/submap/lonehome) +"TX" = (/obj/item/clothing/suit/storage/apron/white,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/tiled/white,/area/submap/lonehome) +"Uj" = (/obj/machinery/light/small,/obj/item/weapon/ore/diamond,/obj/structure/sign/goldenplaque{desc = "Done No Harm."; name = "Best Doctor 2552"; pixel_y = -32},/obj/structure/table/wooden_reinforced,/turf/simulated/floor/wood,/area/submap/lonehome) +"UA" = (/obj/structure/fence/door/opened,/turf/template_noop,/area/submap/lonehome) +"UB" = (/obj/item/weapon/storage/box/characters,/obj/structure/curtain/open/bed,/obj/structure/table/rack,/turf/simulated/floor/wood,/area/submap/lonehome) +"US" = (/turf/simulated/floor/tiled/white,/area/submap/lonehome) +"Vn" = (/obj/item/weapon/reagent_containers/food/condiment/small/sugar,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/wood/broken,/area/submap/lonehome) +"VI" = (/obj/structure/fence{dir = 4},/turf/template_noop,/area/submap/lonehome) +"Wf" = (/obj/structure/bed/padded,/obj/random/trash,/obj/random/trash,/obj/random/trash,/obj/random/trash,/obj/random/trash,/obj/random/junk,/obj/random/junk,/obj/random/junk,/obj/random/junk,/obj/item/weapon/bedsheet/ian,/turf/simulated/floor/wood,/area/submap/lonehome) +"Wj" = (/obj/machinery/gibber/autogibber{emagged = 1},/turf/simulated/floor,/area/submap/lonehome) +"Wn" = (/obj/structure/fence/cut/medium{dir = 4},/turf/template_noop,/area/submap/lonehome) +"WQ" = (/obj/structure/window/reinforced/polarized{dir = 8; id = "h_living"},/obj/structure/bed/chair/sofa/black/corner{dir = 4},/turf/simulated/floor/wood,/area/submap/lonehome) +"Xc" = (/obj/item/weapon/module/power_control,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/wood,/area/submap/lonehome) +"Xz" = (/obj/item/weapon/material/shard,/turf/template_noop,/area/submap/lonehome) +"Ys" = (/obj/item/weapon/pen/fountain,/turf/simulated/floor/wood,/area/submap/lonehome) +"YK" = (/obj/structure/table/marble,/obj/item/organ/internal/intestine/unathi{pixel_x = -1; pixel_y = 8},/obj/item/organ/internal/lungs,/turf/simulated/floor,/area/submap/lonehome) +"Zi" = (/obj/machinery/light{dir = 8},/turf/simulated/floor/wood,/area/submap/lonehome) +"ZR" = (/obj/structure/fence{dir = 4},/turf/simulated/floor/outdoors/grass/heavy,/area/submap/lonehome) + +(1,1,1) = {" +NLNLNLNLNLyhNLyhNLNLNLNLNLNLNLNLNLNLNLNL +NLNLNLNLyhyhyhNLNLNLNLNLNLNLNLNLNLawNLNL +NLNLNLNLyhNLNLNLawNLNLNLNLNLNLNLNLNLNLNL +NLNLyhmayhmaNLNLNLNLNLNLNLNLNLNLNLNLNLNL +NLNLmamaJWmamaflNLflmamaucucmamaNLNLNLNL +NLmaFNFhpXLlucmamamamaKwnLqkqimamamayhNL +yhNLNDuRcSiwwalJmaOdmayQDkTXDkDEDdyhNLNL +NLgnynnDoZpXiwQXucJWmaiQkghHyQUSMnAQNLNL +XzSprgveFuFuEowaJWcSJWwauRiiTgjKknQxuoNL +NLEkrgveFuqNqNNxmacSmaZinTiwiwLSOLRINLNL +XzEkWQyFatwacSXctpjyaIuRuRVnPcGAlBXzNLNL +NLucmamamamaucmamabbucipjHwahhMbhKOeyhNL +NLmamarugIumuRExJWpXmauCuwUjlzGmmamaNLNL +NLmaDLzNTwSNBHbbmackmamaucmamamaHcmamaNL +NLmacnYsdRNKytksuccSmaUBImkTKimaxOWjmaNL +NLmaoxnaNKFuqNJqmacSJWpXxrroyrmalSEZmaNL +NLmapoLliwwawjqomauRmaLlEaWfoSmamncEmaNL +NLflmamaOrGrhqeLmaiwmaaKmamamamaQUurmaNL +MMNLmaKrFyKruIFymaJWmaldHuGSkUmaqEYKmaNL +NLMMqaMMMMrEMMMMuKMMDGnininzewucaumamaNL +NLMMJiMMMMMMMMMMMMKbmamamaucmamaucmaNLNL +NLNLqaMMMMMMMMMMMMMMMMMMMMMMMMMMMMqaNLNL +NLMMjtVIpbuhZRZRpbUAVIpbVIWnVIVIxMSdNLNL +MMMMNLNLNLNLNLNLNLNLNLNLNLNLNLNLNLMMNLNL +NLNLNLNLNLNLNLNLNLNLawNLNLNLNLNLNLNLNLNL +"} diff --git a/maps/submaps/surface_submaps/plains/methlab.dmm b/maps/submaps/surface_submaps/plains/methlab.dmm new file mode 100644 index 00000000000..b419e7655d8 --- /dev/null +++ b/maps/submaps/surface_submaps/plains/methlab.dmm @@ -0,0 +1,141 @@ +"ai" = (/obj/structure/table/steel_reinforced,/obj/item/weapon/paper_bin,/obj/item/weapon/pen/fountain,/turf/simulated/floor/tiled/steel_dirty,/area/submap/methlab) +"as" = (/obj/machinery/door/airlock,/turf/simulated/floor/tiled/steel_grid,/area/submap/methlab) +"aY" = (/obj/item/weapon/material/shard{pixel_x = 5; pixel_y = 3},/obj/item/weapon/material/shard{pixel_x = 9},/turf/template_noop,/area/submap/methlab) +"bn" = (/obj/structure/fence/cut/medium,/turf/template_noop,/area/submap/methlab) +"bA" = (/obj/item/weapon/cell/hyper,/turf/simulated/floor/tiled/steel_dirty,/area/submap/methlab) +"bJ" = (/obj/effect/floor_decal/rust,/obj/random/maintenance,/turf/simulated/floor/tiled/steel_dirty,/area/submap/methlab) +"bQ" = (/obj/item/weapon/material/shard{icon_state = "medium"},/obj/item/weapon/material/shard{pixel_x = 9},/obj/item/weapon/material/shard{pixel_x = 5},/turf/template_noop,/area/submap/methlab) +"cg" = (/obj/structure/table/steel_reinforced,/obj/item/device/radio{anchored = 1; canhear_range = 1; frequency = 1487; icon = 'icons/obj/items.dmi'; icon_state = "red_phone"; name = "Reception Emergency Phone"},/turf/simulated/floor/tiled/steel_dirty,/area/submap/methlab) +"ck" = (/obj/machinery/portable_atmospherics/hydroponics,/obj/item/seeds/ambrosiadeusseed,/obj/effect/floor_decal/industrial/hatch/yellow,/turf/simulated/floor/tiled/old_tile/white,/area/submap/methlab) +"dy" = (/obj/effect/floor_decal/industrial/warning/corner,/obj/effect/floor_decal/rust,/obj/random/maintenance,/turf/simulated/floor/tiled/steel_dirty,/area/submap/methlab) +"fr" = (/obj/structure/fence,/turf/template_noop,/area/submap/methlab) +"fD" = (/obj/effect/floor_decal/industrial/warning{dir = 8},/turf/simulated/floor/tiled/techfloor,/area/submap/methlab) +"fY" = (/obj/item/stack/cable_coil,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor,/area/submap/methlab) +"hf" = (/turf/simulated/floor,/area/submap/methlab) +"hj" = (/obj/machinery/power/port_gen/pacman,/turf/simulated/floor,/area/submap/methlab) +"hE" = (/obj/machinery/door/airlock/vault/bolted,/turf/simulated/floor/tiled/techfloor/grid,/area/submap/methlab) +"hQ" = (/turf/simulated/floor/tiled/steel_dirty,/area/submap/methlab) +"ic" = (/obj/machinery/portable_atmospherics/hydroponics,/obj/machinery/light{dir = 8},/obj/item/seeds/ambrosiavulgarisseed,/obj/effect/floor_decal/industrial/hatch/yellow,/turf/simulated/floor/tiled/old_tile/white,/area/submap/methlab) +"iz" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor,/area/submap/methlab) +"iN" = (/obj/structure/table/steel_reinforced,/obj/item/weapon/reagent_containers/dropper,/turf/simulated/floor/tiled/steel_dirty,/area/submap/methlab) +"jm" = (/obj/structure/fence{dir = 4},/turf/simulated/floor/outdoors/dirt,/area/submap/methlab) +"jo" = (/obj/machinery/vending/hydronutrients,/turf/simulated/floor/tiled/old_tile/white,/area/submap/methlab) +"kp" = (/obj/effect/floor_decal/rust/mono_rusted3,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/tiled/old_tile/green,/area/submap/methlab) +"lb" = (/obj/machinery/biogenerator,/turf/simulated/floor/tiled/old_tile/white,/area/submap/methlab) +"lt" = (/obj/item/frame/apc,/obj/structure/table/steel,/obj/machinery/light_switch{pixel_x = 11; pixel_y = 22},/turf/simulated/floor,/area/submap/methlab) +"lx" = (/turf/simulated/floor/outdoors/dirt,/area/submap/methlab) +"lJ" = (/obj/structure/fence/corner,/turf/template_noop,/area/submap/methlab) +"lN" = (/obj/structure/barricade,/obj/effect/floor_decal/steeldecal/steel_decals_central5,/turf/simulated/floor/tiled/steel_dirty,/area/submap/methlab) +"me" = (/obj/structure/salvageable/data,/turf/simulated/floor/tiled/steel_dirty,/area/submap/methlab) +"mi" = (/obj/effect/floor_decal/sign,/turf/simulated/wall,/area/submap/methlab) +"mw" = (/obj/structure/table/steel_reinforced,/obj/item/weapon/storage/toolbox/syndicate,/turf/simulated/floor/tiled/steel_dirty,/area/submap/methlab) +"nq" = (/obj/random/junk,/turf/simulated/floor,/area/submap/methlab) +"oo" = (/obj/machinery/portable_atmospherics/hydroponics,/obj/item/seeds/ambrosiainfernusseed,/obj/effect/floor_decal/industrial/hatch/yellow,/turf/simulated/floor/tiled/old_tile/white,/area/submap/methlab) +"oF" = (/obj/structure/fence/cut/large,/turf/template_noop,/area/submap/methlab) +"oN" = (/turf/simulated/wall/r_wall,/area/submap/methlab) +"pq" = (/obj/structure/bed/chair{dir = 8},/obj/random/junk,/turf/simulated/floor/tiled/steel_dirty,/area/submap/methlab) +"ps" = (/turf/template_noop,/area/submap/methlab) +"rK" = (/obj/item/weapon/reagent_containers/glass/beaker/large,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor,/area/submap/methlab) +"rU" = (/obj/item/clothing/under/suit_jacket,/obj/item/clothing/shoes/dress{pixel_y = -9},/obj/item/clothing/mask/demon,/obj/structure/curtain/black,/turf/simulated/floor/tiled/techfloor,/area/submap/methlab) +"sI" = (/obj/machinery/light,/obj/effect/floor_decal/rust,/obj/effect/decal/cleanable/dirt,/obj/random/maintenance,/turf/simulated/floor/tiled/steel_dirty,/area/submap/methlab) +"sW" = (/obj/item/weapon/material/shard{pixel_x = 9},/turf/template_noop,/area/submap/methlab) +"tt" = (/obj/structure/table/steel_reinforced,/obj/structure/salvageable/personal,/turf/simulated/floor/tiled/steel_dirty,/area/submap/methlab) +"tz" = (/obj/effect/wingrille_spawn/reinforced,/turf/simulated/floor/tiled/techfloor,/area/submap/methlab) +"tL" = (/obj/effect/floor_decal/rust,/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/tiled/steel_dirty,/area/submap/methlab) +"tQ" = (/obj/structure/girder,/turf/simulated/floor,/area/submap/methlab) +"uA" = (/obj/structure/fence/cut/large{dir = 8},/turf/template_noop,/area/submap/methlab) +"uY" = (/obj/random/trash,/turf/simulated/floor/tiled/steel_dirty,/area/submap/methlab) +"wd" = (/turf/simulated/floor/tiled/old_tile/green,/area/submap/methlab) +"wI" = (/obj/item/weapon/reagent_containers/dropper,/obj/random/junk,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/tiled/steel_dirty,/area/submap/methlab) +"wQ" = (/obj/machinery/light{dir = 8},/turf/template_noop,/area/submap/methlab) +"xM" = (/obj/machinery/door/airlock,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/tiled/steel_grid,/area/submap/methlab) +"xR" = (/obj/structure/loot_pile/maint/technical,/turf/template_noop,/area/submap/methlab) +"yr" = (/obj/random/trash,/turf/simulated/floor,/area/submap/methlab) +"yM" = (/obj/item/clothing/under/suit_jacket/really_black,/obj/item/clothing/shoes/dress{pixel_y = -9},/obj/item/clothing/mask/luchador,/obj/structure/curtain/black,/turf/simulated/floor/tiled/techfloor,/area/submap/methlab) +"yY" = (/obj/effect/floor_decal/rust,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/tiled/steel_dirty,/area/submap/methlab) +"zu" = (/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/tiled/old_tile/green,/area/submap/methlab) +"zG" = (/obj/random/junk,/turf/template_noop,/area/submap/methlab) +"zH" = (/obj/machinery/light{dir = 4},/turf/template_noop,/area/submap/methlab) +"zZ" = (/obj/structure/fence/corner{dir = 4},/turf/template_noop,/area/submap/methlab) +"AB" = (/obj/structure/table/steel_reinforced,/obj/item/weapon/reagent_containers/glass/beaker/large,/turf/simulated/floor/tiled/steel_dirty,/area/submap/methlab) +"AM" = (/mob/living/simple_mob/humanoid/merc/melee/poi,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/tiled/steel_dirty,/area/submap/methlab) +"AW" = (/obj/random/junk,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/tiled/steel_dirty,/area/submap/methlab) +"BP" = (/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/tiled/steel_dirty,/area/submap/methlab) +"BR" = (/obj/structure/table/steel_reinforced,/obj/item/weapon/reagent_containers/glass/bucket,/obj/item/weapon/reagent_containers/glass/bucket,/turf/simulated/floor/tiled/steel_dirty,/area/submap/methlab) +"BT" = (/obj/structure/safe/floor,/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiavulgaris,/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiavulgaris,/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiavulgaris,/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiavulgaris,/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiavulgaris,/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiavulgaris,/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiavulgaris,/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiavulgaris,/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiavulgaris,/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiavulgaris,/obj/item/weapon/storage/bag/cash,/obj/item/weapon/storage/bag/cash,/turf/simulated/floor,/area/submap/methlab) +"CH" = (/obj/item/seeds/ambrosiavulgarisseed,/obj/item/seeds/ambrosiavulgarisseed,/obj/item/seeds/ambrosiavulgarisseed,/obj/item/seeds/ambrosiainfernusseed,/obj/item/seeds/ambrosiainfernusseed,/obj/item/seeds/ambrosiainfernusseed,/obj/item/seeds/ambrosiadeusseed,/obj/item/seeds/ambrosiadeusseed,/obj/item/seeds/ambrosiadeusseed,/obj/structure/table/rack,/turf/simulated/floor/tiled/old_tile/white,/area/submap/methlab) +"CL" = (/obj/structure/grille/rustic,/obj/item/weapon/material/shard{icon_state = "medium"},/turf/simulated/floor/tiled/old_tile/green,/area/submap/methlab) +"CW" = (/obj/machinery/light{dir = 4},/turf/simulated/floor/tiled/techfloor,/area/submap/methlab) +"DG" = (/obj/structure/fence,/turf/simulated/floor/outdoors/dirt,/area/submap/methlab) +"DP" = (/obj/item/weapon/reagent_containers/dropper,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/tiled/steel_dirty,/area/submap/methlab) +"Eb" = (/obj/machinery/portable_atmospherics/hydroponics,/obj/item/seeds/ambrosiadeusseed,/obj/effect/floor_decal/rust,/obj/effect/floor_decal/industrial/hatch/yellow,/turf/simulated/floor/tiled/old_tile/white,/area/submap/methlab) +"EW" = (/obj/item/weapon/stool,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor,/area/submap/methlab) +"Fg" = (/obj/machinery/door/airlock,/turf/simulated/floor,/area/submap/methlab) +"Gs" = (/obj/structure/table/steel_reinforced,/obj/machinery/light{dir = 1},/turf/simulated/floor/tiled/steel_dirty,/area/submap/methlab) +"GP" = (/obj/structure/flora/tree/sif,/turf/template_noop,/area/submap/methlab) +"HA" = (/obj/structure/window/reinforced/full,/obj/structure/grille/rustic,/turf/simulated/floor/tiled/old_tile/green,/area/submap/methlab) +"HN" = (/obj/machinery/porta_turret/lasertag/red{name = "REAL turret"},/turf/simulated/floor,/area/submap/methlab) +"HX" = (/obj/machinery/light,/obj/effect/floor_decal/rust,/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/obj/structure/barricade,/turf/simulated/floor/tiled/steel_dirty,/area/submap/methlab) +"Ih" = (/obj/structure/sign/warning/lethal_turrets,/turf/simulated/wall,/area/submap/methlab) +"IH" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/tiled/old_tile/green,/area/submap/methlab) +"IQ" = (/obj/item/clothing/accessory/stethoscope,/obj/effect/floor_decal/industrial/warning{dir = 4},/turf/simulated/floor,/area/submap/methlab) +"JQ" = (/obj/effect/floor_decal/industrial/warning/corner{dir = 4},/obj/effect/floor_decal/rust,/obj/effect/floor_decal/steeldecal/steel_decals3,/turf/simulated/floor/tiled/steel_dirty,/area/submap/methlab) +"Kg" = (/obj/structure/fence/cut/medium{dir = 4},/turf/simulated/floor/outdoors/dirt,/area/submap/methlab) +"KK" = (/obj/machinery/chem_master,/obj/effect/floor_decal/rust/color_rustedfull,/turf/simulated/floor/tiled/steel_dirty,/area/submap/methlab) +"Lh" = (/obj/effect/floor_decal/rust,/turf/simulated/floor/tiled/steel_dirty,/area/submap/methlab) +"LM" = (/obj/random/trash,/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/tiled/steel_dirty,/area/submap/methlab) +"LX" = (/obj/item/weapon/stool,/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/tiled/steel_dirty,/area/submap/methlab) +"Mn" = (/obj/structure/barricade,/turf/simulated/floor,/area/submap/methlab) +"Of" = (/obj/effect/wingrille_spawn/reinforced,/obj/structure/barricade,/turf/simulated/floor/tiled/techfloor,/area/submap/methlab) +"Ol" = (/obj/effect/floor_decal/rust,/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/tiled/old_tile/green,/area/submap/methlab) +"Oq" = (/obj/structure/fence{dir = 4},/turf/template_noop,/area/submap/methlab) +"Py" = (/obj/random/trash,/turf/simulated/floor/outdoors/dirt,/area/submap/methlab) +"PH" = (/obj/machinery/seed_extractor,/turf/simulated/floor/tiled/old_tile/white,/area/submap/methlab) +"PO" = (/obj/structure/table/steel_reinforced,/obj/item/weapon/module/power_control,/turf/simulated/floor/tiled/steel_dirty,/area/submap/methlab) +"PZ" = (/obj/effect/floor_decal/rust,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/tiled/old_tile/green,/area/submap/methlab) +"QP" = (/obj/structure/table/steel_reinforced,/turf/simulated/floor/tiled/steel_dirty,/area/submap/methlab) +"QW" = (/obj/effect/floor_decal/rust,/turf/simulated/floor/tiled/old_tile/green,/area/submap/methlab) +"Sn" = (/obj/structure/barricade,/obj/effect/floor_decal/steeldecal/steel_decals_central5,/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/tiled/steel_dirty,/area/submap/methlab) +"St" = (/obj/structure/salvageable/implant_container,/turf/simulated/floor/tiled/steel_dirty,/area/submap/methlab) +"Ti" = (/obj/machinery/portable_atmospherics/hydroponics,/obj/machinery/light{dir = 4},/obj/item/seeds/ambrosiadeusseed,/obj/effect/floor_decal/industrial/hatch/yellow,/turf/simulated/floor/tiled/old_tile/white,/area/submap/methlab) +"Tr" = (/obj/item/weapon/stool,/obj/effect/floor_decal/rust,/obj/random/maintenance/engineering,/turf/simulated/floor/tiled/steel_dirty,/area/submap/methlab) +"Ts" = (/obj/random/maintenance,/turf/simulated/floor/tiled/steel_dirty,/area/submap/methlab) +"Ty" = (/obj/item/clothing/under/suit_jacket/burgundy,/obj/item/clothing/shoes/dress{pixel_y = -9},/obj/item/clothing/mask/dolphin,/obj/structure/curtain/black,/turf/simulated/floor/tiled/techfloor,/area/submap/methlab) +"TU" = (/obj/structure/safe/floor,/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiadeus,/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiadeus,/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiadeus,/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiadeus,/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiadeus,/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiadeus,/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiadeus,/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiadeus,/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiadeus,/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiadeus,/obj/item/weapon/storage/bag/cash,/obj/item/weapon/storage/bag/cash,/turf/simulated/floor,/area/submap/methlab) +"Uy" = (/obj/structure/fence/corner{dir = 8},/turf/template_noop,/area/submap/methlab) +"UD" = (/obj/item/clothing/under/suit_jacket/red,/obj/item/clothing/shoes/dress{pixel_y = -9},/obj/item/clothing/mask/goblin,/obj/structure/curtain/black,/turf/simulated/floor/tiled/techfloor,/area/submap/methlab) +"UO" = (/obj/item/weapon/material/shard{icon_state = "medium"},/turf/template_noop,/area/submap/methlab) +"Vf" = (/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/obj/random/maintenance/cargo,/turf/simulated/floor/tiled/old_tile/green,/area/submap/methlab) +"Vu" = (/obj/structure/fence/cut/medium{dir = 4},/turf/template_noop,/area/submap/methlab) +"Vw" = (/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/obj/random/maintenance,/turf/simulated/floor/tiled/steel_dirty,/area/submap/methlab) +"VV" = (/obj/structure/fence/corner{dir = 10},/turf/template_noop,/area/submap/methlab) +"Wp" = (/obj/structure/loot_pile/maint/trash,/turf/template_noop,/area/submap/methlab) +"Xi" = (/turf/simulated/wall,/area/submap/methlab) +"Xo" = (/obj/effect/floor_decal/rust,/obj/random/maintenance/engineering,/turf/simulated/floor/tiled/old_tile/green,/area/submap/methlab) +"Xr" = (/obj/item/stack/material/phoron{amount = 5},/obj/item/stack/material/phoron{amount = 5},/obj/item/weapon/extinguisher,/obj/item/weapon/storage/box/lights/mixed,/turf/simulated/floor,/area/submap/methlab) +"Yz" = (/obj/machinery/portable_atmospherics/hydroponics,/obj/item/seeds/ambrosiavulgarisseed,/obj/effect/floor_decal/industrial/hatch/yellow,/turf/simulated/floor/tiled/old_tile/white,/area/submap/methlab) +"Zp" = (/obj/structure/grille/rustic,/obj/item/weapon/material/shard{pixel_x = 5; pixel_y = 3},/turf/simulated/floor/tiled/old_tile/green,/area/submap/methlab) +"Zt" = (/obj/structure/salvageable/autolathe,/obj/effect/floor_decal/rust/color_rustedfull,/turf/simulated/floor/tiled/steel_dirty,/area/submap/methlab) + +(1,1,1) = {" +UyOqOqVuOqOqOqVuOqOqOqjmjmOqOqOqVuOqOqzZ +frpspspspspspspspspsXitzOfOfIhpspspspsfr +frpspsHNpspsGPpspsXiXiKKGsQPXiXipsGPpsoF +oFpspshfpspslxpspsXibArKDPTrmetQWppspsps +pspspshfpszGPylxWptQKKABiNuYmeoNoNoNoNfr +pspspsIhXiOfOftzXiXibJEWyYfYdyoNBTBToNfr +frpsXiXiZtcgttaiStStKKPOABuYIQhEfDCWoNfr +frlxtzmwhfTsLhpqhQAMwItLLXAWJQoNTUTUoNoF +DGpsOfBRLhuYhfsIizLMVwBPHXSnlNoNoNoNoNfr +frWpXitQXixMXiXirUTyyMUDXiasasXihjltXifr +pspspspsHAkpHAXiXiXiXiXiXihfhfXiyrXrXifr +oFpsHAHAHAOlHAHAHAxRxRWpXiMnMnXiFgXiXifr +oFbQCLYzPZVfzuEbHApspspsXiasasXinqyrhfoF +pssWHAYzPZPHOlckHApspszHmiyrhfIhwQpspsps +pspsHAicwdjoVfTiHApspspspsPylxhfpspspsfr +bnpsHAooXolbIHckHAUOpszGpslxpsHNpspspsfr +frpsHAoowdCHQWckZpaYzGpspspslxpspsGPpsfr +pspsHAHAHAHAHAHAHApspspspslxpspspspspsfr +frpspspspspspspspspspspspspspspspspspsfr +VVOqOqOqOqOquApsOqVuOqOqOqOqKgpsuAOquAlJ +"} diff --git a/maps/submaps/surface_submaps/plains/oldhotel.dmm b/maps/submaps/surface_submaps/plains/oldhotel.dmm new file mode 100644 index 00000000000..57ba1213bb9 --- /dev/null +++ b/maps/submaps/surface_submaps/plains/oldhotel.dmm @@ -0,0 +1,153 @@ +"ai" = (/obj/random/trash,/turf/simulated/floor/carpet/purcarpet,/area/submap/oldhotel) +"aJ" = (/obj/item/weapon/towel/random,/obj/item/weapon/towel/random,/obj/structure/table/standard,/obj/item/weapon/storage/firstaid,/turf/simulated/floor/tiled/asteroid_steel,/area/submap/oldhotel) +"bb" = (/obj/machinery/light/small{dir = 4},/obj/item/device/multitool,/turf/simulated/floor/wood,/area/submap/oldhotel) +"bQ" = (/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/tiled/asteroid_steel,/area/submap/oldhotel) +"bW" = (/obj/item/weapon/material/shard,/turf/template_noop,/area/submap/oldhotel) +"cA" = (/obj/structure/sink/kitchen,/turf/simulated/wall/wood,/area/submap/oldhotel) +"cZ" = (/obj/effect/decal/cleanable/dirt,/obj/random/junk,/turf/simulated/floor/carpet/oracarpet,/area/submap/oldhotel) +"da" = (/obj/structure/bed/chair/sofa/teal/right,/turf/simulated/floor/carpet/blue,/area/submap/oldhotel) +"dc" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/carpet/oracarpet,/area/submap/oldhotel) +"dn" = (/obj/structure/table/woodentable,/obj/item/weapon/flame/candle/everburn,/turf/simulated/floor/wood,/area/submap/oldhotel) +"dr" = (/obj/item/stack/material/log/sif,/turf/simulated/floor/tiled/asteroid_steel,/area/submap/oldhotel) +"dz" = (/obj/structure/sink{dir = 8; pixel_x = -12; pixel_y = 2},/obj/structure/mirror{dir = 4; pixel_x = -28},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/tiled/asteroid_steel,/area/submap/oldhotel) +"dL" = (/obj/structure/window/reinforced/full,/obj/structure/grille/rustic,/turf/simulated/floor/tiled/asteroid_steel,/area/submap/oldhotel) +"eK" = (/obj/structure/bonfire/sifwood,/obj/structure/grille/rustic,/turf/simulated/floor/outdoors/dirt,/area/submap/oldhotel) +"go" = (/obj/structure/simple_door/iron,/turf/simulated/floor/wood,/area/submap/oldhotel) +"gA" = (/turf/template_noop,/area/template_noop) +"gM" = (/obj/machinery/appliance/cooker/oven,/turf/simulated/floor/tiled/asteroid_steel,/area/submap/oldhotel) +"hc" = (/obj/random/trash,/turf/simulated/floor/wood,/area/submap/oldhotel) +"hp" = (/obj/random/junk,/turf/simulated/floor/carpet/sblucarpet,/area/submap/oldhotel) +"hQ" = (/turf/simulated/wall/wood,/area/submap/oldhotel) +"if" = (/obj/structure/bed/chair/sofa/teal/left{dir = 8},/turf/simulated/floor/carpet/blue,/area/submap/oldhotel) +"iU" = (/obj/structure/table/woodentable,/obj/item/trash/tray,/turf/simulated/floor/wood,/area/submap/oldhotel) +"ja" = (/obj/effect/decal/cleanable/dirt,/obj/random/junk,/turf/simulated/floor/carpet/purcarpet,/area/submap/oldhotel) +"je" = (/obj/structure/closet/cabinet,/obj/item/device/binoculars/spyglass,/obj/random/contraband,/obj/random/contraband,/obj/random/maintenance/medical,/obj/random/cash,/obj/random/drinkbottle,/obj/random/junk,/obj/random/junk,/obj/random/maintenance,/obj/random/maintenance,/turf/simulated/floor/wood,/area/submap/oldhotel) +"jO" = (/obj/structure/bed/chair/sofa/teal,/turf/simulated/floor/carpet/blue,/area/submap/oldhotel) +"jS" = (/obj/structure/closet/cabinet,/obj/random/maintenance/medical,/obj/random/cash,/obj/random/cigarettes,/obj/random/firstaid,/obj/random/junk,/obj/random/junk,/obj/random/junk,/obj/random/maintenance,/turf/simulated/floor/wood,/area/submap/oldhotel) +"kh" = (/turf/simulated/floor/carpet/blue,/area/submap/oldhotel) +"kw" = (/obj/structure/lightpost,/turf/template_noop,/area/submap/oldhotel) +"kI" = (/turf/simulated/floor/carpet/sblucarpet,/area/submap/oldhotel) +"kW" = (/obj/structure/table/woodentable,/obj/item/weapon/reagent_containers/food/condiment/small/saltshaker,/obj/item/weapon/reagent_containers/food/condiment/small/peppermill{pixel_x = 3},/turf/simulated/floor/wood,/area/submap/oldhotel) +"lj" = (/obj/structure/table/wooden_reinforced,/obj/item/weapon/material/kitchen/rollingpin,/turf/simulated/floor/tiled/asteroid_steel,/area/submap/oldhotel) +"ly" = (/obj/structure/bed/double/padded,/obj/item/weapon/bedsheet/mimedouble,/turf/simulated/floor/wood,/area/submap/oldhotel) +"lZ" = (/obj/structure/table/woodentable,/obj/item/trash/tray,/turf/simulated/floor/carpet/blue,/area/submap/oldhotel) +"mr" = (/obj/structure/table/woodentable,/obj/item/weapon/cell/hyper,/turf/simulated/floor/wood,/area/submap/oldhotel) +"mR" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/outdoors/dirt,/area/submap/oldhotel) +"nD" = (/turf/simulated/floor,/area/submap/oldhotel) +"nG" = (/obj/item/weapon/material/shard,/turf/simulated/floor/outdoors/dirt,/area/submap/oldhotel) +"nZ" = (/obj/fiftyspawner/wood,/turf/simulated/floor/tiled/asteroid_steel,/area/submap/oldhotel) +"op" = (/obj/structure/table/woodentable,/obj/random/cigarettes,/turf/simulated/floor/carpet/blue,/area/submap/oldhotel) +"pi" = (/obj/item/weapon/material/shard,/obj/item/weapon/material/shard{icon_state = "medium"; pixel_x = 12; pixel_y = 7},/turf/template_noop,/area/submap/oldhotel) +"pn" = (/obj/item/weapon/material/shard,/obj/item/weapon/material/shard{pixel_x = 7},/turf/template_noop,/area/submap/oldhotel) +"qg" = (/turf/simulated/floor/wood,/area/submap/oldhotel) +"qY" = (/obj/effect/decal/cleanable/dirt,/obj/random/junk,/turf/simulated/floor/wood,/area/submap/oldhotel) +"rb" = (/obj/item/weapon/module/power_control,/turf/simulated/floor/tiled/asteroid_steel,/area/submap/oldhotel) +"rK" = (/obj/structure/table/woodentable,/obj/item/trash/candle,/turf/simulated/floor/wood,/area/submap/oldhotel) +"rZ" = (/obj/item/weapon/material/shard{icon_state = "medium"},/turf/template_noop,/area/submap/oldhotel) +"sd" = (/obj/structure/toilet,/turf/simulated/floor/tiled/asteroid_steel,/area/submap/oldhotel) +"sV" = (/obj/structure/table/woodentable,/obj/random/contraband,/turf/simulated/floor/wood,/area/submap/oldhotel) +"tn" = (/obj/structure/simple_door/wood,/turf/simulated/floor/wood,/area/submap/oldhotel) +"tz" = (/obj/structure/bed/double/padded,/obj/item/weapon/bedsheet/rddouble,/turf/simulated/floor/wood,/area/submap/oldhotel) +"tE" = (/obj/structure/table/woodentable,/obj/random/coin,/obj/item/weapon/reagent_containers/glass/rag,/turf/simulated/floor/carpet/blue,/area/submap/oldhotel) +"tV" = (/obj/structure/bed/chair/wood{dir = 1},/obj/item/weapon/material/shard,/turf/simulated/floor/wood,/area/submap/oldhotel) +"uF" = (/obj/fiftyspawner/steel,/turf/simulated/floor/tiled/asteroid_steel,/area/submap/oldhotel) +"uU" = (/obj/structure/closet/cabinet,/obj/random/maintenance/medical,/obj/random/carp_plushie,/obj/random/cigarettes,/obj/random/drinkbottle,/obj/random/junk,/obj/random/junk,/obj/random/junk,/obj/random/maintenance,/turf/simulated/floor/wood,/area/submap/oldhotel) +"vh" = (/obj/structure/bed/chair/sofa/teal/corner,/turf/simulated/floor/carpet/blue,/area/submap/oldhotel) +"vA" = (/obj/structure/table/woodentable,/obj/item/weapon/telecube/randomized{name = "Odd artifact"},/turf/simulated/floor/wood,/area/submap/oldhotel) +"vM" = (/obj/item/weapon/material/shard,/obj/item/weapon/material/shard{pixel_y = -6},/obj/item/weapon/material/shard{pixel_x = 9},/obj/structure/grille/broken/rustic,/turf/simulated/floor/tiled/asteroid_steel,/area/submap/oldhotel) +"vN" = (/obj/random/humanoidremains,/obj/random/humanoidremains,/turf/simulated/floor/wood/broken,/area/submap/oldhotel) +"vR" = (/obj/structure/table/woodentable,/obj/item/weapon/flame/candle/candelabra,/turf/simulated/floor/carpet/blue,/area/submap/oldhotel) +"wm" = (/obj/random/trash,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/outdoors/dirt,/area/submap/oldhotel) +"wK" = (/obj/item/weapon/material/shard,/obj/item/weapon/material/shard,/obj/item/weapon/material/shard{icon_state = "medium"; pixel_x = 12; pixel_y = 7},/turf/simulated/floor/tiled/asteroid_steel,/area/submap/oldhotel) +"wV" = (/obj/structure/table/wooden_reinforced,/obj/item/weapon/reagent_containers/glass/beaker,/obj/item/weapon/reagent_containers/food/condiment/enzyme,/turf/simulated/floor/tiled/asteroid_steel,/area/submap/oldhotel) +"wX" = (/obj/item/weapon/material/shard,/obj/item/weapon/material/shard{icon_state = "medium"; pixel_x = 12; pixel_y = 7},/turf/simulated/floor/outdoors/dirt,/area/submap/oldhotel) +"yj" = (/obj/random/mob/sif/peaceful,/turf/simulated/floor/outdoors/dirt,/area/submap/oldhotel) +"yM" = (/obj/item/stack/cable_coil,/turf/simulated/floor/carpet/purcarpet,/area/submap/oldhotel) +"zs" = (/obj/effect/decal/cleanable/dirt,/obj/random/junk,/turf/simulated/floor/outdoors/dirt,/area/submap/oldhotel) +"zt" = (/obj/structure/noticeboard,/turf/simulated/wall/wood,/area/submap/oldhotel) +"zO" = (/obj/item/weapon/material/shard,/obj/structure/grille/broken/rustic,/obj/item/weapon/material/shard{icon_state = "medium"; pixel_x = 12; pixel_y = 7},/turf/simulated/floor/tiled/asteroid_steel,/area/submap/oldhotel) +"zP" = (/obj/random/plushie,/turf/simulated/floor/wood,/area/submap/oldhotel) +"Ac" = (/obj/structure/table/wooden_reinforced,/obj/item/weapon/material/knife/butch,/turf/simulated/floor/tiled/asteroid_steel,/area/submap/oldhotel) +"AO" = (/obj/structure/railing,/turf/simulated/floor/outdoors/dirt,/area/submap/oldhotel) +"AU" = (/obj/structure/table/woodentable,/obj/item/device/tape,/turf/simulated/floor/wood,/area/submap/oldhotel) +"AZ" = (/obj/structure/table/woodentable,/obj/item/trash/candle,/obj/item/weapon/paper{info = "This is a stupid tresure hunt task, that thing is not taking us anywhere. Go on and have fun finding a waste of time."; name = "Wrinkled sheet of paper"},/turf/simulated/floor/wood,/area/submap/oldhotel) +"Bt" = (/obj/structure/closet/cabinet,/obj/item/clothing/gloves/yellow,/obj/random/projectile/scrapped_pistol,/obj/random/junk,/obj/random/junk,/obj/random/junk,/obj/random/maintenance,/obj/random/maintenance,/obj/random/maintenance,/turf/simulated/floor/wood,/area/submap/oldhotel) +"Cx" = (/turf/simulated/floor/outdoors/dirt,/area/submap/oldhotel) +"CS" = (/obj/item/weapon/storage/toolbox/mechanical,/turf/simulated/floor/wood,/area/submap/oldhotel) +"Di" = (/obj/structure/table/wooden_reinforced,/obj/machinery/microwave,/turf/simulated/floor/tiled/asteroid_steel,/area/submap/oldhotel) +"Dx" = (/obj/structure/table/wooden_reinforced,/obj/random/medical,/obj/random/medical,/turf/simulated/floor/tiled/asteroid_steel,/area/submap/oldhotel) +"DN" = (/obj/structure/bed/chair/wood,/turf/simulated/floor/wood,/area/submap/oldhotel) +"Es" = (/obj/random/junk,/turf/simulated/floor/outdoors/dirt,/area/submap/oldhotel) +"ES" = (/obj/random/trash,/turf/simulated/floor/carpet/oracarpet,/area/submap/oldhotel) +"Gk" = (/obj/structure/bed/chair/wood{dir = 1},/turf/simulated/floor/wood,/area/submap/oldhotel) +"Gr" = (/obj/item/frame/apc,/turf/simulated/floor/wood,/area/submap/oldhotel) +"Gz" = (/obj/structure/window/reinforced/tinted{dir = 8},/obj/machinery/shower{dir = 1},/obj/structure/curtain/open/shower/medical,/turf/simulated/floor/tiled/asteroid_steel,/area/submap/oldhotel) +"GC" = (/obj/random/trash,/obj/random/trash,/turf/simulated/floor/outdoors/dirt,/area/submap/oldhotel) +"GN" = (/obj/structure/flora/tree/sif,/turf/template_noop,/area/submap/oldhotel) +"GV" = (/obj/structure/table/woodentable,/obj/item/weapon/storage/fancy/candle_box,/obj/item/weapon/storage/fancy/candle_box,/obj/item/weapon/storage/fancy/candle_box,/obj/item/weapon/flame/lighter/random,/obj/item/weapon/flame/lighter/random,/obj/item/weapon/melee/umbrella/random,/turf/simulated/floor/wood,/area/submap/oldhotel) +"Ik" = (/obj/item/weapon/material/shard,/obj/item/weapon/material/shard{icon_state = "medium"},/turf/simulated/floor/tiled/asteroid_steel,/area/submap/oldhotel) +"Il" = (/obj/structure/closet/secure_closet/freezer/kitchen{locked = 0},/turf/simulated/floor/tiled/asteroid_steel,/area/submap/oldhotel) +"IQ" = (/obj/structure/railing,/obj/structure/closet/crate/bin,/turf/simulated/floor/tiled/asteroid_steel,/area/submap/oldhotel) +"Jq" = (/turf/simulated/floor/tiled/asteroid_steel,/area/submap/oldhotel) +"JT" = (/obj/random/junk,/turf/simulated/floor/wood,/area/submap/oldhotel) +"JV" = (/obj/structure/table/bench/sifwooden,/turf/simulated/floor/outdoors/dirt,/area/submap/oldhotel) +"Lg" = (/obj/item/weapon/material/shard,/obj/structure/grille/broken/rustic,/obj/item/weapon/material/shard{icon_state = "medium"},/turf/simulated/floor/tiled/asteroid_steel,/area/submap/oldhotel) +"Mk" = (/obj/structure/closet/crate,/obj/random/action_figure,/obj/random/action_figure,/obj/random/action_figure,/obj/random/action_figure,/turf/simulated/floor/wood,/area/submap/oldhotel) +"Mo" = (/obj/structure/railing,/turf/template_noop,/area/submap/oldhotel) +"Mq" = (/obj/structure/closet/crate,/obj/random/firstaid,/turf/simulated/floor/wood,/area/submap/oldhotel) +"MD" = (/obj/effect/decal/cleanable/dirt,/obj/structure/simple_door/wood,/turf/simulated/floor/wood,/area/submap/oldhotel) +"MU" = (/turf/template_noop,/area/submap/oldhotel) +"Nu" = (/obj/random/soap,/turf/simulated/floor/tiled/asteroid_steel,/area/submap/oldhotel) +"OQ" = (/obj/structure/closet/crate,/obj/random/cash,/turf/simulated/floor/wood,/area/submap/oldhotel) +"Pd" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/carpet/sblucarpet,/area/submap/oldhotel) +"PO" = (/obj/machinery/space_heater,/turf/simulated/floor/wood/broken,/area/submap/oldhotel) +"Qv" = (/obj/structure/table/woodentable,/obj/item/weapon/paper_bin,/obj/item/weapon/pen,/obj/item/weapon/pen,/obj/item/weapon/pen,/turf/simulated/floor/wood,/area/submap/oldhotel) +"Qw" = (/obj/item/weapon/stool,/obj/random/cash,/obj/machinery/light/small,/turf/simulated/floor/wood,/area/submap/oldhotel) +"QG" = (/obj/structure/bed/chair/sofa/teal{dir = 8},/turf/simulated/floor/carpet/blue,/area/submap/oldhotel) +"RM" = (/obj/machinery/space_heater,/turf/simulated/floor/wood,/area/submap/oldhotel) +"RQ" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/wood/broken,/area/submap/oldhotel) +"Sf" = (/obj/structure/bed/double/padded,/obj/item/weapon/bedsheet/yellowdouble,/turf/simulated/floor/wood,/area/submap/oldhotel) +"Sy" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/tiled/asteroid_steel,/area/submap/oldhotel) +"SG" = (/turf/simulated/floor/carpet/purcarpet,/area/submap/oldhotel) +"SL" = (/obj/item/weapon/material/shard,/obj/item/weapon/material/shard,/obj/item/weapon/material/shard{icon_state = "medium"; pixel_x = 12; pixel_y = 7},/turf/simulated/floor,/area/submap/oldhotel) +"SZ" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/wood,/area/submap/oldhotel) +"TU" = (/turf/simulated/floor/wood/broken,/area/submap/oldhotel) +"Ut" = (/obj/structure/kitchenspike,/turf/simulated/floor/outdoors/dirt,/area/submap/oldhotel) +"Uw" = (/obj/structure/table/wooden_reinforced,/obj/item/weapon/book/manual/chef_recipes,/turf/simulated/floor/tiled/asteroid_steel,/area/submap/oldhotel) +"UU" = (/obj/structure/table/woodentable,/obj/item/weapon/flame/lighter/zippo/royal,/obj/item/weapon/lipstick/random,/turf/simulated/floor/wood,/area/submap/oldhotel) +"Vf" = (/obj/structure/window/reinforced/tinted{dir = 4},/obj/machinery/shower{dir = 1},/obj/structure/curtain/open/shower/medical,/obj/random/soap,/turf/simulated/floor/tiled/asteroid_steel,/area/submap/oldhotel) +"Vj" = (/turf/simulated/floor/carpet/oracarpet,/area/submap/oldhotel) +"Wy" = (/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/wood,/area/submap/oldhotel) +"WD" = (/obj/structure/closet/secure_closet/freezer/fridge,/obj/random/meat,/obj/random/meat,/obj/random/meat,/obj/random/meat,/obj/random/meat,/obj/random/meat,/obj/random/meat,/obj/machinery/light/small{dir = 8},/obj/random/meat,/turf/simulated/floor/tiled/asteroid_steel,/area/submap/oldhotel) +"WH" = (/obj/item/device/flashlight{pixel_x = 2; pixel_y = 2},/turf/simulated/floor/wood,/area/submap/oldhotel) +"YI" = (/obj/structure/coatrack,/turf/simulated/floor/wood,/area/submap/oldhotel) +"YQ" = (/obj/item/weapon/material/shard,/obj/structure/grille/broken/rustic,/turf/simulated/floor/tiled/asteroid_steel,/area/submap/oldhotel) +"ZG" = (/obj/structure/girder,/turf/simulated/floor,/area/submap/oldhotel) + +(1,1,1) = {" +gAgAgAgAgAgAgAgAgAgAgAgAgAgAgAgAgAgAgAgAgAgAgAgAgA +gAMUMUMUmRMUMUMUMUMUMUMUMUMUMUMUMUMUMUMUMUMUMUMUgA +gAMUkwhQmRhQwXMUpiZGnDMUwXMUhQZGhQMUMUMUMUGNMUMUgA +gAMUhQhQgoztvMdLwKhQhQdLzOdLhQhQhQhQZGMUMUMUMUMUgA +gAMUhQBtTUSZqgqYJTzPqgqgJTqgmrZGaJsdhQMUMUMUMUMUgA +gAMUZGYITUQvrKUUAUTUqgdajOvhTUhQdzSyZGMUMUMUMUMUgA +gAMUZGGVWHSZQwGrqgqgSZopvRQGhcMDSyNuSLMUMUMUMUMUgA +gAMUhQhQhQhQhQZGnDhQqglZtEQGSZhQVfGzhQMUMUMUMUMUgA +gAMUMUhQhQDNTURMrKhQSZkhkhifqghQnDhQhQMUMUMUMUMUgA +gAMUMUrZdLsVESdctzhQJTSZqgSZTUhQdrdrZGMUCxMUMUMUgA +gAMUMUnGYQtVVjcZuUhQtntnhQgogocAuFnZhQCxMUMUMUMUgA +gAMUMUhQhQMqSZSZqgtnqgSZZGJqJqSyJqbQUtCxMUMUMUMUgA +gAMUMUnDZGnDhQhQhQhQhcDNhQrbCxmREsCxJqCxMUCxMUMUgA +gAMUMUhQhQDNRMTUrKhQSZdnnDljJqEsCxCxCxMUMUCxMUGNgA +gAMUMUCxIkiUaiSGSfZGqgkWZGAcCxmRyjMUMUCxMUMUMUMUgA +gAMUbWpnLgGkjayMjShQSZGkhQUwJqCxCxJVMUMUMUMUMUMUgA +gAMUMUnDZGOQqgWySZtnRQbbhQWDSywmCxeKCxCxMUCxMUMUgA +gAMUMUhQZGhQhQZGhQhQSZDNhQwVJqCxCxJVMUMUMUMUMUMUgA +gAMUMUhQhQMkPOvNJTtnSZkWhQDxmRmREsMUMUMUMUMUMUMUgA +gAMUMUCxdLDNPdkIjehQSZdnhQDiSyzsCxCxMUMUMUMUMUMUgA +gAMUMUCxdLvAhpPdlynDCSGkhQgMCxGCyjMUMUMUMUMUMUMUgA +gAMUMUhQhQGkqgqgAZhQdLdLZGIlJqCxCxMUMUMUMUMUMUMUgA +gAMUMUhQhQhQZGhQhQhQMUMUnDIQCxAOAOMUMoMUGNMUMUMUgA +gAMUMUMUMUMUMUMUMUMUMUMUMUMUMUMUMUMUMUMUMUMUMUMUgA +gAgAgAgAgAgAgAgAgAgAgAgAgAgAgAgAgAgAgAgAgAgAgAgAgA +"} diff --git a/maps/submaps/surface_submaps/plains/plains.dm b/maps/submaps/surface_submaps/plains/plains.dm index cf05e432230..3f51385c1c0 100644 --- a/maps/submaps/surface_submaps/plains/plains.dm +++ b/maps/submaps/surface_submaps/plains/plains.dm @@ -32,6 +32,11 @@ #include "BuriedTreasure.dmm" #include "BuriedTreasure2.dmm" #include "BuriedTreasure3.dmm" +#include "methlab.dmm" +#include "hotspring.dmm" +#include "lonehome.dmm" +#include "priderock.dmm" +#include "oldhotel.dmm" #endif @@ -246,3 +251,33 @@ mappath = 'maps/submaps/surface_submaps/plains/BuriedTreasure3.dmm' cost = 10 template_group = "Shallow Grave" + +/datum/map_template/surface/plains/oldhotel + name = "Old Hotel" + desc = "A abandoned hotel of sort, wonder why it was left behind." + mappath = 'maps/submaps/surface_submaps/plains/oldhotel.dmm' + cost = 15 + +/datum/map_template/surface/plains/priderock + name = "Pride Rock" + desc = "A quite steep petruding rock from the earth, looks like a good hike." + mappath = 'maps/submaps/surface_submaps/plains/priderock.dmm' + cost = 10 + +/datum/map_template/surface/plains/lonehome + name = "Lone Home" + desc = "A quite inoffensive looking home, damaged but still holding up." + mappath = 'maps/submaps/surface_submaps/plains/lonehome.dmm' + cost = 15 + +/datum/map_template/surface/plains/hotspring + name = "Hot Spring" + desc = "Wait what, a hotspring in a frost planet?" + mappath = 'maps/submaps/surface_submaps/plains/hotspring.dmm' + cost = 5 + +/datum/map_template/surface/plains/methlab + name = "Meth Lab" + desc = "A broken down greenhouse lab?, this does not look safe." + mappath = 'maps/submaps/surface_submaps/plains/methlab.dmm' + cost = 15 \ No newline at end of file diff --git a/maps/submaps/surface_submaps/plains/plains_areas.dm b/maps/submaps/surface_submaps/plains/plains_areas.dm index 58895767572..90903e17ddc 100644 --- a/maps/submaps/surface_submaps/plains/plains_areas.dm +++ b/maps/submaps/surface_submaps/plains/plains_areas.dm @@ -110,3 +110,23 @@ /area/submap/BuriedTreasure name = "POI - Buried Treasure" ambience = AMBIENCE_FOREBODING + +/area/submap/oldhotel + name = "POI - Old Hotel" + ambience = AMBIENCE_SIF + +/area/submap/priderock + name = "POI - Pride Rock" + ambience = AMBIENCE_SIF + +/area/submap/lonehome + name = "POI - Lone Home" + ambience = AMBIENCE_FOREBODING + +/area/submap/hotspring + name = "POI - Hot Spring" + ambience = AMBIENCE_SIF + +/area/submap/methlab + name = "POI - Meth Lab" + ambience = AMBIENCE_TECH_RUINS diff --git a/maps/submaps/surface_submaps/plains/priderock.dmm b/maps/submaps/surface_submaps/plains/priderock.dmm new file mode 100644 index 00000000000..1b2246d2af2 --- /dev/null +++ b/maps/submaps/surface_submaps/plains/priderock.dmm @@ -0,0 +1,88 @@ +"ae" = (/obj/structure/railing,/obj/item/weapon/bone,/turf/simulated/floor/outdoors/dirt,/area/submap/priderock) +"cR" = (/obj/structure/bed/chair{dir = 1},/turf/simulated/floor/outdoors/dirt,/area/submap/priderock) +"dq" = (/obj/effect/decal/cleanable/dirt,/obj/structure/bonfire/sifwood,/turf/simulated/floor/outdoors/grass/sif,/area/submap/priderock) +"dD" = (/obj/random/junk,/turf/simulated/floor/outdoors/dirt,/area/submap/priderock) +"fL" = (/obj/structure/railing{dir = 8},/obj/structure/cliff/automatic{dir = 8},/turf/simulated/floor/outdoors/dirt,/area/submap/priderock) +"hI" = (/obj/structure/table/woodentable,/turf/simulated/floor/outdoors/grass/sif,/area/submap/priderock) +"ik" = (/obj/random/trash,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/outdoors/dirt,/area/submap/priderock) +"jM" = (/obj/random/maintenance/medical,/obj/random/maintenance/medical,/obj/random/maintenance/medical,/obj/item/weapon/towel/random,/turf/simulated/floor/outdoors/dirt,/area/submap/priderock) +"md" = (/obj/random/trash,/turf/template_noop,/area/submap/priderock) +"nG" = (/obj/structure/railing,/obj/random/junk,/obj/item/weapon/bone/ribs,/obj/item/weapon/bone/skull,/turf/simulated/floor/outdoors/dirt,/area/submap/priderock) +"nV" = (/obj/item/stack/material/log/sif,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/outdoors/dirt,/area/submap/priderock) +"qh" = (/obj/structure/cliff/automatic{dir = 8},/turf/simulated/floor/outdoors/dirt,/area/submap/priderock) +"qP" = (/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/outdoors/dirt,/area/submap/priderock) +"qY" = (/obj/structure/cliff/automatic{dir = 9},/obj/structure/railing{dir = 1},/obj/structure/railing{dir = 8},/turf/simulated/floor/outdoors/dirt,/area/submap/priderock) +"sr" = (/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/outdoors/grass/sif,/area/submap/priderock) +"uv" = (/obj/structure/cliff/automatic/ramp,/obj/structure/railing{dir = 4},/turf/simulated/floor/outdoors/dirt,/area/submap/priderock) +"uG" = (/obj/structure/ledge/ledge_stairs,/turf/simulated/floor/outdoors/rocks,/area/submap/priderock) +"wU" = (/obj/structure/ledge/ledge_stairs{dir = 8},/turf/simulated/floor/outdoors/dirt,/area/submap/priderock) +"xE" = (/obj/structure/closet/crate/bin,/obj/random/junk,/obj/random/junk,/obj/random/junk,/obj/random/junk,/obj/random/junk,/obj/random/junk,/obj/random/junk,/turf/simulated/floor/outdoors/dirt,/area/submap/priderock) +"yi" = (/obj/structure/cliff/automatic/ramp{dir = 9},/obj/structure/railing{dir = 8},/turf/simulated/floor/outdoors/dirt,/area/submap/priderock) +"yI" = (/obj/structure/cliff/automatic{dir = 4},/turf/simulated/floor/outdoors/dirt,/area/submap/priderock) +"An" = (/obj/structure/railing,/obj/random/humanoidremains,/obj/random/humanoidremains,/turf/simulated/floor/outdoors/dirt,/area/submap/priderock) +"As" = (/obj/structure/closet/crate,/obj/random/maintenance/clean,/obj/random/maintenance/clean,/obj/random/maintenance/clean,/obj/random/maintenance/cargo,/obj/random/maintenance/medical,/obj/random/maintenance/medical,/turf/simulated/floor/outdoors/dirt,/area/submap/priderock) +"Bf" = (/obj/random/trash,/obj/random/trash,/turf/simulated/floor/outdoors/dirt,/area/submap/priderock) +"Bv" = (/obj/structure/loot_pile/maint/trash,/turf/simulated/floor/outdoors/dirt,/area/submap/priderock) +"BB" = (/obj/structure/flora/tree/sif,/turf/template_noop,/area/submap/priderock) +"Dg" = (/obj/effect/decal/cleanable/dirt,/obj/structure/ledge/ledge_stairs{dir = 8},/turf/simulated/floor/outdoors/dirt,/area/submap/priderock) +"Dx" = (/obj/structure/cliff/automatic/corner{dir = 9},/turf/simulated/floor/outdoors/dirt,/area/submap/priderock) +"DU" = (/obj/structure/cliff/automatic/corner,/turf/simulated/floor/outdoors/dirt,/area/submap/priderock) +"Ff" = (/obj/structure/cliff/automatic{dir = 8},/obj/structure/railing{dir = 8},/turf/simulated/floor/outdoors/dirt,/area/submap/priderock) +"Fg" = (/obj/effect/decal/cleanable/dirt,/obj/structure/ledge/ledge_stairs,/turf/simulated/floor/outdoors/dirt,/area/submap/priderock) +"Fo" = (/obj/structure/cliff/automatic{dir = 4},/obj/structure/railing{dir = 4},/turf/simulated/floor/outdoors/dirt,/area/submap/priderock) +"FO" = (/obj/random/junk,/turf/simulated/floor/outdoors/grass/sif,/area/submap/priderock) +"Gk" = (/obj/effect/decal/cleanable/dirt,/obj/structure/table/bench/wooden,/turf/simulated/floor/outdoors/grass/sif,/area/submap/priderock) +"Hw" = (/obj/random/trash,/turf/simulated/floor/outdoors/dirt,/area/submap/priderock) +"If" = (/obj/structure/bed/chair,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/outdoors/dirt,/area/submap/priderock) +"Ix" = (/obj/structure/cliff/automatic{dir = 10},/obj/structure/railing{dir = 8},/turf/simulated/floor/outdoors/dirt,/area/submap/priderock) +"Jk" = (/turf/simulated/floor/outdoors/grass/sif,/area/submap/priderock) +"Lm" = (/obj/random/junk,/obj/random/junk,/obj/random/junk,/obj/item/weapon/bone/skull/tajaran,/turf/simulated/floor/outdoors/dirt,/area/submap/priderock) +"Lo" = (/obj/structure/cliff/automatic{dir = 2},/obj/structure/railing,/turf/simulated/floor/outdoors/dirt,/area/submap/priderock) +"LK" = (/obj/structure/cliff/automatic,/turf/simulated/floor/outdoors/dirt,/area/submap/priderock) +"Mg" = (/obj/structure/cliff/automatic{dir = 2},/turf/simulated/floor/outdoors/dirt,/area/submap/priderock) +"Oc" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/outdoors/dirt,/area/submap/priderock) +"Od" = (/obj/structure/cliff/automatic/corner{dir = 10},/turf/simulated/floor/outdoors/dirt,/area/submap/priderock) +"Pb" = (/obj/item/weapon/storage/backpack/dufflebag/syndie/med,/turf/simulated/floor/outdoors/dirt,/area/submap/priderock) +"Pn" = (/obj/structure/table/bench/wooden,/turf/simulated/floor/outdoors/dirt,/area/submap/priderock) +"PW" = (/obj/random/tool,/obj/random/tool,/turf/simulated/floor/outdoors/dirt,/area/submap/priderock) +"Si" = (/obj/structure/cliff/automatic{dir = 6},/obj/structure/railing{dir = 4},/obj/structure/railing,/turf/simulated/floor/outdoors/dirt,/area/submap/priderock) +"SE" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/outdoors/rocks,/area/submap/priderock) +"Tb" = (/obj/structure/railing,/turf/simulated/floor/outdoors/dirt,/area/submap/priderock) +"Td" = (/obj/structure/cliff/automatic{dir = 10},/obj/structure/railing,/obj/structure/railing{dir = 8},/turf/simulated/floor/outdoors/dirt,/area/submap/priderock) +"Ud" = (/obj/effect/decal/cleanable/dirt,/obj/random/junk,/turf/simulated/floor/outdoors/dirt,/area/submap/priderock) +"UG" = (/obj/vehicle/train/engine/quadbike/random{desc = "A rideable electric ATV designed for all terrain. Looks very worn down."; locked = 1; name = "Old looking ATV"},/turf/simulated/floor/outdoors/dirt,/area/submap/priderock) +"VF" = (/obj/structure/cliff/automatic{dir = 5},/obj/structure/railing{dir = 1},/obj/structure/railing{dir = 4},/turf/simulated/floor/outdoors/dirt,/area/submap/priderock) +"VM" = (/obj/structure/loot_pile/maint/trash,/turf/template_noop,/area/submap/priderock) +"Wk" = (/turf/simulated/floor/outdoors/dirt,/area/submap/priderock) +"Xd" = (/obj/structure/cliff/automatic,/obj/structure/railing{dir = 1},/turf/simulated/floor/outdoors/dirt,/area/submap/priderock) +"XN" = (/obj/item/clothing/head/bearpelt,/obj/item/device/binoculars/spyglass,/turf/simulated/floor/outdoors/rocks,/area/submap/priderock) +"Yd" = (/obj/effect/decal/cleanable/dirt,/obj/structure/ledge/ledge_stairs{dir = 4},/turf/simulated/floor/outdoors/dirt,/area/submap/priderock) +"YP" = (/turf/simulated/floor/outdoors/rocks,/area/submap/priderock) +"Zc" = (/obj/random/trash,/obj/effect/decal/cleanable/dirt,/obj/structure/ledge/ledge_stairs{dir = 8},/turf/simulated/floor/outdoors/dirt,/area/submap/priderock) +"Zm" = (/turf/template_noop,/area/submap/priderock) +"ZA" = (/obj/random/trash,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/outdoors/grass/sif,/area/submap/priderock) +"ZJ" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/outdoors/grass/sif,/area/submap/priderock) +"ZO" = (/obj/structure/table/woodentable,/obj/random/plushie,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/outdoors/grass/sif,/area/submap/priderock) + +(1,1,1) = {" +ZmZmZmZmqPZmZmZmZmZmZmZmZmZmZm +ZmZmZmWksrWkWkZmZmOcZmWkZmZmZm +ZmZmOcuvqPZJyiBfZmZmZmZmBvZmZm +WkBBWkFoFgFgIxLoLoMgLoMgLoLoOd +WkZmZmFoZJqPZJOcOcZJqPZJPnPWFf +ZmWkUGDUXdLKLKXdVFOcZAUddqWkqh +ZmWkWkYPWkYPYPYPyIWkOcOcGkOcFf +ZmWkTbTbTbTbTbTbSinVZJZJOcJkFf +ZmFoPbFOwUYPJkwUJkZJZJZAZJxEFf +HwFoFOSEZcZJSEDgikZJOcIfIfJkFf +ZmFoYPqYXdLKXdXdVFWkFOhIZOjMFf +ZmFoWkfLYPWkYPYPFoJkJkcRcRdDqh +ZmyISETdaenGAnLmFoAsWkWkJkWkFf +WkFoOcSEYdYPWkFfDUXdLKXdXdXdDx +ZmDUXdXdXdVFYPqhZmZmWkZmWkZmWk +ZmWkWkWkZmyIuGFfHwHwVMZmVMZmZm +ZmmdmdVMWkFoXNFfZmWkZmWkBBZmZm +ZmZmZmZmWkDULKDxWkZmZmZmZmZmZm +ZmZmZmZmZmWkWkWkZmZmZmZmZmZmZm +ZmZmZmZmZmZmZmWkZmZmZmZmZmZmZm +"} diff --git a/maps/tether/submaps/gateway/zoo.dmm b/maps/tether/submaps/gateway/zoo.dmm index 76fff34ad98..7039ea57186 100644 --- a/maps/tether/submaps/gateway/zoo.dmm +++ b/maps/tether/submaps/gateway/zoo.dmm @@ -2323,7 +2323,7 @@ /turf/simulated/floor/plating, /area/awaymission/zoo) "gR" = ( -/obj/item/weapon/caution, +/obj/item/clothing/suit/caution, /turf/simulated/floor/plating, /area/awaymission/zoo/pirateship) "gS" = ( diff --git a/maps/tether/submaps/offmap/talon1.dmm b/maps/tether/submaps/offmap/talon1.dmm index 5cbf638bde6..81e4081c712 100644 --- a/maps/tether/submaps/offmap/talon1.dmm +++ b/maps/tether/submaps/offmap/talon1.dmm @@ -153,11 +153,15 @@ /turf/simulated/floor/tiled/eris/dark/cyancorner, /area/talon/deckone/bridge) "ar" = ( -/obj/machinery/atmospherics/unary/vent_pump/on{ - dir = 1 +/obj/machinery/door/blast/regular/open{ + dir = 4; + icon_state = "pdoor1"; + id = "talon_unused_hardpoint"; + name = "Unused Hardpoint Blast Door" }, -/turf/simulated/floor/tiled/eris/white/orangecorner, -/area/talon/deckone/armory) +/obj/structure/lattice, +/turf/space, +/area/talon/maintenance/deckone_starboard) "as" = ( /obj/structure/cable/green{ d1 = 4; @@ -190,9 +194,160 @@ }, /turf/simulated/floor/tiled/eris/dark/brown_perforated, /area/talon/deckone/port_eng) +"au" = ( +/obj/effect/floor_decal/industrial/outline/grey, +/obj/machinery/atmospherics/portables_connector/aux{ + dir = 8; + icon_state = "map_connector-aux" + }, +/obj/machinery/portable_atmospherics/canister/air/airlock, +/turf/simulated/floor/tiled/eris/steel/gray_perforated, +/area/talon/deckone/starboard_eng) +"av" = ( +/obj/structure/table/standard, +/obj/machinery/reagentgrinder, +/turf/simulated/floor/tiled/eris/white/bluecorner, +/area/talon/deckone/medical) +"aw" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 10 + }, +/obj/structure/table/standard, +/obj/machinery/chemical_dispenser/full, +/turf/simulated/floor/tiled/eris/white/bluecorner, +/area/talon/deckone/medical) +"ax" = ( +/obj/structure/table/rack/shelf/steel, +/obj/item/weapon/tank/oxygen, +/obj/item/weapon/tank/oxygen, +/obj/item/weapon/tank/oxygen, +/obj/item/weapon/tank/oxygen, +/turf/simulated/floor/tiled/eris/dark/danger, +/area/talon/deckone/secure_storage) +"ay" = ( +/obj/structure/catwalk, +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/obj/machinery/light/small{ + dir = 4; + pixel_y = 0 + }, +/turf/simulated/floor/plating/eris/under, +/area/talon/maintenance/deckone_port) +"az" = ( +/obj/structure/catwalk, +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/obj/machinery/light/small{ + dir = 8; + pixel_x = 0 + }, +/turf/simulated/floor/plating/eris/under, +/area/talon/maintenance/deckone_starboard) +"aA" = ( +/obj/structure/catwalk, +/obj/structure/cable/green{ + d1 = 1; + d2 = 4; + icon_state = "1-4" + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/light/small, +/turf/simulated/floor/plating/eris/under, +/area/talon/maintenance/deckone_port) +"aB" = ( +/obj/structure/catwalk, +/obj/structure/cable/green{ + icon_state = "1-8" + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/light/small, +/turf/simulated/floor/plating/eris/under, +/area/talon/maintenance/deckone_starboard) "aC" = ( /turf/simulated/wall/rshull, /area/talon/maintenance/deckone_port) +"aD" = ( +/obj/structure/table/rack/steel, +/obj/machinery/camera/network/talon, +/obj/item/device/suit_cooling_unit, +/obj/item/device/suit_cooling_unit, +/obj/item/device/suit_cooling_unit, +/obj/item/device/suit_cooling_unit, +/turf/simulated/floor/tiled/eris/dark/danger, +/area/talon/deckone/secure_storage) +"aE" = ( +/obj/machinery/camera/network/talon, +/obj/structure/table/rack/steel, +/obj/item/clothing/under/syndicate/combat, +/obj/item/clothing/suit/armor/combat, +/obj/item/clothing/head/helmet/combat, +/turf/simulated/floor/tiled/eris/white/danger, +/area/talon/deckone/armory) +"aF" = ( +/obj/effect/floor_decal/industrial/warning/dust{ + dir = 9 + }, +/obj/effect/floor_decal/industrial/warning/dust{ + dir = 6 + }, +/turf/simulated/floor/greengrid/airless, +/area/talon/maintenance/deckone_starboard) +"aG" = ( +/obj/structure/catwalk, +/obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction{ + dir = 8; + icon_state = "intact" + }, +/obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction{ + dir = 8; + icon_state = "intact" + }, +/obj/structure/handrail{ + dir = 8 + }, +/turf/space, +/area/talon/maintenance/deckone_port_fore_wing) +"aH" = ( +/obj/structure/catwalk, +/obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction{ + dir = 4; + icon_state = "intact" + }, +/obj/structure/handrail{ + dir = 4 + }, +/turf/space, +/area/talon/maintenance/deckone_starboard_fore_wing) +"aI" = ( +/obj/structure/catwalk, +/obj/structure/sign/warning/moving_parts{ + pixel_x = 30 + }, +/turf/space, +/area/talon/maintenance/deckone_port_fore_wing) +"aJ" = ( +/obj/structure/table/rack/shelf/steel, +/obj/item/clothing/shoes/magboots, +/obj/item/clothing/shoes/magboots, +/obj/item/clothing/shoes/magboots, +/obj/item/clothing/shoes/magboots, +/turf/simulated/floor/tiled/eris/dark/danger, +/area/talon/deckone/secure_storage) "aK" = ( /turf/simulated/wall/rshull, /area/talon/maintenance/deckone_starboard) @@ -215,9 +370,25 @@ "aM" = ( /turf/simulated/wall, /area/talon/maintenance/deckone_port) +"aN" = ( +/obj/structure/table/rack/shelf/steel, +/obj/item/weapon/tank/jetpack/carbondioxide, +/obj/item/weapon/tank/jetpack/carbondioxide, +/obj/item/weapon/tank/jetpack/carbondioxide, +/obj/item/weapon/tank/jetpack/carbondioxide, +/obj/item/weapon/tank/jetpack/carbondioxide, +/turf/simulated/floor/tiled/eris/dark/danger, +/area/talon/deckone/secure_storage) "aO" = ( /turf/simulated/wall, /area/talon/maintenance/deckone_starboard) +"aP" = ( +/obj/structure/table/rack/steel, +/obj/item/clothing/shoes/magboots, +/obj/item/clothing/suit/space/syndicate/black, +/obj/item/clothing/head/helmet/space/syndicate/black, +/turf/simulated/floor/tiled/eris/white/danger, +/area/talon/deckone/armory) "aQ" = ( /obj/machinery/computer/ship/engines{ dir = 8; @@ -229,6 +400,30 @@ "aR" = ( /turf/simulated/wall, /area/talon/deckone/secure_storage) +"aS" = ( +/obj/structure/catwalk, +/obj/structure/sign/warning/moving_parts{ + pixel_x = -30 + }, +/turf/space, +/area/talon/maintenance/deckone_starboard_fore_wing) +"aT" = ( +/obj/structure/catwalk, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/space, +/area/talon/maintenance/deckone_port_fore_wing) +"aU" = ( +/obj/structure/catwalk, +/obj/structure/cable/green{ + dir = 1; + icon_state = "4-8" + }, +/turf/space, +/area/talon/maintenance/deckone_starboard_fore_wing) "aV" = ( /obj/machinery/atmospherics/pipe/simple/hidden/aux, /obj/structure/catwalk, @@ -238,9 +433,67 @@ }, /turf/simulated/floor/plating/eris/under, /area/talon/maintenance/deckone_port) +"aW" = ( +/obj/machinery/alarm/talon{ + dir = 1; + pixel_y = -25 + }, +/obj/machinery/portable_atmospherics/canister/carbon_dioxide, +/turf/simulated/floor/tiled/eris/dark/danger, +/area/talon/deckone/secure_storage) +"aX" = ( +/obj/machinery/atmospherics/unary/vent_pump/on{ + dir = 1 + }, +/obj/structure/closet/wardrobe/black{ + starts_with = list(/obj/item/clothing/under/color/black = 4, /obj/item/clothing/accessory/storage/black_vest = 4, /obj/item/clothing/accessory/storage/black_drop_pouches = 4, /obj/item/clothing/gloves/black = 4, /obj/item/clothing/head/soft/black = 4, /obj/item/clothing/mask/balaclava = 4, /obj/item/clothing/mask/bandana = 4, /obj/item/clothing/mask/gas/commando = 4, /obj/item/weapon/storage/backpack/messenger/black = 4, /obj/item/weapon/storage/backpack/dufflebag = 4, /obj/item/clothing/shoes/black = 4, /obj/item/clothing/shoes/boots/duty = 4) + }, +/turf/simulated/floor/tiled/eris/white/orangecorner, +/area/talon/deckone/armory) "aY" = ( /turf/simulated/wall, /area/talon/deckone/armory) +"aZ" = ( +/obj/structure/catwalk, +/turf/space, +/area/talon/maintenance/deckone_port_fore_wing) +"ba" = ( +/obj/structure/catwalk, +/turf/space, +/area/talon/maintenance/deckone_starboard_fore_wing) +"bb" = ( +/obj/structure/closet/secure_closet/chemical{ + req_access = list(301) + }, +/turf/simulated/floor/tiled/eris/white/bluecorner, +/area/talon/deckone/medical) +"bc" = ( +/obj/structure/catwalk, +/obj/structure/handrail{ + dir = 8 + }, +/turf/space, +/area/talon/maintenance/deckone_port_aft_wing) +"bd" = ( +/obj/structure/catwalk, +/obj/structure/handrail{ + dir = 4 + }, +/turf/space, +/area/talon/maintenance/deckone_starboard_aft_wing) +"be" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/structure/table/standard, +/obj/item/clothing/gloves/sterile/nitrile, +/obj/item/clothing/mask/surgical, +/obj/item/clothing/suit/surgicalapron, +/turf/simulated/floor/tiled/eris/white/bluecorner, +/area/talon/deckone/medical) +"bf" = ( +/obj/structure/table/standard, +/obj/machinery/chemical_dispenser/biochemistry/full, +/turf/simulated/floor/tiled/eris/white/bluecorner, +/area/talon/deckone/medical) "bg" = ( /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ dir = 1 @@ -254,6 +507,17 @@ }, /turf/simulated/floor/tiled/eris/steel, /area/talon/deckone/brig) +"bh" = ( +/obj/structure/table/standard, +/obj/item/device/defib_kit/loaded, +/obj/item/weapon/storage/belt/medical/emt, +/obj/item/device/sleevemate, +/turf/simulated/floor/tiled/eris/white/bluecorner, +/area/talon/deckone/medical) +"bi" = ( +/obj/structure/catwalk, +/turf/space, +/area/talon/maintenance/deckone_port_aft_wing) "bj" = ( /obj/structure/window/reinforced, /turf/simulated/floor/tiled/eris/steel, @@ -265,6 +529,62 @@ }, /turf/simulated/floor/plating/eris/under, /area/talon/maintenance/deckone_starboard) +"bl" = ( +/obj/structure/catwalk, +/turf/space, +/area/talon/maintenance/deckone_starboard_aft_wing) +"bm" = ( +/obj/structure/catwalk, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/space, +/area/talon/maintenance/deckone_port_aft_wing) +"bn" = ( +/obj/structure/catwalk, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/space, +/area/talon/maintenance/deckone_starboard_aft_wing) +"bo" = ( +/obj/machinery/light/small{ + dir = 4; + pixel_y = 0 + }, +/obj/structure/catwalk, +/turf/space, +/area/talon/maintenance/deckone_port) +"bp" = ( +/obj/machinery/light/small{ + dir = 8; + pixel_y = 0 + }, +/obj/structure/catwalk, +/turf/space, +/area/talon/maintenance/deckone_starboard) +"bq" = ( +/obj/machinery/airlock_sensor{ + dir = 4; + pixel_x = -28; + req_one_access = list(301) + }, +/obj/effect/map_helper/airlock/atmos/chamber_pump, +/obj/effect/map_helper/airlock/sensor/chamber_sensor, +/obj/machinery/light/small{ + dir = 1; + icon_state = "bulb1" + }, +/obj/machinery/atmospherics/unary/vent_pump/high_volume/aux{ + dir = 4; + icon_state = "map_vent_aux" + }, +/turf/simulated/floor/tiled/eris/dark/gray_perforated, +/area/shuttle/talonboat) "br" = ( /obj/structure/grille, /obj/structure/window/reinforced/full, @@ -279,6 +599,23 @@ }, /turf/simulated/floor/plating, /area/talon/maintenance/deckone_port) +"bs" = ( +/obj/machinery/embedded_controller/radio/airlock/airlock_controller{ + dir = 8; + id_tag = "talon_boat"; + pixel_x = 28 + }, +/obj/effect/map_helper/airlock/atmos/chamber_pump, +/obj/machinery/atmospherics/unary/vent_pump/high_volume/aux{ + dir = 8; + icon_state = "map_vent_aux" + }, +/turf/simulated/floor/tiled/eris/dark/gray_perforated, +/area/shuttle/talonboat) +"bt" = ( +/obj/machinery/portable_atmospherics/canister/carbon_dioxide, +/turf/simulated/floor/tiled/eris/steel, +/area/talon/deckone/central_hallway) "bu" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4; @@ -297,6 +634,20 @@ }, /turf/simulated/floor/tiled/steel_grid, /area/talon/deckone/secure_storage) +"bv" = ( +/obj/machinery/door/firedoor/glass/talon, +/obj/machinery/door/blast/regular/open{ + dir = 4; + id = "talon_windows" + }, +/obj/structure/grille, +/obj/structure/window/reinforced/full, +/obj/structure/window/reinforced, +/obj/structure/window/reinforced{ + dir = 1 + }, +/turf/simulated/floor/plating/eris/under, +/area/talon/maintenance/deckone_starboard) "bw" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4; @@ -304,6 +655,17 @@ }, /turf/simulated/floor/tiled/eris/dark/brown_perforated, /area/talon/deckone/port_eng) +"bx" = ( +/obj/machinery/airlock_sensor{ + dir = 8; + pixel_x = 28; + pixel_y = 28; + req_one_access = list(301) + }, +/obj/effect/map_helper/airlock/sensor/ext_sensor, +/obj/structure/catwalk, +/turf/space, +/area/talon/maintenance/deckone_port) "by" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4; @@ -323,6 +685,48 @@ }, /turf/simulated/floor/tiled/steel_grid, /area/talon/deckone/armory) +"bz" = ( +/obj/machinery/airlock_sensor{ + dir = 4; + pixel_x = -28; + pixel_y = 28; + req_one_access = list(301) + }, +/obj/effect/map_helper/airlock/sensor/ext_sensor, +/obj/structure/catwalk, +/turf/space, +/area/talon/maintenance/deckone_starboard) +"bA" = ( +/obj/structure/catwalk, +/obj/structure/sign/warning/moving_parts{ + pixel_x = 30 + }, +/obj/machinery/camera/network/talon{ + dir = 8; + icon_state = "camera" + }, +/turf/space, +/area/talon/maintenance/deckone_port) +"bB" = ( +/obj/structure/catwalk, +/obj/structure/sign/warning/moving_parts{ + pixel_x = -30 + }, +/obj/machinery/camera/network/talon{ + dir = 4; + icon_state = "camera" + }, +/turf/space, +/area/talon/maintenance/deckone_starboard) +"bC" = ( +/obj/structure/table/rack, +/obj/item/weapon/storage/box/bodybags, +/obj/item/roller, +/obj/item/roller{ + pixel_y = 8 + }, +/turf/simulated/floor/tiled/eris/white/bluecorner, +/area/talon/deckone/medical) "bP" = ( /obj/machinery/atmospherics/pipe/manifold/hidden, /turf/simulated/floor/tiled/eris/dark/brown_perforated, @@ -818,39 +1222,6 @@ /obj/machinery/atmospherics/pipe/manifold/hidden/aux, /turf/simulated/floor/tiled/eris/dark/gray_perforated, /area/shuttle/talonboat) -"fo" = ( -/obj/structure/catwalk, -/obj/structure/sign/warning/moving_parts{ - pixel_x = 30 - }, -/obj/machinery/camera/network/talon{ - dir = 8; - icon_state = "camera" - }, -/turf/space, -/area/talon/maintenance/deckone_port) -"fy" = ( -/obj/structure/catwalk, -/obj/structure/sign/warning/moving_parts{ - pixel_x = -30 - }, -/obj/machinery/camera/network/talon{ - dir = 4; - icon_state = "camera" - }, -/turf/space, -/area/talon/maintenance/deckone_starboard) -"fz" = ( -/obj/machinery/airlock_sensor{ - dir = 8; - pixel_x = 28; - pixel_y = 28; - req_one_access = list(301) - }, -/obj/effect/map_helper/airlock/sensor/ext_sensor, -/obj/structure/catwalk, -/turf/space, -/area/talon/maintenance/deckone_port) "fH" = ( /obj/machinery/firealarm{ dir = 1; @@ -873,22 +1244,6 @@ /obj/effect/catwalk_plated, /turf/simulated/floor/plating/eris/under, /area/talon/deckone/central_hallway) -"fW" = ( -/obj/machinery/airlock_sensor{ - dir = 4; - pixel_x = -28; - pixel_y = 28; - req_one_access = list(301) - }, -/obj/effect/map_helper/airlock/sensor/ext_sensor, -/obj/structure/catwalk, -/turf/space, -/area/talon/maintenance/deckone_starboard) -"fZ" = ( -/obj/structure/table/standard, -/obj/machinery/chemical_dispenser/full, -/turf/simulated/floor/tiled/eris/white/bluecorner, -/area/talon/deckone/medical) "ga" = ( /obj/structure/grille, /obj/structure/window/reinforced/full, @@ -1144,20 +1499,6 @@ /obj/machinery/optable, /turf/simulated/floor/tiled/eris/white/bluecorner, /area/talon/deckone/medical) -"iw" = ( -/obj/structure/catwalk, -/obj/structure/cable/green{ - d1 = 1; - d2 = 4; - icon_state = "1-4" - }, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/turf/simulated/floor/plating/eris/under, -/area/talon/maintenance/deckone_port) "ix" = ( /obj/structure/grille, /obj/structure/window/reinforced/full, @@ -1384,22 +1725,6 @@ }, /turf/simulated/floor/reinforced/airless, /area/talon/deckone/starboard_eng) -"kl" = ( -/obj/machinery/light/small{ - dir = 4; - pixel_y = 0 - }, -/obj/structure/catwalk, -/turf/space, -/area/talon/maintenance/deckone_port) -"km" = ( -/obj/machinery/light/small{ - dir = 8; - pixel_y = 0 - }, -/obj/structure/catwalk, -/turf/space, -/area/talon/maintenance/deckone_starboard) "kr" = ( /obj/structure/barricade, /obj/structure/catwalk, @@ -1725,15 +2050,6 @@ /obj/structure/catwalk, /turf/simulated/floor/plating/eris/under, /area/talon/maintenance/deckone_starboard) -"mM" = ( -/obj/structure/catwalk, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/turf/space, -/area/talon/maintenance/deckone_port_fore_wing) "mN" = ( /obj/structure/catwalk, /obj/structure/cable/green{ @@ -1800,13 +2116,6 @@ }, /turf/simulated/floor/hull/airless, /area/talon/maintenance/deckone_port_aft_wing) -"nI" = ( -/obj/structure/catwalk, -/obj/structure/sign/warning/moving_parts{ - pixel_x = 30 - }, -/turf/space, -/area/talon/maintenance/deckone_port_fore_wing) "nN" = ( /obj/structure/cable/green{ d1 = 4; @@ -1816,20 +2125,6 @@ /obj/structure/catwalk, /turf/simulated/floor/plating/eris/under, /area/talon/maintenance/deckone_starboard) -"nR" = ( -/obj/structure/catwalk, -/obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction{ - dir = 4; - icon_state = "intact" - }, -/turf/space, -/area/talon/maintenance/deckone_starboard_fore_wing) -"nS" = ( -/obj/structure/table/rack/shelf/steel, -/obj/item/weapon/tank/jetpack/carbondioxide, -/obj/item/weapon/tank/jetpack/carbondioxide, -/turf/simulated/floor/tiled/eris/dark/danger, -/area/talon/deckone/secure_storage) "nT" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, @@ -2200,11 +2495,6 @@ }, /turf/simulated/floor/tiled/eris/steel, /area/talon/deckone/central_hallway) -"sb" = ( -/obj/structure/table/rack/shelf/steel, -/obj/item/clothing/shoes/magboots, -/turf/simulated/floor/tiled/eris/dark/danger, -/area/talon/deckone/secure_storage) "sc" = ( /obj/structure/cable/green{ d1 = 1; @@ -2453,15 +2743,6 @@ }, /turf/simulated/floor/hull/airless, /area/talon/maintenance/deckone_starboard_aft_wing) -"up" = ( -/obj/effect/floor_decal/industrial/outline/grey, -/obj/machinery/atmospherics/portables_connector/aux{ - dir = 8; - icon_state = "map_connector-aux" - }, -/obj/machinery/portable_atmospherics/canister/air/airlock, -/turf/simulated/floor/tiled/eris/steel/gray_perforated, -/area/talon/deckone/starboard_eng) "ur" = ( /obj/structure/cable/green{ d1 = 4; @@ -2554,13 +2835,6 @@ }, /turf/simulated/floor/tiled/eris/dark/orangecorner, /area/talon/deckone/brig) -"vc" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/structure/table/standard, -/obj/item/clothing/mask/surgical, -/obj/item/clothing/suit/surgicalapron, -/turf/simulated/floor/tiled/eris/white/bluecorner, -/area/talon/deckone/medical) "vf" = ( /obj/machinery/atmospherics/pipe/simple/heat_exchanging{ dir = 5; @@ -2655,12 +2929,6 @@ }, /turf/simulated/floor/tiled/eris/white/golden, /area/talon/deckone/bridge) -"wz" = ( -/obj/structure/table/rack/steel, -/obj/machinery/camera/network/talon, -/obj/item/device/suit_cooling_unit, -/turf/simulated/floor/tiled/eris/dark/danger, -/area/talon/deckone/secure_storage) "wD" = ( /obj/machinery/power/terminal{ dir = 8; @@ -2865,15 +3133,6 @@ /obj/structure/table/standard, /turf/simulated/floor/tiled/eris/steel, /area/talon/deckone/brig) -"yn" = ( -/obj/structure/catwalk, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/turf/space, -/area/talon/maintenance/deckone_port_aft_wing) "yo" = ( /obj/structure/cable/green{ d1 = 1; @@ -2897,15 +3156,6 @@ }, /turf/simulated/floor/tiled/eris/white/gray_platform, /area/shuttle/talonboat) -"yy" = ( -/obj/structure/catwalk, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/turf/space, -/area/talon/maintenance/deckone_starboard_aft_wing) "yA" = ( /obj/effect/floor_decal/industrial/warning/dust{ dir = 1 @@ -2985,15 +3235,6 @@ }, /turf/simulated/floor/tiled/eris/steel, /area/talon/deckone/central_hallway) -"zt" = ( -/obj/machinery/alarm/talon{ - dir = 1; - pixel_y = -25 - }, -/obj/structure/table/rack/steel, -/obj/item/weapon/tank/oxygen, -/turf/simulated/floor/tiled/eris/dark/danger, -/area/talon/deckone/secure_storage) "zx" = ( /obj/structure/cable/green{ d2 = 2; @@ -3355,11 +3596,6 @@ }, /turf/simulated/floor/hull/airless, /area/talon/maintenance/deckone_port_fore_wing) -"Dq" = ( -/obj/structure/table/standard, -/obj/item/device/sleevemate, -/turf/simulated/floor/tiled/eris/white/bluecorner, -/area/talon/deckone/medical) "Dr" = ( /obj/machinery/atmospherics/pipe/simple/heat_exchanging{ dir = 6; @@ -3767,12 +4003,6 @@ /obj/machinery/door/firedoor/glass/talon, /turf/simulated/floor/tiled/eris/techmaint_panels, /area/talon/deckone/medical) -"GK" = ( -/obj/structure/table/standard, -/obj/item/device/defib_kit/loaded, -/obj/item/weapon/storage/belt/medical/emt, -/turf/simulated/floor/tiled/eris/white/bluecorner, -/area/talon/deckone/medical) "GL" = ( /obj/machinery/atmospherics/pipe/simple/heat_exchanging{ dir = 1; @@ -3801,10 +4031,6 @@ }, /turf/simulated/floor/hull/airless, /area/talon/maintenance/deckone_starboard_fore_wing) -"Hb" = ( -/obj/structure/catwalk, -/turf/space, -/area/talon/maintenance/deckone_starboard_fore_wing) "Hh" = ( /obj/machinery/atmospherics/unary/vent_pump/on, /obj/machinery/light_switch{ @@ -4100,14 +4326,6 @@ }, /turf/simulated/floor/reinforced/airless, /area/talon/deckone/port_eng) -"JM" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 10 - }, -/obj/structure/table/standard, -/obj/machinery/reagentgrinder, -/turf/simulated/floor/tiled/eris/white/bluecorner, -/area/talon/deckone/medical) "JP" = ( /obj/machinery/power/apc/talon{ dir = 4; @@ -4222,24 +4440,6 @@ /obj/machinery/vending/medical_talon, /turf/simulated/floor/tiled/eris/white/bluecorner, /area/talon/deckone/medical) -"Kx" = ( -/obj/machinery/airlock_sensor{ - dir = 4; - pixel_x = -28; - req_one_access = list(301) - }, -/obj/machinery/atmospherics/unary/vent_pump/aux{ - dir = 4; - icon_state = "map_vent_aux" - }, -/obj/effect/map_helper/airlock/atmos/chamber_pump, -/obj/effect/map_helper/airlock/sensor/chamber_sensor, -/obj/machinery/light/small{ - dir = 1; - icon_state = "bulb1" - }, -/turf/simulated/floor/tiled/eris/dark/gray_perforated, -/area/shuttle/talonboat) "KF" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, @@ -4329,26 +4529,6 @@ }, /turf/simulated/floor/tiled/eris/steel, /area/talon/deckone/central_hallway) -"Lm" = ( -/obj/structure/table/rack/steel, -/obj/item/clothing/suit/armor/combat, -/obj/item/clothing/head/helmet/combat, -/obj/item/clothing/under/syndicate/combat, -/obj/machinery/camera/network/talon, -/turf/simulated/floor/tiled/eris/white/danger, -/area/talon/deckone/armory) -"Lt" = ( -/obj/structure/catwalk, -/obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction{ - dir = 8; - icon_state = "intact" - }, -/obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction{ - dir = 8; - icon_state = "intact" - }, -/turf/space, -/area/talon/maintenance/deckone_port_fore_wing) "Ly" = ( /obj/effect/floor_decal/industrial/hatch/yellow, /obj/machinery/door/window/brigdoor/eastleft{ @@ -4545,18 +4725,6 @@ }, /turf/simulated/floor/plating/eris/under, /area/talon/maintenance/deckone_port) -"MJ" = ( -/obj/structure/catwalk, -/obj/structure/cable/green{ - icon_state = "1-8" - }, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/turf/simulated/floor/plating/eris/under, -/area/talon/maintenance/deckone_starboard) "ML" = ( /obj/structure/catwalk, /obj/structure/cable/green{ @@ -4726,11 +4894,6 @@ }, /turf/simulated/floor/tiled/eris/dark/cyancorner, /area/talon/deckone/bridge) -"Ou" = ( -/obj/structure/table/rack/shelf/steel, -/obj/item/weapon/tank/oxygen, -/turf/simulated/floor/tiled/eris/dark/danger, -/area/talon/deckone/secure_storage) "Ow" = ( /obj/machinery/atmospherics/pipe/simple/hidden/aux, /obj/machinery/alarm/talon{ @@ -4786,10 +4949,6 @@ /obj/structure/bedsheetbin, /turf/simulated/floor/tiled/eris/steel, /area/talon/deckone/brig) -"Pi" = ( -/obj/structure/catwalk, -/turf/space, -/area/talon/maintenance/deckone_port_fore_wing) "Pu" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, @@ -5221,13 +5380,6 @@ /obj/structure/disposalpipe/segment, /turf/simulated/floor/tiled/eris/steel, /area/talon/deckone/central_hallway) -"TN" = ( -/obj/structure/table/rack/steel, -/obj/item/clothing/suit/space/syndicate/black, -/obj/item/clothing/head/helmet/space/syndicate/black, -/obj/item/clothing/shoes/magboots, -/turf/simulated/floor/tiled/eris/white/danger, -/area/talon/deckone/armory) "TO" = ( /obj/machinery/atmospherics/pipe/simple/hidden/aux, /obj/machinery/alarm/talon{ @@ -5261,21 +5413,6 @@ /obj/item/clothing/accessory/holster/waist, /turf/simulated/floor/tiled/eris/white/danger, /area/talon/deckone/armory) -"Ue" = ( -/obj/structure/catwalk, -/obj/structure/sign/warning/moving_parts{ - pixel_x = -30 - }, -/turf/space, -/area/talon/maintenance/deckone_starboard_fore_wing) -"Ui" = ( -/obj/structure/catwalk, -/obj/structure/cable/green{ - dir = 1; - icon_state = "4-8" - }, -/turf/space, -/area/talon/maintenance/deckone_starboard_fore_wing) "Uq" = ( /obj/machinery/alarm/talon{ dir = 4; @@ -5561,19 +5698,6 @@ }, /turf/simulated/floor/plating/eris/under, /area/talon/maintenance/deckone_port) -"VZ" = ( -/obj/machinery/embedded_controller/radio/airlock/airlock_controller{ - dir = 8; - id_tag = "talon_boat"; - pixel_x = 28 - }, -/obj/machinery/atmospherics/unary/vent_pump/aux{ - dir = 8; - icon_state = "map_vent_aux" - }, -/obj/effect/map_helper/airlock/atmos/chamber_pump, -/turf/simulated/floor/tiled/eris/dark/gray_perforated, -/area/shuttle/talonboat) "Wo" = ( /obj/structure/grille, /obj/structure/window/reinforced/full, @@ -5836,10 +5960,6 @@ }, /turf/simulated/floor/tiled/eris/steel/techfloor_grid, /area/shuttle/talonboat) -"YS" = ( -/obj/structure/catwalk, -/turf/space, -/area/talon/maintenance/deckone_port_aft_wing) "YT" = ( /obj/machinery/alarm/talon{ dir = 1; @@ -5851,10 +5971,6 @@ }, /turf/simulated/floor/tiled/eris/dark/cyancorner, /area/talon/deckone/bridge) -"Za" = ( -/obj/structure/catwalk, -/turf/space, -/area/talon/maintenance/deckone_starboard_aft_wing) "Zg" = ( /obj/structure/cable/yellow{ d1 = 1; @@ -13283,11 +13399,11 @@ vz qo sc Dh -YS -kl -fz -fo -YS +bi +bo +bx +bA +bi Dh Dh Dh @@ -13425,11 +13541,11 @@ lD Sc Km Dh -YS +bi aC TP aC -YS +bi Dh Dh Dh @@ -13562,22 +13678,22 @@ aa aa aa aa -YS -YS -YS -yn -YS -YS +bc +bi +bi +bm +bi +bi aC MH aC -YS -YS -YS -YS -YS -YS -YS +bi +bi +bi +bi +bi +bi +bc aa aa aa @@ -14257,11 +14373,11 @@ aa aa aa aa -Lt -nI -mM -Pi -Lt +aG +aI +aT +aZ +aG aa aC am @@ -14544,12 +14660,12 @@ am am am yC -GH +ay GH GH VY GH -iw +aA cl Se FQ @@ -14825,9 +14941,9 @@ aa aa ab ac -Ou +ax dQ -sb +aJ kN en aR @@ -14969,7 +15085,7 @@ ab ac wj kN -nS +aN kN LO aR @@ -15109,11 +15225,11 @@ ab ab ab ac -wz +aD kN sK kN -zt +aW aR aM aM @@ -15717,7 +15833,7 @@ YO YO mT lb -Kx +bq lb nc ki @@ -16001,7 +16117,7 @@ ht xu Kk lb -VZ +bs lb nc ki @@ -16249,7 +16365,7 @@ ZH if mj VN -ar +aX bQ jp aO @@ -16529,9 +16645,9 @@ ab ab ab ac -Lm +aE Fl -TN +aP Fl xd aY @@ -16569,7 +16685,7 @@ iN dL wk UN -Bj +bt Bj Bj ki @@ -16829,7 +16945,7 @@ co co Nm dO -fZ +av FA Gb Gb @@ -16951,8 +17067,8 @@ aa aa aa aa -aa -aa +aK +aK aK aO aY @@ -16972,9 +17088,9 @@ co qA dO xH -JM +aw Xd -vc +be eV dO uN @@ -17093,19 +17209,19 @@ aa aa aa aa -aa -aa -aK +ar +aF +bv sI Of qA mN -sL +az sL sL BD sL -MJ +aB co yN kz @@ -17235,8 +17351,8 @@ aa aa aa aa -aa -aa +aK +aK aK aK aK @@ -17256,10 +17372,10 @@ co qA dO NG -Gb +bb Gb qB -Dq +bf dO hD pz @@ -17381,11 +17497,11 @@ aa aa aa aa -nR -Ue -Ui -Hb -nR +aH +aS +aU +ba +aH aa aK qA @@ -17400,8 +17516,8 @@ dO dz Rk Gb -Gb -GK +bC +bh dO Gt SI @@ -17416,7 +17532,7 @@ gY NP ho iF -up +au yB Mi Bm @@ -18106,22 +18222,22 @@ aa aa aa aa -Za -Za -Za -yy -Za -Za +bd +bl +bl +bn +bl +bl aK xQ aK -Za -Za -Za -Za -Za -Za -Za +bl +bl +bl +bl +bl +bl +bd aa aa aa @@ -18253,11 +18369,11 @@ Eo QX UI Ru -Za +bl aK oU aK -Za +bl Ru Ru Ru @@ -18395,11 +18511,11 @@ Bs uo rL Ru -Za -km -fW -fy -Za +bl +bp +bz +bB +bl Ru Ru Ru diff --git a/maps/tether/submaps/offmap/talon2.dmm b/maps/tether/submaps/offmap/talon2.dmm index 9f30e789f90..1c3794d1d8f 100644 --- a/maps/tether/submaps/offmap/talon2.dmm +++ b/maps/tether/submaps/offmap/talon2.dmm @@ -109,6 +109,26 @@ "ap" = ( /turf/simulated/wall/rshull, /area/talon/decktwo/cap_room) +"aq" = ( +/obj/machinery/atmospherics/portables_connector/aux{ + dir = 1; + icon_state = "map_connector-aux" + }, +/obj/machinery/portable_atmospherics/canister/air/airlock, +/turf/simulated/floor/plating/eris/under, +/area/talon/maintenance/decktwo_aft) +"ar" = ( +/obj/structure/closet/secure_closet/personal/cabinet{ + locked = 0 + }, +/turf/simulated/floor/wood, +/area/talon/decktwo/eng_room) +"as" = ( +/obj/structure/closet/secure_closet/personal/cabinet{ + locked = 0 + }, +/turf/simulated/floor/wood, +/area/talon/decktwo/pilot_room) "at" = ( /turf/simulated/floor/tiled/eris/steel, /area/talon/decktwo/central_hallway) @@ -175,6 +195,18 @@ "aC" = ( /turf/simulated/wall, /area/talon/decktwo/cap_room) +"aD" = ( +/obj/structure/closet/secure_closet/personal/cabinet{ + locked = 0 + }, +/turf/simulated/floor/wood, +/area/talon/decktwo/med_room) +"aE" = ( +/obj/structure/closet/secure_closet/personal/cabinet{ + locked = 0 + }, +/turf/simulated/floor/wood, +/area/talon/decktwo/sec_room) "aF" = ( /obj/structure/bed/chair/bay/chair, /turf/simulated/floor/wood, @@ -193,6 +225,29 @@ }, /turf/simulated/floor/tiled/eris/white, /area/talon/decktwo/central_hallway) +"aI" = ( +/obj/structure/catwalk, +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/obj/machinery/light/small{ + dir = 4; + pixel_y = 0 + }, +/turf/simulated/floor/plating/eris/under, +/area/talon/maintenance/decktwo_port) +"aJ" = ( +/obj/machinery/atmospherics/pipe/simple/visible/supply{ + dir = 4 + }, +/obj/structure/catwalk, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/simulated/floor/plating/eris/under, +/area/talon/maintenance/decktwo_aft) "aK" = ( /turf/simulated/floor/carpet/blucarpet, /area/talon/decktwo/cap_room) @@ -207,6 +262,39 @@ "aM" = ( /turf/simulated/floor/wood, /area/talon/decktwo/cap_room) +"aN" = ( +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/atm{ + pixel_x = 32; + step_x = 0 + }, +/turf/simulated/floor/tiled/eris/steel, +/area/talon/decktwo/central_hallway) +"aO" = ( +/obj/machinery/airlock_sensor{ + dir = 4; + pixel_x = -28; + req_one_access = list(301) + }, +/obj/machinery/embedded_controller/radio/airlock/airlock_controller{ + dir = 8; + id_tag = "talon_aft_solar"; + pixel_x = 28; + req_one_access = list(301) + }, +/obj/effect/map_helper/airlock/atmos/chamber_pump, +/obj/effect/map_helper/airlock/sensor/chamber_sensor, +/obj/machinery/atmospherics/unary/vent_pump/high_volume/aux{ + dir = 1 + }, +/turf/simulated/floor/plating/eris/under, +/area/talon/maintenance/decktwo_aft) "aP" = ( /obj/machinery/alarm/talon{ dir = 4; @@ -220,12 +308,38 @@ "aQ" = ( /turf/simulated/floor/wood, /area/talon/decktwo/bar) -"aV" = ( +"aR" = ( +/obj/structure/handrail{ + dir = 1 + }, +/turf/simulated/floor/hull/airless, +/area/talon/maintenance/decktwo_solars) +"aS" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 9; + pixel_y = 0 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 9 + }, +/obj/machinery/vending/food{ + dir = 1 + }, +/turf/simulated/floor/tiled/eris/steel/gray_perforated, +/area/talon/decktwo/bar) +"aT" = ( /obj/machinery/vending/coffee{ dir = 1 }, /turf/simulated/floor/tiled/eris/steel/gray_perforated, /area/talon/decktwo/bar) +"aU" = ( +/obj/machinery/vending/dinnerware{ + dir = 1; + icon_state = "dinnerware" + }, +/turf/simulated/floor/tiled/eris/steel/gray_perforated, +/area/talon/decktwo/bar) "aX" = ( /obj/structure/bed/chair/bay/chair{ dir = 1; @@ -550,13 +664,6 @@ }, /turf/simulated/open, /area/talon/decktwo/central_hallway) -"cn" = ( -/obj/machinery/vending/dinnerware{ - dir = 1; - icon_state = "dinnerware" - }, -/turf/simulated/floor/tiled/eris/steel/gray_perforated, -/area/talon/decktwo/bar) "cp" = ( /obj/structure/lattice, /obj/structure/cable/green{ @@ -981,10 +1088,6 @@ }, /turf/simulated/floor/wood, /area/talon/decktwo/eng_room) -"eE" = ( -/obj/structure/closet/secure_closet/personal/cabinet, -/turf/simulated/floor/wood, -/area/talon/decktwo/eng_room) "eF" = ( /obj/machinery/atmospherics/unary/vent_pump/on{ dir = 1 @@ -1012,10 +1115,6 @@ /obj/structure/closet/secure_closet/talon_pilot, /turf/simulated/floor/wood, /area/talon/decktwo/pilot_room) -"eJ" = ( -/obj/structure/closet/secure_closet/personal/cabinet, -/turf/simulated/floor/wood, -/area/talon/decktwo/pilot_room) "eK" = ( /obj/machinery/atmospherics/unary/vent_scrubber/on{ dir = 1 @@ -1336,10 +1435,6 @@ }, /turf/simulated/floor/wood, /area/talon/decktwo/med_room) -"ga" = ( -/obj/structure/closet/secure_closet/personal/cabinet, -/turf/simulated/floor/wood, -/area/talon/decktwo/med_room) "gb" = ( /obj/machinery/atmospherics/unary/vent_pump/on{ dir = 1 @@ -1354,10 +1449,6 @@ /obj/structure/closet/secure_closet/talon_guard, /turf/simulated/floor/wood, /area/talon/decktwo/sec_room) -"gd" = ( -/obj/structure/closet/secure_closet/personal/cabinet, -/turf/simulated/floor/wood, -/area/talon/decktwo/sec_room) "ge" = ( /obj/machinery/atmospherics/unary/vent_scrubber/on{ dir = 1 @@ -2075,14 +2166,6 @@ }, /turf/simulated/floor/tiled/eris/cafe, /area/talon/decktwo/bar) -"oA" = ( -/obj/machinery/atmospherics/portables_connector/aux{ - dir = 1; - icon_state = "map_connector-aux" - }, -/obj/machinery/portable_atmospherics/canister/air/airlock, -/turf/simulated/floor/plating/eris/under, -/area/talon/maintenance/decktwo_aft) "oJ" = ( /obj/structure/cable/green{ d1 = 4; @@ -2263,19 +2346,6 @@ }, /turf/simulated/floor/plating/eris/under, /area/talon/maintenance/decktwo_aft) -"rz" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 9; - pixel_y = 0 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 9 - }, -/obj/machinery/vending/food{ - dir = 1 - }, -/turf/simulated/floor/tiled/eris/steel/gray_perforated, -/area/talon/decktwo/bar) "rA" = ( /obj/structure/cable/yellow{ d1 = 2; @@ -2307,26 +2377,6 @@ }, /turf/simulated/floor/tiled/eris/steel, /area/talon/decktwo/central_hallway) -"rJ" = ( -/obj/machinery/airlock_sensor{ - dir = 4; - pixel_x = -28; - req_one_access = list(301) - }, -/obj/machinery/atmospherics/unary/vent_pump/aux{ - dir = 1; - icon_state = "map_vent_aux" - }, -/obj/machinery/embedded_controller/radio/airlock/airlock_controller{ - dir = 8; - id_tag = "talon_aft_solar"; - pixel_x = 28; - req_one_access = list(301) - }, -/obj/effect/map_helper/airlock/atmos/chamber_pump, -/obj/effect/map_helper/airlock/sensor/chamber_sensor, -/turf/simulated/floor/plating/eris/under, -/area/talon/maintenance/decktwo_aft) "rQ" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, @@ -12988,7 +13038,7 @@ Qt lx lx lx -lx +aI lx lx lx @@ -13279,7 +13329,7 @@ cc gZ gZ hu -WG +aJ mm ht ao @@ -13383,7 +13433,7 @@ aa aa aa pi -pi +aR ap ap ap @@ -13564,7 +13614,7 @@ PG aH hu RD -oA +aq ht ao zs @@ -13831,13 +13881,13 @@ dz dM ea eo -eE +ar dr eV fm fA fN -ga +aD eT gn gn @@ -14523,7 +14573,7 @@ As dX ay Rm -Gq +aN Gq Af Gq @@ -14559,7 +14609,7 @@ gC gT gS nj -rJ +aO pt DT pi @@ -15098,7 +15148,7 @@ WS VZ bI Uf -rz +aS aw cl cz @@ -15240,7 +15290,7 @@ Zn UY aQ vB -aV +aT aw cl cz @@ -15251,13 +15301,13 @@ dH dU eh ew -eJ +as du fb fs fG fT -gd +aE eZ gn gn @@ -15382,7 +15432,7 @@ UY ZF bJ bP -cn +aU aw ck cy @@ -15654,8 +15704,8 @@ aa aa aa aa -aa -aa +pi +aR ax ax ax @@ -15796,8 +15846,8 @@ aa aa aa aa -aa -aa +pi +pi pi pi pi @@ -15938,8 +15988,8 @@ aa aa aa aa -aa -aa +pi +pi pi pi pi @@ -16112,7 +16162,7 @@ Az QA QA QA -QA +AX QA QA QA diff --git a/maps/tether/submaps/om_ships/vespa.dmm b/maps/tether/submaps/om_ships/vespa.dmm index 12be67f2a2b..604a2749187 100644 --- a/maps/tether/submaps/om_ships/vespa.dmm +++ b/maps/tether/submaps/om_ships/vespa.dmm @@ -353,7 +353,7 @@ /turf/simulated/floor, /area/ship/expe/atmospherics) "bb" = ( -/obj/item/weapon/caution/cone, +/obj/item/clothing/head/cone, /turf/simulated/floor/tiled/techfloor, /area/ship/expe/maintenancerim) "bc" = ( diff --git a/maps/tether/tether-01-surface1.dmm b/maps/tether/tether-01-surface1.dmm index 15974d5c6c3..b3158fc4687 100644 --- a/maps/tether/tether-01-surface1.dmm +++ b/maps/tether/tether-01-surface1.dmm @@ -600,6 +600,23 @@ dir = 8; pixel_x = -24 }, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/obj/structure/cable{ + d1 = 2; + d2 = 4; + icon_state = "2-4" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/cyan, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 6 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 6 + }, /turf/simulated/floor/tiled, /area/tether/surfacebase/cargo/mining) "aaZ" = ( @@ -5431,6 +5448,14 @@ name = "Mining Maintenance Access"; req_one_access = list(48) }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/cyan, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/visible/scrubbers, /turf/simulated/floor/plating, /area/tether/surfacebase/cargo/mining) "ajc" = ( diff --git a/maps/tether/tether-05-station1.dmm b/maps/tether/tether-05-station1.dmm index f36d143c622..cbd1abc8b55 100644 --- a/maps/tether/tether-05-station1.dmm +++ b/maps/tether/tether-05-station1.dmm @@ -20737,7 +20737,7 @@ /area/engineering/workshop) "bZk" = ( /obj/effect/decal/cleanable/dirt, -/obj/item/weapon/caution/cone, +/obj/item/clothing/head/cone, /turf/simulated/floor, /area/vacant/vacant_restaurant_lower) "bZm" = ( diff --git a/maps/virgo/virgo-1.dmm b/maps/virgo/virgo-1.dmm index 070412998bd..b51e66dcab8 100644 --- a/maps/virgo/virgo-1.dmm +++ b/maps/virgo/virgo-1.dmm @@ -32,7 +32,7 @@ "aaF" = (/obj/machinery/power/solar{id = "portsolar"; name = "Port Solar Array"},/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/airless{icon_state = "solarpanel"},/area/solar/auxstarboard) "aaG" = (/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/airless,/area/solar/auxstarboard) "aaH" = (/obj/machinery/power/solar{id = "portsolar"; name = "Port Solar Array"},/obj/structure/cable/yellow{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/airless{icon_state = "solarpanel"},/area/solar/auxstarboard) -"aaI" = (/obj/item/weapon/caution/cone,/turf/simulated/floor,/area/maintenance/locker) +"aaI" = (/obj/item/clothing/head/cone,/turf/simulated/floor,/area/maintenance/locker) "aaJ" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/airless,/area/solar/auxstarboard) "aaK" = (/turf/simulated/floor,/area/maintenance/locker) "aaL" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/maintenance/auxsolarstarboard) @@ -1605,7 +1605,7 @@ "aES" = (/obj/effect/floor_decal/spline/plain{dir = 9},/turf/simulated/floor/water/pool,/area/crew_quarters/pool) "aET" = (/obj/effect/floor_decal/spline/plain{dir = 1},/turf/simulated/floor/water/deep/pool,/area/crew_quarters/pool) "aEU" = (/obj/structure/bed/chair{dir = 8},/turf/simulated/floor/tiled/freezer,/area/crew_quarters/pool) -"aEV" = (/obj/item/weapon/caution/cone,/turf/simulated/floor,/area/maintenance/pool) +"aEV" = (/obj/item/clothing/head/cone,/turf/simulated/floor,/area/maintenance/pool) "aEW" = (/obj/effect/decal/cleanable/blood,/turf/simulated/floor,/area/maintenance/pool) "aEX" = (/obj/machinery/light/small{dir = 4; pixel_y = 0},/turf/simulated/floor,/area/maintenance/pool) "aEY" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/obj/effect/floor_decal/corner/red{dir = 8},/obj/machinery/camera/network/security{c_tag = "SEC - Brig Port"; dir = 1},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/tiled,/area/security/brig) @@ -5564,7 +5564,7 @@ "ccZ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/hallway/secondary/medical_emergency_hallway) "cda" = (/obj/machinery/atmospherics/unary/vent_scrubber/on,/obj/effect/floor_decal/corner/pink{dir = 9},/turf/simulated/floor/tiled,/area/hallway/secondary/medical_emergency_hallway) "cdb" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/item/device/radio/intercom{dir = 4; name = "Station Intercom (General)"; pixel_x = 26},/obj/effect/floor_decal/corner/pink{dir = 6},/turf/simulated/floor/tiled,/area/hallway/secondary/medical_emergency_hallway) -"cdc" = (/obj/item/weapon/caution/cone,/turf/simulated/floor,/area/maintenance/medbay_aft) +"cdc" = (/obj/item/clothing/head/cone,/turf/simulated/floor,/area/maintenance/medbay_aft) "cdd" = (/obj/item/weapon/broken_bottle,/turf/simulated/floor,/area/maintenance/medbay_aft) "cde" = (/obj/structure/table/woodentable,/obj/item/weapon/material/ashtray/plastic,/obj/item/weapon/cigbutt/cigarbutt,/obj/random/maintenance/clean,/obj/random/maintenance/clean,/turf/simulated/floor,/area/maintenance/medbay_aft) "cdf" = (/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "medbayquar"; name = "Medbay Emergency Lockdown Shutters"; opacity = 0},/turf/simulated/floor,/area/maintenance/medbay_aft) diff --git a/nano/templates/disperser.tmpl b/nano/templates/disperser.tmpl deleted file mode 100644 index 08db5ed2baf..00000000000 --- a/nano/templates/disperser.tmpl +++ /dev/null @@ -1,91 +0,0 @@ -{{if data.faillink}} -
    - ERROR: Machine is incomplete, out of range, or misaligned! -
    -{{else}} -
    -

    Targeting

    -
    -
    -
    - {{:helper.link('', 'triangle-1-nw', { 'choose' : 9 }, data.overmapdir == 9 ? 'selected' : null, null)}} - {{:helper.link('', 'triangle-1-n', { 'choose' : 1 }, data.overmapdir == 1 ? 'selected' : null, null)}} - {{:helper.link('', 'triangle-1-ne', { 'choose' : 5 }, data.overmapdir == 5 ? 'selected' : null, null)}} -
    -
    - {{:helper.link('', 'triangle-1-w', { 'choose' : 8 }, data.overmapdir == 8 ? 'selected' : null, null)}} - {{:helper.link('', 'circle-close', { 'choose' : 0 }, data.overmapdir == 0 ? 'selected' : null, null)}} - {{:helper.link('', 'triangle-1-e', { 'choose' : 4 }, data.overmapdir == 4 ? 'selected' : null, null)}} -
    -
    - {{:helper.link('', 'triangle-1-sw', { 'choose' : 10 }, data.overmapdir == 10 ? 'selected' : null, null)}} - {{:helper.link('', 'triangle-1-s', { 'choose' : 2 }, data.overmapdir == 2 ? 'selected' : null, null)}} - {{:helper.link('', 'triangle-1-se', { 'choose' : 6 }, data.overmapdir == 6 ? 'selected' : null, null)}} -
    -
    -
    -
    -
    -

    Charge

    -
    - {{if data.nopower}} - At least one part of the machine is unpowered. - {{/if}} -
    - Charge Load Type -
    -
    - {{:data.chargeload}} -
    -
    - Cooldown -
    -
    - {{if data.next_shot == 0}} - Ready - {{else}} - {{:data.next_shot}} seconds -
    Warning: Do not fire during cooldown. - {{/if}} -
    -
    -
    -
    -
    -

    Calibration

    -
    -
    - {{:data.cal_accuracy}}% -
    -
    - {{:helper.link('Pre-Calibration', 'transfer-e-w', { 'skill_calibration' : 1 }, data.skill ? null : 'disabled', null)}} -

    - {{for data.calibration}} -
    - {{:helper.link(value, 'shuffle', { 'calibration' : index }, null, null)}} -
    -
    - {{/for}} -
    -
    -
    -

    Setup

    -
    -
    - Strength -
    -
    - {{:helper.link(data.strength, 'lightbulb', { 'strength' : 1 }, null, null)}} -
    -
    - Radius -
    -
    - {{:helper.link(data.range, 'arrow-4-diag', { 'range' : 1 }, null, null)}} -
    -
    -
    -
    -{{:helper.link("Fire", 'alert', { 'fire' : 1 }, null, null)}} -
    -{{/if}} \ No newline at end of file diff --git a/nano/templates/dnaforensics.tmpl b/nano/templates/dnaforensics.tmpl deleted file mode 100644 index efe69e6158a..00000000000 --- a/nano/templates/dnaforensics.tmpl +++ /dev/null @@ -1,45 +0,0 @@ -

    Machine Status

    -
    -
    - {{:helper.link(data.scanning ? 'Halt Scan' : 'Begin Scan', 'signal-diag', {'scanItem' : 1}, null)}} -
    -
    - {{:helper.link((data.lidstate ? 'Open Lid' : 'Close Lid'), (data.lidstate ? 'unlocked' : 'locked'), {'toggleLid' : 1}, null)}} -
    -
    - {{:helper.link('Eject item', 'eject', {'ejectItem' : 1}, (data.bloodsamp && !data.scanning) ? null : 'disabled')}} -
    -
    -

    Scanner

    -
    -
    Scan progress:
    -
    - {{:helper.displayBar(data.scan_progress, 0, 100, 'good')}} - {{:data.scan_progress}} % -
    -
    - {{if data.scan_progress >= 100}} - Scan completed successfully. - {{/if}} -
    -
    -
    -
    -
    Item:
    -
    - {{if data.bloodsamp}} - {{:data.bloodsamp}} - {{else}} - No item inserted - {{/if}} -
    -
    -
    -
    Heuristic analysis:
    -
    - {{if data.bloodsamp_desc}} - {{:data.bloodsamp_desc}} - {{/if}} -
    -
    -
    \ No newline at end of file diff --git a/nano/templates/engines_control.tmpl b/nano/templates/engines_control.tmpl deleted file mode 100644 index 2933b1cbe6e..00000000000 --- a/nano/templates/engines_control.tmpl +++ /dev/null @@ -1,110 +0,0 @@ -
    - {{:helper.link('Overall info', 'note', {'state' :'status'}, null, data.state == 'status' ? 'selected' : null)}} - {{:helper.link('Details', 'note', {'state' : 'engines'}, null, data.state == 'engines' ? 'selected' : null)}} -
    -
    -
    -
    - Global controls: -
    -
    - {{:helper.link(data.global_state ? 'Shut all down' : 'Power all up', 'power', {'global_toggle' : 1}, null, data.global_state ? 'selected' : null)}} -
    -
    -
    -
    - Volume limit: -
    -
    - {{:helper.link('', 'circle-plus', { 'global_limit' : 0.1}, null, null)}} - {{:helper.link(data.global_limit+'%', null, { 'set_global_limit' : 1 }, null, null)}} - {{:helper.link('', 'circle-minus', { 'global_limit' : -0.1}, null, null)}} -
    -
    -
    -
    - Total thrust: -
    -
    - {{:data.total_thrust}} -
    -
    -
    -{{if data.state == "engines"}} - {{if data.engines_info}} - {{for data.engines_info}} -
    -
    - Engine #{{:(index + 1)}}: -
    -
    - {{:helper.link(value.eng_on ? 'Shutdown' : 'Power up', 'power', { 'toggle' : 1, 'engine' : value.eng_reference }, null, value.eng_on ? value.eng_on == 1 ? 'linkOn' : 'yellowButton' : null)}} -
    -
    -
    -
    - Type: -
    -
    - {{:value.eng_type}} -
    -
    -
    -
    - Status: -
    -
    - {{:value.eng_on ? value.eng_on == 1 ? 'Online' : 'Booting' : 'Offline'}}
    - {{:value.eng_status}} -
    -
    -
    -
    - Current thrust: -
    -
    - {{:value.eng_thrust}} -
    -
    -
    -
    - Volume limit: -
    -
    - {{:helper.link('', 'circle-plus', { 'limit' : 0.1, 'engine' : value.eng_reference }, null, null)}} - {{:helper.link(value.eng_thrust_limiter+'%', null, { 'set_limit' : 1, 'engine' : value.eng_reference }, null, null)}} - {{:helper.link('', 'circle-minus', { 'limit' : -0.1, 'engine' : value.eng_reference }, null, null)}} -
    -
    -
    - {{/for}} - {{/if}} -{{/if}} -{{if data.state == "status"}} - {{if data.engines_info}} - {{for data.engines_info}} -
    -
    -
    - Engine #{{:(index + 1)}}: -
    -
    - {{:helper.link(value.eng_on ? 'Shutdown' : 'Power up', 'power', { 'toggle' : 1, 'engine' : value.eng_reference }, null, value.eng_on ? value.eng_on == 1 ? 'linkOn' : 'yellowButton' : null)}} -
    -
    -
    -
    - Thrust: -
    - Volume limit: -
    -
    - {{:value.eng_thrust}} -
    - {{:value.eng_thrust_limiter}}% -
    -
    -
    - {{/for}} - {{/if}} -{{/if}} \ No newline at end of file diff --git a/nano/templates/flight.tmpl b/nano/templates/flight.tmpl deleted file mode 100644 index 60d4cd605a5..00000000000 --- a/nano/templates/flight.tmpl +++ /dev/null @@ -1,241 +0,0 @@ -{{if data.autopilot == 1}} -
    -

    AI PILOT (CLASS D) ACTIVE

    - This vessel will start and stop automatically.
    - Ensure that all non-cycling capable hatches and doors are closed, as the automated system may not be able to control them.
    - Docking and flight controls are locked. To unlock, disable the automated flight system.

    -
    -{{/if}} - -{{if data.can_rename == 1}} -
    -
    -
    - {{:helper.link('Rename', 'pencil', {"rename_command" : 1})}} -
    -
    -
    -{{/if}} - -

    Shuttle Status

    -{{if data.is_moving == 0}} -
    -
    - Current Location: -
    -
    - {{:data.shuttle_location}} -
    -
    -{{/if}} - -
    -
    -
    - Engines: -
    -
    - {{if data.shuttle_state == "idle"}} - IDLE - {{else data.shuttle_state == "warmup"}} - SPINNING UP - {{else data.shuttle_state == "in_transit"}} - ENGAGED - {{else}} - ERROR - {{/if}} -
    -
    -
    - -{{if data.is_moving == 0}} - - {{if data.skip_docking == 0}} -
    -
    -
    - Docking Status: -
    -
    - {{if data.docking_status == "docked"}} - DOCKED - {{else data.docking_status == "docking"}} - {{if !data.docking_override}} - DOCKING - {{else}} - DOCKING-MANUAL - {{/if}} - {{else data.docking_status == "undocking"}} - {{if !data.docking_override}} - UNDOCKING - {{else}} - UNDOCKING-MANUAL - {{/if}} - {{else data.docking_status == "undocked"}} - UNDOCKED - {{else}} - ERROR - {{/if}} - - - {{:helper.link('Dock', 'arrowthickstop-1-e', {'dock_command' : 1}, (data.docking_status != "undocked")? 'selected' : null)}} - {{:helper.link('Undock', 'arrowthickstop-1-e', {'undock_command' : 1}, (data.docking_status != "docked")? 'selected' : null)}} -
    - -
    - -
    -
    - {{/if}} - - {{if data.can_cloak == 1}} -
    -
    - Shuttle Stealth System: -
    - - {{:helper.link('Cloak', 'radio-off', {'cloak_command' : 1}, (data.cloaked == 1)? 'selected' : null)}} - {{:helper.link('Uncloak', 'radio-on', {'uncloak_command' : 1}, (data.cloaked == 0)? 'selected' : null)}} -
    -
- {{/if}} - - {{if data.can_autopilot == 1}} -
-
- Automated Flight Control: -
- - {{:helper.link('On', 'circle-check', {'autopilot_on_command' : 1}, (data.autopilot == 1)? 'selected' : null)}} - {{:helper.link('Off', 'circle-close ', {'autopilot_off_command' : 1}, (data.autopilot == 0)? 'selected' : null)}} -
- - {{/if}} - -{{/if}} - -{{if data.is_moving == 0}} -

Available Destinations

-
-

- {{for data.routes}} -
-
- {{:value.name}} -
-
-
- {{:helper.link(value.travel_time, 'clock', {"traverse" : value.index})}} -
-
-
- {{/for}} - -{{/if}} - -{{if data.is_in_transit == 1}} -

Destination ETA

-
-
- Distance from target: -
-
- {{:helper.displayBar(data.travel_progress, 0, 100, "good")}} -
- {{:data.time_left}}s -
-
-
-{{/if}} - -{{if data.doors}} -

Hatch Status

-
-
- {{props data.doors}} -
-
{{:key}}
-
- {{if value.open}} - OPN - {{else}} - CLS - {{/if}} - - - {{if value.bolted}} - BLT - {{else}} - UBLT - {{/if}} -
-
- {{/props}} -
-{{/if}} - -{{if data.sensors}} -

Air Readout

-
- {{props data.sensors}} -
-
- {{:key}} -
-
- {{if value.reading == 1}} -
- Pressure: -
-
- {{:helper.string('{1} kPa', value.pressure < 80 || value.pressure > 120 ? 'bad' : value.pressure < 95 || value.pressure > 110 ? 'average' : 'good' , value.pressure)}} -
-
- Temperature: -
-
- {{:helper.string('{1} °C', value.temp < 5 || value.temp > 35 ? 'bad' : value.temp < 15 || value.temp > 25 ? 'average' : 'good' , value.temp)}} -
-
-
- Oxygen: -
-
- {{:helper.string('{1}%', value.oxygen < 17 ? 'bad' : value.oxygen < 19 ? 'average' : 'good' , value.oxygen)}} -
-
- Nitrogen: -
-
- {{:helper.string('{1}%', value.nitrogen > 82 ? 'bad' : value.nitrogen > 80 ? 'average' : 'good' , value.nitrogen)}} -
-
- Carbon Dioxide: -
-
- {{:helper.string('{1}%', value.carbon_dioxide > 5 ? 'bad' : 'good' , value.carbon_dioxide)}} -
-
- Phoron: -
-
- {{:helper.string('{1}%', value.phoron > 0 ? 'bad' : 'good' , value.phoron)}} - -
- {{if value.other > 0}} -
- Unknown: -
-
- {{:value.other}}% -
- {{/if}} - {{else}} -
- Unable to get air reading -
- {{/if}} -
-
- {{/props}} -{{/if}} - diff --git a/nano/templates/helm.tmpl b/nano/templates/helm.tmpl deleted file mode 100644 index 2d371b11540..00000000000 --- a/nano/templates/helm.tmpl +++ /dev/null @@ -1,159 +0,0 @@ - - - -
-
- Flight data -
-
- ETA to next grid: -
-
- {{:data.ETAnext}} -
-
-
-
- Speed: -
-
- {{:data.speed}} Gm/h -
-
-
-
- Acceleration: -
-
- {{:data.accel}} Gm/h -
-
-
-
- Heading: -
-
- {{:data.heading}}° -
-
-
-
- Acceleration limiter: -
-
- {{:helper.link(data.accellimit, null, { 'accellimit' : 1}, null, null)}} Gm/h -
-
-
-
- -
-
- Manual control -
-
- {{:helper.link('', 'triangle-1-nw', { 'move' : 9 }, data.canburn ? null : 'disabled', null)}} - {{:helper.link('', 'triangle-1-n', { 'move' : 1 }, data.canburn ? null : 'disabled', null)}} - {{:helper.link('', 'triangle-1-ne', { 'move' : 5 }, data.canburn ? null : 'disabled', null)}} -
-
- {{:helper.link('', 'triangle-1-w', { 'move' : 8 }, data.canburn ? null : 'disabled', null)}} - {{:helper.link('', 'circle-close', { 'brake' : 1 }, data.canburn ? null : 'disabled', null)}} - {{:helper.link('', 'triangle-1-e', { 'move' : 4 }, data.canburn ? null : 'disabled', null)}} -
-
- {{:helper.link('', 'triangle-1-sw', { 'move' : 10 }, data.canburn ? null : 'disabled', null)}} - {{:helper.link('', 'triangle-1-s', { 'move' : 2 }, data.canburn ? null : 'disabled', null)}} - {{:helper.link('', 'triangle-1-se', { 'move' : 6 }, data.canburn ? null : 'disabled', null)}} -
- -
- Direct control -
- {{:helper.link(data.manual_control ? 'Engaged' : 'Disengaged', 'shuffle', { 'manual' : 1 }, null, data.manual_control ? 'selected' : null)}} -
-
-
-
- -
-
- Autopilot -
-
- Target: -
-
- {{if data.dest}} - {{:helper.link(data.d_x, null, { 'setx' : 1 }, null, null)}} {{:helper.link(data.d_y, null, { 'sety' : 1 }, null, null)}} - {{else}} - {{:helper.link('None', null, { 'sety' : 1, 'setx' : 1 }, null, null)}} - {{/if}} -
-
-
-
- Speed limit: -
-
- {{:helper.link(data.speedlimit, null, { 'speedlimit' : 1 }, null, null)}} Gm/h -
-
-
- {{:helper.link(data.autopilot ? 'Engaged' : 'Disengaged', 'gear', { 'apilot' : 1 }, data.dest ? null : 'disabled', data.autopilot ? 'selected' : null)}} -
-
-
- -
-

Navigation data

-
-
- Location: -
-
- {{:data.sector}} -
-
-
-
- Coordinates: -
-
- {{:data.s_x}} : {{:data.s_y}} -
-
-
-
- Scan data: -
-
- {{:data.sector_info}} -
-
-
-
- Status: -
-
- {{:data.landed}} -
-
-
- {{:helper.link('Save current position', 'disk', { 'add' : 'current' }, null)}} - {{:helper.link('Add new entry', 'document', { 'add' : 'new' }, null)}} -
-
- -
NameCoordinatesActions - {{for data.locations}} -
{{:value.name}} - {{:value.x}} : {{:value.y}} - {{:helper.link('Plot course', 'arrowreturnthick-1-e', { 'x' : value.x, 'y' : value.y }, null, null)}} - {{:helper.link('Remove', 'close', { 'remove' : value.reference }, null, null)}} - {{/for}} -
-
-
- - \ No newline at end of file diff --git a/nano/templates/nav.tmpl b/nano/templates/nav.tmpl deleted file mode 100644 index 6b5f5a96280..00000000000 --- a/nano/templates/nav.tmpl +++ /dev/null @@ -1,59 +0,0 @@ -

Navigation

-
-
-
-
- Map view - {{:helper.link(data.viewing ? 'Engaged' : 'Disengaged', 'shuffle', { 'viewing' : 1 }, null, data.viewing ? 'selected' : null)}} -
-
-
-
-
-

Sector information

-
- {{:data.sector}} -
- Coordinates: {{:data.s_x}} : {{:data.s_y}} -
- Additional information: {{:data.sector_info}} -
-
- -
-

Flight data

-
-
-
- ETA to next grid: -
-
- {{:data.ETAnext}} -
-
-
-
- Speed: -
-
- {{:data.speed}} Gm/h -
-
-
-
- Acceleration: -
-
- {{:data.accel}} Gm/h -
-
-
-
- Heading: -
-
- {{:data.heading}}° -
-
-
-
\ No newline at end of file diff --git a/nano/templates/pointdefense_control.tmpl b/nano/templates/pointdefense_control.tmpl deleted file mode 100644 index 19f85d3dba9..00000000000 --- a/nano/templates/pointdefense_control.tmpl +++ /dev/null @@ -1,54 +0,0 @@ -

Fire Assist Mainframe: {{:data.id || "[no tag]"}}

-{{if !(data.id)}} -
- This system has not been assigned an ident tag. Please contact your system administrator or conduct a manual update with a standard multitool. -
- {{/if}} -{{for data.turrets}} -

{{:value.id}}

-
-
- Battery status -
-
- {{if value.active}} - Online {{:helper.link('Shut down', null, {'toggle_active': value.ref})}} - {{else}} - Offline {{:helper.link('Start up', null, {'toggle_active': value.ref})}} - {{/if}} -
-
-
-
- Effective range -
-
- {{:value.effective_range}} -
-
-
-
- Reaction wheel delay -
-
- {{:value.reaction_wheel_delay}} -
-
-
-
- Recharge time -
-
- {{:value.recharge_time}} -
-{{empty}} -
-
- Error: -
-
- No weapon systems detected. Please check network connection. -
-
-
-{{/for}} diff --git a/nano/templates/request_console.tmpl b/nano/templates/request_console.tmpl deleted file mode 100644 index 5750bbe2b07..00000000000 --- a/nano/templates/request_console.tmpl +++ /dev/null @@ -1,123 +0,0 @@ - - -{{if data.screen == 1}} -

Request assistance from another department.

- - {{for data.assist_dept}} - {{if value != data.department}} - - - - - - {{/if}} - {{empty}} - - {{/for}} -
{{:value}} -
{{:helper.link('Message', null, { 'write' : value , 'priority' : 1 })}}
{{:helper.link('High Priority', null, { 'write' : value , 'priority' : 2 })}}
There are no available departments to request assistance from.

-
{{:helper.link('Back', 'arrowreturnthick-1-w', { 'setScreen' : 0 })}}
-{{else data.screen == 2}} -

Request supplies from another department.

- - {{for data.supply_dept}} - {{if value != data.department}} - - - - - - {{/if}} - {{empty}} - - {{/for}} -
{{:value}} -
{{:helper.link('Message', null, { 'write' : value , 'priority' : 1 })}}
{{:helper.link('High Priority', null, { 'write' : value , 'priority' : 2 })}}
There are no available departments to request supplies from.

-
{{:helper.link('Back', 'arrowreturnthick-1-w', { 'setScreen' : 0 })}}
-{{else data.screen == 3}} -

Relay info to another department.

- - {{for data.info_dept}} - {{if value != data.department}} - - - - - - {{/if}} - {{empty}} - - {{/for}} -
{{:value}} -
{{:helper.link('Message', null, { 'write' : value , 'priority' : 1 })}}
{{:helper.link('High Priority', null, { 'write' : value , 'priority' : 2 })}}
There are no available departments to relay information to.

-
{{:helper.link('Back', 'arrowreturnthick-1-w', { 'setScreen' : 0 })}}
-{{else data.screen == 4}} -
Message sent successfully.
-
{{:helper.link('Continue', 'arrowthick-1-e', { 'setScreen' : 0 })}}
-{{else data.screen == 5}} -
An Error occured. Message not sent.
-
{{:helper.link('Continue', 'arrowthick-1-e', { 'setScreen' : 0 })}}
-{{else data.screen == 6}} -
- {{for data.message_log}} -
{{:value}}
-
{{:helper.link('Print', null, { 'print' : index + 1 })}}
- {{empty}} -
No messages have been received.
- {{/for}} -
-
{{:helper.link('Back', 'arrowreturnthick-1-w', { 'setScreen' : 0 })}}
-{{else data.screen == 7}} -

Message Authentication


-
-
Message for {{:data.recipient}}: {{:data.message}}
-
Validated by: {{:data.msgVerified}}
-
Stamped by: {{:data.msgStamped}}
-
-
- {{:helper.link('Send Message', 'arrowthick-1-e', { 'department' : data.recipient })}} - {{:helper.link('Back', 'arrowreturnthick-1-w', { 'setScreen' : 0 })}} -
-{{else data.screen == 8}} -

Station wide announcement

-
Message: {{:data.message}} {{:helper.link('Write Message', 'pencil', { 'writeAnnouncement' : 1 })}}
-
- {{if data.announceAuth}} -
ID verified. Authentication accepted.
- {{else}} -
Swipe your ID card to authenticate yourself.
- {{/if}} -
-
- {{:helper.link('Announce', 'signal-diag', { 'sendAnnouncement' : 1 }, (data.announceAuth && data.message) ? null : 'disabled' )}} - {{:helper.link('Back', 'arrowreturnthick-1-w', { 'setScreen' : 0 })}} -
-{{else}} - {{if data.newmessagepriority == 1}} -
There are new messages
- {{else data.newmessagepriority == 2}} -
NEW PRIORITY MESSAGES
- {{/if}} -
{{:helper.link('View Messages', data.newmessagepriority ? 'mail-closed' : 'mail-open', { 'setScreen' : 6 })}}
-
-
{{:helper.link('Request Assistance', 'gear', { 'setScreen' : 1 })}}
-
{{:helper.link('Request Supplies', 'gear', { 'setScreen' : 2 })}}
-
{{:helper.link('Relay Anonymous Information', 'gear', { 'setScreen' : 3})}}
-
- {{if data.announcementConsole}} -
{{:helper.link('Send Station-wide Announcement', 'signal-diag', { 'setScreen' : 8})}}
-
- {{/if}} -
{{:helper.link(data.silent ? 'Speaker OFF' : 'Speaker ON', data.silent ? 'volume-off' : 'volume-on', { 'toggleSilent' : 1})}}
-{{/if}} \ No newline at end of file diff --git a/nano/templates/shield_generator.tmpl b/nano/templates/shield_generator.tmpl deleted file mode 100644 index b93ddc62209..00000000000 --- a/nano/templates/shield_generator.tmpl +++ /dev/null @@ -1,158 +0,0 @@ -{{if data.offline_for}} -

EMERGENCY SHUTDOWN

- An emergency shutdown has been initiated - generator cooling down
- Please wait until the generator cools down before resuming operation. Estimated time left: {{:data.offline_for}} seconds. -{{else}} -

SYSTEM STATUS

-
-
- Generator is: -
-
- {{if data.running == 2}} - {{if data.overloaded}} - Recovering - {{else}} - Active - {{/if}} - {{else data.running == 1}} - Shutting Down - {{else data.running == 3}} - Inactive - {{else data.running == 4}} - Spinning Up  - {{if data.target_radius != data.field_radius}} - (Adjusting Radius) - {{else}} - ({{:data.spinup_counter * 2}}s) - {{/if}} - {{else}} - Offline - {{/if}} -
-
-
-
- Energy Storage: -
-
- {{:data.current_energy}}/{{:data.max_energy}} MJ ({{:data.percentage_energy}}%) -
-
-
-
- Shield Integrity: -
-
- {{:data.field_integrity}}% -
-
-
-
- Mitigation: -
-
- {{:data.mitigation_em}}% EM / {{:data.mitigation_physical}}% PH / {{:data.mitigation_heat}}% HE / {{:data.mitigation_max}}% MAX -
-
-
-
- Upkeep Energy Use: -
-
- {{:data.upkeep_power_usage}} kW -
-
-
-
- Total Energy Use: -
-
- {{if data.input_cap_kw}} - {{:data.power_usage}} / {{:data.input_cap_kw}} kW - {{else}} - {{:data.power_usage}} kW (No Limit) - {{/if}} -
-
-
-
- Field Size: -
-
- {{:data.functional_segments}} / {{:data.total_segments}} m2 (radius {{:data.field_radius}}, target {{:data.target_radius}}) -
-
-

CONTROLS

- - - {{if (data.running >= 2)}} - - {{else}} - - {{/if}} - {{else}} - - - - -
{{:helper.link('Turn off', null, {'begin_shutdown' : '1'})}} - {{if (data.running == 3)}} - {{:helper.link('Activate', null, {'toggle_idle' : '0'})}} {{:helper.link('Deactivate', null, {'toggle_idle' : '1'})}} {{:helper.link('Turn on', null, {'start_generator' : '1'})}} - {{/if}} - {{if data.running}} - {{if data.hacked}} - {{:helper.link('EMERGENCY SHUTDOWN', null, {'emergency_shutdown' : '1'}, null, 'redButton')}} - {{/if}} - {{/if}} - -
{{:helper.link('Set Field Range', null, {'set_range' : '1'})}} - {{:helper.link('Set Input Cap', null, {'set_input_cap' : '1'})}} -
Set inactive power use intensity: - {{for data.idle_valid_values}} - {{:helper.link(value, null, {'switch_idle' : value}, (value == data.idle_multiplier) ? 'selected' : (data.running == 4 ? 'disabled' : null))}} - {{/for}} -
-

FIELD CALIBRATION

-
- {{for data.modes}} -
-
- Mode: -
-
- {{:value.name}} -
-
-
-
- Description: -
-
- {{:value.desc}} -
-
-
-
- Status: -
-
- {{if value.status}} - Enabled - {{else}} - Disabled - {{/if}} - {{:helper.link('Toggle', null, {'toggle_mode' : value.flag})}} -
-
-
-
- Multiplier: -
-
- {{:value.multiplier}} -
-
-
- {{/for}} -{{/if}} \ No newline at end of file diff --git a/nano/templates/shipsensors.tmpl b/nano/templates/shipsensors.tmpl deleted file mode 100644 index 5931fd01b24..00000000000 --- a/nano/templates/shipsensors.tmpl +++ /dev/null @@ -1,90 +0,0 @@ -

Sensors control console

-
- {{:helper.link(data.on ? 'Switch off' : 'Switch on', 'gear', { 'toggle' : 1 }, data.status != 'MISSING' ? null : 'disabled', data.on ? 'selected' : null)}} -
-
- Status: -
-
- {{:data.status}} -
-
-
-
- Range: -
-
- {{:helper.link(data.range, null, { 'range' : 1 }, null, null)}} -
-
-
-
-
-
- Integrity: -
-
- {{if data.health < (data.max_health * 0.25)}} - {{:helper.displayBar(data.health, 0, data.max_health, 'bad')}} -
{{:data.health}}/{{:data.max_health}} - {{else data.health < data.max_health *.75}} - {{:helper.displayBar(data.health, 0, data.max_health, 'average')}} -
{{:data.health}}/{{:data.max_health}} - {{else}} - {{:helper.displayBar(data.health, 0, data.max_health, 'good')}} -
{{:data.health}}/{{:data.max_health}} - {{/if}} -
-
-
-
- Temperature: -
-
- {{if data.heat < (data.critical_heat * 0.5)}} - {{:helper.displayBar(data.heat, 0, data.critical_heat, 'good')}} - {{else data.heat < (data.critical_heat * 0.75)}} - {{:helper.displayBar(data.heat, 0, data.critical_heat, 'average')}} - {{else}} - {{:helper.displayBar(data.heat, 0, data.critical_heat, 'bad')}} - {{/if}} -
-
- {{if data.heat < (data.critical_heat * 0.5)}} - Temperature low. - {{else data.heat < (data.critical_heat * 0.75)}} - Sensor temperature high! - {{else}} - TEMPERATURE CRITICAL: Disable or reduce power immediately! - {{/if}} -
-
-
-
-
-
- Sector map view - {{:helper.link(data.viewing ? 'Engaged' : 'Disengaged', 'shuffle', { 'viewing' : 1 }, null, data.viewing ? 'selected' : null)}} -
-
-
-

Sensor contacts

-
-{{if data.contacts}} - - {{for data.contacts}} - -
-
- - - - {{/for}} -
{{:helper.link('Scan', 'search' ,{ 'scan' : value.ref }, null, null)}}{{:value.name}}, bearing {{:value.bearing}}
-{{/if}} -
-{{if data.status == 'MISSING'}} -
- {{:helper.link('Link up with the sensor suite', 'gear', { 'link' : 1 }, data.status == 'MISSING' ? null : 'disabled', null)}} -
-{{/if}} diff --git a/nano/templates/shuttle_control_console.tmpl b/nano/templates/shuttle_control_console.tmpl deleted file mode 100644 index 05cae4ef092..00000000000 --- a/nano/templates/shuttle_control_console.tmpl +++ /dev/null @@ -1,72 +0,0 @@ -

Shuttle Status

-
-
- {{:data.shuttle_status}} -
-
-
-
-
- Bluespace Drive: -
-
- {{if data.shuttle_state == "idle"}} - IDLE - {{else data.shuttle_state == "warmup"}} - SPINNING UP - {{else data.shuttle_state == "in_transit"}} - ENGAGED - {{else}} - ERROR - {{/if}} -
-
-
-{{if data.has_docking}} -
-
-
- Docking Status: -
-
- {{if data.docking_status == "docked"}} - DOCKED - {{else data.docking_status == "docking"}} - {{if !data.docking_override}} - DOCKING - {{else}} - DOCKING-MANUAL - {{/if}} - {{else data.docking_status == "undocking"}} - {{if !data.docking_override}} - UNDOCKING - {{else}} - UNDOCKING-MANUAL - {{/if}} - {{else data.docking_status == "undocked"}} - UNDOCKED - {{else}} - ERROR - {{/if}} - -
-
- Docking Codes: -
-
- {{:helper.link(data.docking_codes ? data.docking_codes : 'Not set', null, {'set_codes' : '1'}, null , null)}} -
-
-
-{{/if}} - -

Shuttle Control

-
-
-
- {{:helper.link('Launch Shuttle', 'arrowthickstop-1-e', {'move' : '1'}, data.can_launch? null : 'disabled' , null)}} - {{:helper.link('Cancel Launch', 'cancel', {'cancel' : '1'}, data.can_cancel ? null : 'disabled' , null)}} - {{:helper.link('Force Launch', 'alert', {'force' : '1'}, data.can_force? null : 'disabled' , data.can_force ? 'redButton' : null)}} -
-
-
\ No newline at end of file diff --git a/nano/templates/shuttle_control_console_exploration.tmpl b/nano/templates/shuttle_control_console_exploration.tmpl deleted file mode 100644 index e368f484dba..00000000000 --- a/nano/templates/shuttle_control_console_exploration.tmpl +++ /dev/null @@ -1,95 +0,0 @@ -

Shuttle Status

-
-
- {{:data.shuttle_status}} -
-
-
-
-
- Engines: -
-
- {{if data.shuttle_state == "idle"}} - IDLE - {{else data.shuttle_state == "warmup"}} - SPINNING UP - {{else data.shuttle_state == "in_transit"}} - ENGAGED - {{else}} - ERROR - {{/if}} -
-
-
-{{if data.has_docking}} -
-
-
- Docking Status: -
-
- {{if data.docking_status == "docked"}} - DOCKED - {{else data.docking_status == "docking"}} - {{if !data.docking_override}} - DOCKING - {{else}} - DOCKING-MANUAL - {{/if}} - {{else data.docking_status == "undocking"}} - {{if !data.docking_override}} - UNDOCKING - {{else}} - UNDOCKING-MANUAL - {{/if}} - {{else data.docking_status == "undocked"}} - UNDOCKED - {{else}} - ERROR - {{/if}} -
-
- Docking Codes: -
-
- {{:helper.link(data.docking_codes ? data.docking_codes : 'Not set', null, {'set_codes' : '1'}, null , null)}} -
-
-
-{{/if}} -
-
- Current Destination: -
- {{:data.destination_name}} -
- {{:helper.link('Choose Destination', 'arrowreturn-1-s', {'pick' : '1'}, data.can_pick ? null : 'disabled' , null)}} -
-
-{{if data.fuel_usage}} -
-
- Est. Delta-V Budget: -
-
- {{:data.remaining_fuel}} m/s -
-
- Avg. Delta-V Per Maneuver: -
-
- {{:data.fuel_usage}} m/s -
-
-{{/if}} -

Shuttle Control

-
-
-
- {{:helper.link('Launch Shuttle', 'arrowthickstop-1-e', {'move' : '1'}, data.can_launch ? null : 'disabled' , null)}} - {{:helper.link('Cancel Launch', 'cancel', {'cancel' : '1'}, data.can_cancel ? null : 'disabled' , null)}} - {{:helper.link('Force Launch', 'alert', {'force' : '1'}, data.can_force ? null : 'disabled' , data.can_force ? 'redButton' : null)}} -
-
-
\ No newline at end of file diff --git a/nano/templates/shuttle_control_console_multi.tmpl b/nano/templates/shuttle_control_console_multi.tmpl deleted file mode 100644 index df25132bc7e..00000000000 --- a/nano/templates/shuttle_control_console_multi.tmpl +++ /dev/null @@ -1,84 +0,0 @@ -

Shuttle Status

-
-
- {{:data.shuttle_status}} -
- {{if data.can_cloak}} -
- {{:data.legit ? "ATC Inhibitor" : "Cloaking Field"}} is {{:data.cloaked ? "enabled" : "disabled"}}. {{:helper.link('Toggle', 'arrowreturn-1-s', {'toggle_cloaked' : '1'}) }} -
- {{/if}} -
-
-
-
- Bluespace Drive: -
-
- {{if data.shuttle_state == "idle"}} - IDLE - {{else data.shuttle_state == "warmup"}} - SPINNING UP - {{else data.shuttle_state == "in_transit"}} - ENGAGED - {{else}} - ERROR - {{/if}} -
-
-
-{{if data.has_docking}} -
-
-
- Docking Status: -
-
- {{if data.docking_status == "docked"}} - DOCKED - {{else data.docking_status == "docking"}} - {{if !data.docking_override}} - DOCKING - {{else}} - DOCKING-MANUAL - {{/if}} - {{else data.docking_status == "undocking"}} - {{if !data.docking_override}} - UNDOCKING - {{else}} - UNDOCKING-MANUAL - {{/if}} - {{else data.docking_status == "undocked"}} - UNDOCKED - {{else}} - ERROR - {{/if}} -
-
- Docking Codes: -
-
- {{:helper.link(data.docking_codes ? data.docking_codes : 'Not set', null, {'set_codes' : '1'}, null , null)}} -
-
-
-{{/if}} -
-
- Current Destination: -
- {{:data.destination_name}} -
- {{:helper.link('Choose Destination', 'arrowreturn-1-s', {'pick' : '1'}, data.can_pick ? null : 'disabled' , null)}} -
-
-

Shuttle Control

-
-
-
- {{:helper.link('Launch Shuttle', 'arrowthickstop-1-e', {'move' : '1'}, data.can_launch ? null : 'disabled' , null)}} - {{:helper.link('Cancel Launch', 'cancel', {'cancel' : '1'}, data.can_cancel ? null : 'disabled' , null)}} - {{:helper.link('Force Launch', 'alert', {'force' : '1'}, data.can_force ? null : 'disabled' , data.can_force ? 'redButton' : null)}} -
-
-
diff --git a/nano/templates/zone_console.tmpl b/nano/templates/zone_console.tmpl deleted file mode 100644 index cb7389f978e..00000000000 --- a/nano/templates/zone_console.tmpl +++ /dev/null @@ -1,83 +0,0 @@ -
-
-
- Scn. Ramestat Core: -
-
- {{:helper.displayBar(data.timeout_percent, 0, 100, (data.timeout_percent < 75) ? 'bad' : (data.timeout_percent < 100) ? 'average' : 'good')}} -
-
-
-
-
- Mineral Content: -
-
- {{:data.difficulty}} -
-
-
-
-
- Shuttle Location: -
-
- {{:data.shuttle_location}} -
- {{if data.can_recall_shuttle > 0}} -
- {{:helper.link('Recall Shuttle', 'alert-red', {'action' : 'recall_shuttle'}, null)}} -
- {{/if}} -
-{{if data.occupied > 0}} -
-
- WARNING: -
-
- Area Occupied by {{:data.occupied}} personnel! -
-
-{{/if}} - - -

Scanner Operation

-
-
- Scanner Activation: -
-
- {{:helper.link('Scan For Asteroids', 'power', {'action' : 'scan_for_new'}, data.scan_ready ? null : 'disabled')}} -
-
-{{if data.scanning > 0}} -
-
- Scanning: -
-
- In Progress... -
-
-{{/if}} -{{if data.updated > 0 && data.scanning == 0}} -
-
- Info: -
-
- Updated shuttle destination! -
-
-{{/if}} -{{if data.debug > 0}} -
-
- DEBUG: -
-
- TP:{{:data.timeout_percent}},DS:{{:data.diffstep}},D:{{:data.difficulty}},O:{{:data.occupied}},DBG:{{:data.debug}},SL:{{:data.shuttle_location}},SAS:{{:data.shuttle_at_station}},SR:{{:data.scan_ready}} -
-
-{{/if}} \ No newline at end of file diff --git a/sound/effects/clang2.ogg b/sound/effects/clang2.ogg new file mode 100644 index 00000000000..91b13eb2efa Binary files /dev/null and b/sound/effects/clang2.ogg differ diff --git a/sound/items/drop/papercup.ogg b/sound/items/drop/papercup.ogg new file mode 100644 index 00000000000..6bea17488f5 Binary files /dev/null and b/sound/items/drop/papercup.ogg differ diff --git a/sound/machines/honkbot_evil_laugh.ogg b/sound/machines/honkbot_evil_laugh.ogg new file mode 100644 index 00000000000..7b12edf8a32 Binary files /dev/null and b/sound/machines/honkbot_evil_laugh.ogg differ diff --git a/sound/machines/rig/rigservo.ogg b/sound/machines/rig/rigservo.ogg new file mode 100644 index 00000000000..3193acaff44 Binary files /dev/null and b/sound/machines/rig/rigservo.ogg differ diff --git a/sound/mecha/mech_shield_deflect.ogg b/sound/mecha/mech_shield_deflect.ogg new file mode 100644 index 00000000000..5c1970d8724 Binary files /dev/null and b/sound/mecha/mech_shield_deflect.ogg differ diff --git a/sound/mecha/mech_shield_drop.ogg b/sound/mecha/mech_shield_drop.ogg new file mode 100644 index 00000000000..21c6cb5edb9 Binary files /dev/null and b/sound/mecha/mech_shield_drop.ogg differ diff --git a/sound/mecha/mech_shield_raise.ogg b/sound/mecha/mech_shield_raise.ogg new file mode 100644 index 00000000000..65ad70ad14d Binary files /dev/null and b/sound/mecha/mech_shield_raise.ogg differ diff --git a/sound/weapons/parry.ogg b/sound/weapons/parry.ogg new file mode 100644 index 00000000000..ff60f3c8b8f Binary files /dev/null and b/sound/weapons/parry.ogg differ diff --git a/tgui/packages/tgui/format.js b/tgui/packages/tgui/format.js index db21025bdf4..2d5333d4f85 100644 --- a/tgui/packages/tgui/format.js +++ b/tgui/packages/tgui/format.js @@ -103,4 +103,14 @@ export const formatCommaNumber = value => { let parts = value.toString().split("."); parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ","); return parts.join("."); -}; \ No newline at end of file +}; + +// Function from https://stackoverflow.com/a/34841026. CC BY-SA 4.0. +export const formatTime = seconds => { + let hours = Math.floor(seconds / 3600); + let minutes = Math.floor(seconds / 60) % 60; + return [hours, minutes, seconds % 60] + .map(v => v < 10 ? "0" + v : v) + .filter((v, i) => v !== "00" || i > 0) + .join(":"); +}; diff --git a/tgui/packages/tgui/hotkeys.js b/tgui/packages/tgui/hotkeys.js index 0beff6b0288..2af94daef98 100644 --- a/tgui/packages/tgui/hotkeys.js +++ b/tgui/packages/tgui/hotkeys.js @@ -17,6 +17,10 @@ export const KEY_CTRL = 17; export const KEY_ALT = 18; export const KEY_ESCAPE = 27; export const KEY_SPACE = 32; +export const KEY_ARROWLEFT = 37; +export const KEY_ARROWUP = 38; +export const KEY_ARROWRIGHT = 39; +export const KEY_ARROWDOWN = 40; export const KEY_0 = 48; export const KEY_1 = 49; export const KEY_2 = 50; diff --git a/tgui/packages/tgui/interfaces/BrigTimer.js b/tgui/packages/tgui/interfaces/BrigTimer.js new file mode 100644 index 00000000000..f6461a51e06 --- /dev/null +++ b/tgui/packages/tgui/interfaces/BrigTimer.js @@ -0,0 +1,69 @@ +import { round } from 'common/math'; +import { Fragment } from 'inferno'; +import { useBackend } from '../backend'; +import { Button, Section, NumberInput, Flex } from '../components'; +import { Window } from '../layouts'; +import { formatTime } from '../format'; + +export const BrigTimer = (props, context) => { + const { act, data } = useBackend(context); + return ( + + +
+
+
+
+ ); +}; diff --git a/tgui/packages/tgui/interfaces/CameraConsole.js b/tgui/packages/tgui/interfaces/CameraConsole.js index 81ffd5d7b98..78ca9c4bf97 100644 --- a/tgui/packages/tgui/interfaces/CameraConsole.js +++ b/tgui/packages/tgui/interfaces/CameraConsole.js @@ -57,6 +57,7 @@ export const CameraConsole = (props, context) => { export const CameraConsoleContent = (props, context) => { const { act, data, config } = useBackend(context); + const { mapRef, activeCamera } = data; const cameras = selectCameras(data.cameras); const [ @@ -80,16 +81,16 @@ export const CameraConsoleContent = (props, context) => {
{ + const { act, data } = useBackend(context); + const { + scan_progress, + scanning, + bloodsamp, + bloodsamp_desc, + } = data; + return ( + + +
+ + + + }> + + + + + +
+
+ {bloodsamp && ( + + {bloodsamp} + + {bloodsamp_desc} + + + ) || ( + + No blood sample inserted. + + )} +
+
+
+ ); +}; \ No newline at end of file diff --git a/tgui/packages/tgui/interfaces/DestinationTagger.js b/tgui/packages/tgui/interfaces/DestinationTagger.js new file mode 100644 index 00000000000..5a70ede6d62 --- /dev/null +++ b/tgui/packages/tgui/interfaces/DestinationTagger.js @@ -0,0 +1,34 @@ +import { round } from 'common/math'; +import { Fragment } from 'inferno'; +import { useBackend } from "../backend"; +import { Box, Button, Flex, Icon, LabeledList, ProgressBar, Section, Table } from "../components"; +import { Window } from "../layouts"; + +export const DestinationTagger = (props, context) => { + const { act, data } = useBackend(context); + + const { + currTag, + taggerLocs, + } = data; + + return ( + + +
+ + {taggerLocs.sort().map(tag => ( + +
+
+
+ ); +}; \ No newline at end of file diff --git a/tgui/packages/tgui/interfaces/Gps.js b/tgui/packages/tgui/interfaces/Gps.js new file mode 100644 index 00000000000..f2549a31a50 --- /dev/null +++ b/tgui/packages/tgui/interfaces/Gps.js @@ -0,0 +1,133 @@ +import { map, sortBy } from 'common/collections'; +import { flow } from 'common/fp'; +import { clamp } from 'common/math'; +import { vecLength, vecSubtract } from 'common/vector'; +import { Fragment } from 'inferno'; +import { useBackend } from '../backend'; +import { Box, Button, Icon, LabeledList, Section, Table } from '../components'; +import { Window } from '../layouts'; + +import { createLogger } from '../logging'; +const logger = createLogger('lol what'); + +const coordsToVec = coords => map(parseFloat)(coords.split(', ')); + +export const Gps = (props, context) => { + const { act, data } = useBackend(context); + const { + currentArea, + currentCoords, + currentCoordsText, + globalmode, + power, + tag, + updating, + } = data; + const signals = flow([ + map((signal, index) => { + // Calculate distance to the target. BYOND distance is capped to 127, + // that's why we roll our own calculations here. + const dist = signal.dist && ( + Math.round(vecLength(vecSubtract( + currentCoords, + signal.coords))) + ); + return { ...signal, dist, index }; + }), + sortBy( + // Signals with distance metric go first + signal => signal.dist === undefined, + // Sort alphabetically + signal => signal.entrytag), + ])(data.signals || []); + return ( + + +
act('power')} /> + )}> + + +
+ {!!power && ( + +
+ + {currentArea} ({currentCoordsText}) + +
+
+ + + + + + + {signals.map(signal => ( + + + {signal.entrytag} + + + {signal.degrees !== undefined && ( + + )} + {signal.dist !== undefined && ( + signal.dist + 'm' + )} + + + {signal.coordsText} + + + ))} +
+
+
+ )} +
+
+ ); +}; diff --git a/tgui/packages/tgui/interfaces/IDCard.js b/tgui/packages/tgui/interfaces/IDCard.js index 59f2af4d9be..9883fbc88dc 100644 --- a/tgui/packages/tgui/interfaces/IDCard.js +++ b/tgui/packages/tgui/interfaces/IDCard.js @@ -158,14 +158,18 @@ export const IDCard = (props, context) => { overflow: "hidden", outline: "2px solid #4972a1", }}> - + {photo_front && ( + + ) || ( + + )} diff --git a/tgui/packages/tgui/interfaces/MiningOreProcessingConsole.js b/tgui/packages/tgui/interfaces/MiningOreProcessingConsole.js new file mode 100644 index 00000000000..f1a22fbe8be --- /dev/null +++ b/tgui/packages/tgui/interfaces/MiningOreProcessingConsole.js @@ -0,0 +1,145 @@ +import { toTitleCase } from 'common/string'; +import { Fragment } from 'inferno'; +import { useBackend, useLocalState } from "../backend"; +import { Box, Button, Collapsible, Dropdown, Flex, Input, NoticeBox, Section, LabeledList, AnimatedNumber } from '../components'; +import { Window } from "../layouts"; +import { refocusLayout } from '../layouts'; +import { sortBy } from 'common/collections'; +import { MiningUser } from './common/Mining'; + +export const MiningOreProcessingConsole = (props, context) => { + const { act, data } = useBackend(context); + + const { + unclaimedPoints, + ores, + showAllOres, + power, + } = data; + + return ( + + + + + in order to claim points. + + )} /> +
act("power")}> + {power ? "Smelting" : "Not Smelting"} + + }> + + act("claim")}> + Claim + + }> + + + +
+ +
+
+ ); +}; + +// ORDER IS IMPORTANT HERE. +const processingOptions = [ + "Not Processing", + "Smelting", + "Compressing", + "Alloying", +]; + +// Higher in the list == closer to top +// This is just kind of an arbitrary list to sort by because the machine has no predictable ore order in it's list +// and alphabetizing them doesn't really make sense +const oreOrder = [ + "verdantium", + "mhydrogen", + "diamond", + "platinum", + "uranium", + "gold", + "silver", + "rutile", + "phoron", + "marble", + "lead", + "sand", + "carbon", + "hematite", +]; + +const oreSorter = (a, b) => { + if (oreOrder.indexOf(a.ore) === -1) { + return a.ore - b.ore; + } + if (oreOrder.indexOf(b.ore) === -1) { + return a.ore - b.ore; + } + return oreOrder.indexOf(b.ore) - oreOrder.indexOf(a.ore); +}; + +const MOPCOres = (props, context) => { + const { act, data } = useBackend(context); + const { + ores, + showAllOres, + power, + } = data; + return ( +
act("showAllOres")}> + {showAllOres ? "All Ores" : "Ores in Machine"} + + }> + + {ores.length && ores.sort(oreSorter).map(ore => ( + act("toggleSmelting", { + ore: ore.ore, + set: processingOptions.indexOf(val), + })} /> + }> + + + + + )) || ( + + No ores in machine. + + )} + +
+ ); +}; \ No newline at end of file diff --git a/tgui/packages/tgui/interfaces/MiningStackingConsole.js b/tgui/packages/tgui/interfaces/MiningStackingConsole.js new file mode 100644 index 00000000000..0aac5ca35c9 --- /dev/null +++ b/tgui/packages/tgui/interfaces/MiningStackingConsole.js @@ -0,0 +1,51 @@ +import { toTitleCase } from 'common/string'; +import { Fragment } from 'inferno'; +import { useBackend, useLocalState } from "../backend"; +import { Box, Button, Collapsible, Dropdown, Flex, Input, NoticeBox, Section, LabeledList, AnimatedNumber, NumberInput } from '../components'; +import { Window } from "../layouts"; +import { sortBy } from 'common/collections'; + +export const MiningStackingConsole = (props, context) => { + const { act, data } = useBackend(context); + + const { + stacktypes, + stackingAmt, + } = data; + + return ( + + +
+ + + act("change_stack", { amt: val })} /> + + + {stacktypes.length && stacktypes.sort().map(stack => ( + act("release_stack", { stack: stack.type })}> + Eject + + }> + + + )) || ( + + No stacks in machine. + + )} + +
+
+
+ ); +}; diff --git a/tgui/packages/tgui/interfaces/MiningVendor.js b/tgui/packages/tgui/interfaces/MiningVendor.js new file mode 100644 index 00000000000..2b653faaaeb --- /dev/null +++ b/tgui/packages/tgui/interfaces/MiningVendor.js @@ -0,0 +1,179 @@ +import { createSearch } from 'common/string'; +import { Fragment } from 'inferno'; +import { useBackend, useLocalState } from "../backend"; +import { Box, Button, Collapsible, Dropdown, Flex, Input, NoticeBox, Section } from '../components'; +import { Window } from "../layouts"; +import { refocusLayout } from '../layouts'; +import { MiningUser } from './common/Mining'; + +const sortTypes = { + 'Alphabetical': (a, b) => a - b, + 'By availability': (a, b) => -(a.affordable - b.affordable), + 'By price': (a, b) => a.price - b.price, +}; + +export const MiningVendor = (props, context) => { + return ( + + + + + + + + ); +}; + + +const MiningVendorItems = (props, context) => { + const { act, data } = useBackend(context); + const { + has_id, + id, + items, + } = data; + // Search thingies + const [ + searchText, + _setSearchText, + ] = useLocalState(context, 'search', ''); + const [ + sortOrder, + _setSortOrder, + ] = useLocalState(context, 'sort', 'Alphabetical'); + const [ + descending, + _setDescending, + ] = useLocalState(context, 'descending', false); + const searcher = createSearch(searchText, item => { + return item[0]; + }); + + let has_contents = false; + let contents = Object.entries(items).map((kv, _i) => { + let items_in_cat = Object.entries(kv[1]) + .filter(searcher) + .map(kv2 => { + kv2[1].affordable = has_id && id.points >= kv2[1].price; + return kv2[1]; + }) + .sort(sortTypes[sortOrder]); + if (items_in_cat.length === 0) { + return; + } + if (descending) { + items_in_cat = items_in_cat.reverse(); + } + + has_contents = true; + return ( + + ); + }); + return ( + +
refocusLayout()}> + {has_contents + ? contents : ( + + No items matching your criteria was found! + + )} +
+
+ ); +}; + +const MiningVendorSearch = (props, context) => { + const [ + _searchText, + setSearchText, + ] = useLocalState(context, 'search', ''); + const [ + _sortOrder, + setSortOrder, + ] = useLocalState(context, 'sort', ''); + const [ + descending, + setDescending, + ] = useLocalState(context, 'descending', false); + return ( + + + + setSearchText(value)} + /> + + + setSortOrder(v)} /> + + + + + {calibration.map((cal, i) => ( + + Cal #{i}: + + + ))} + + + + +
+ + + + + + + + +
+
+ + + +
+ ); +}; \ No newline at end of file diff --git a/tgui/packages/tgui/interfaces/OvermapEngines.js b/tgui/packages/tgui/interfaces/OvermapEngines.js new file mode 100644 index 00000000000..5dd80a8b70c --- /dev/null +++ b/tgui/packages/tgui/interfaces/OvermapEngines.js @@ -0,0 +1,110 @@ +import { round } from 'common/math'; +import { Fragment } from 'inferno'; +import { useBackend } from "../backend"; +import { Box, Button, Flex, Icon, LabeledList, ProgressBar, Section, AnimatedNumber, Collapsible } from "../components"; +import { Window } from "../layouts"; + +export const OvermapEngines = (props, context) => { + const { act, data } = useBackend(context); + const { + global_state, // This indicates all engines being powered up or not + global_limit, // Global Thrust limit + engines_info, // Array of engines + total_thrust, // Total thrust of all engines together + } = data; + return ( + + +
+ + + + + + +
+
+ {engines_info.map((engine, i) => ( + + + + Engine #{i + 1} | + Thrust: | + Limit: val + "%"} /> + + // "Engine " + (i + 1) + // + " | Thrust: " + engine.eng_thrust + // + " | Limit: " + engine.eng_thrust_limiter + "%" + )}> +
+ + + {engine.eng_type} + + + + {engine.eng_on ? (engine.eng_on === 1 ? "Online" : "Booting") : "Offline"} + + {engine.eng_status.map(status => { + if (Array.isArray(status)) { + return {status[0]}; + } else { + return {status}; + } + })} + + + {engine.eng_thrust} + + + +
+
+
+ + + +
+ ))} +
+
+
+ ); +}; \ No newline at end of file diff --git a/tgui/packages/tgui/interfaces/OvermapHelm.js b/tgui/packages/tgui/interfaces/OvermapHelm.js new file mode 100644 index 00000000000..0ddd5112d6c --- /dev/null +++ b/tgui/packages/tgui/interfaces/OvermapHelm.js @@ -0,0 +1,235 @@ +import { round } from 'common/math'; +import { Fragment } from 'inferno'; +import { useBackend, useLocalState } from "../backend"; +import { Box, Button, Flex, Icon, LabeledList, ProgressBar, Section, Table } from "../components"; +import { Window } from "../layouts"; +import { OvermapFlightData, OvermapPanControls } from './common/Overmap'; + +export const OvermapHelm = (props, context) => { + const { act, data } = useBackend(context); + return ( + + + + + + + + + + + + + + + + + ); +}; + +export const OvermapFlightDataWrap = (props, context) => { + const { act, data } = useBackend(context); + + // While, yes, this is a strange choice to use fieldset over Section + // just look at how pretty the legend is, sticking partially through the border ;///; + return ( +
+ Flight Data + +
+ ); +}; + +const OvermapManualControl = (props, context) => { + const { act, data } = useBackend(context); + + const { + canburn, + manual_control, + } = data; + + return ( +
+ Manual Control + + + + + + + + Direct Control + + + +
+ ); +}; + +const OvermapAutopilot = (props, context) => { + const { act, data } = useBackend(context); + const { + dest, + d_x, + d_y, + speedlimit, + autopilot, + autopilot_disabled, + } = data; + + if (autopilot_disabled) { + return ( +
+ Autopilot + + AUTOPILOT DISABLED + + + Warning: This vessel is equipped with a class I autopilot. + Class I autopilots are unable to do anything but fly in a + straight line directly towards the target, and may result in + collisions. + + + act("apilot_lock")} /> + +
+ ); + } + + return ( +
+ Autopilot + + + {dest && ( + + + + + ) || ( + + )} + + + + + + + +
+ ); +}; + +const OvermapNavComputer = (props, context) => { + const { act, data } = useBackend(context); + + const { + sector, + s_x, + s_y, + sector_info, + landed, + locations, + } = data; + + return ( +
+ + + {sector} + + + {s_x} : {s_y} + + + {sector_info} + + + {landed} + + + + + + + + + + +
+ + + Name + Coordinates + Actions + + {locations.map(loc => ( + + {loc.name} + {loc.x} : {loc.y} + + + + + + ))} +
+
+
+ ); +}; \ No newline at end of file diff --git a/tgui/packages/tgui/interfaces/OvermapNavigation.js b/tgui/packages/tgui/interfaces/OvermapNavigation.js new file mode 100644 index 00000000000..48215060abb --- /dev/null +++ b/tgui/packages/tgui/interfaces/OvermapNavigation.js @@ -0,0 +1,54 @@ +import { round } from 'common/math'; +import { Fragment } from 'inferno'; +import { useBackend } from "../backend"; +import { Box, Button, Flex, Icon, LabeledList, ProgressBar, Section } from "../components"; +import { Window } from "../layouts"; +import { OvermapFlightData } from "./common/Overmap"; + +export const OvermapNavigation = (props, context) => { + return ( + + + + + + ); +}; + +export const OvermapNavigationContent = (props, context) => { + const { act, data } = useBackend(context); + const { + sector, + s_x, + s_y, + sector_info, + viewing, + } = data; + return ( + +
act("viewing")}> + Map View + + }> + + + {sector} + + + {s_x} : {s_y} + + + {sector_info} + + +
+
+ +
+
+ ); +}; diff --git a/tgui/packages/tgui/interfaces/OvermapShieldGenerator.js b/tgui/packages/tgui/interfaces/OvermapShieldGenerator.js new file mode 100644 index 00000000000..11236f8ab07 --- /dev/null +++ b/tgui/packages/tgui/interfaces/OvermapShieldGenerator.js @@ -0,0 +1,212 @@ +import { round } from 'common/math'; +import { Fragment } from 'inferno'; +import { useBackend, useLocalState } from "../backend"; +import { Box, Button, Flex, Icon, LabeledList, ProgressBar, Section, Table, AnimatedNumber } from "../components"; +import { Window } from "../layouts"; + +export const OvermapShieldGenerator = (props, context) => { + return ( + + + + + + ); +}; + +const OvermapShieldGeneratorContent = (props, context) => { + const { act, data } = useBackend(context); + const { + modes, + offline_for, + } = data; + + if (offline_for) { + return ( +
+ An emergency shutdown has been initiated - generator cooling down. + Please wait until the generator cools down before resuming operation. + Estimated time left: {offline_for} seconds. +
+ ); + } + + return ( + + + +
+ {modes.map(mode => ( +
act("toggle_mode", { toggle_mode: mode.flag })}> + {mode.status ? "Enabled" : "Disabled"} + + }> + + {mode.desc} + + + Multiplier: {mode.multiplier} + +
+ ))} +
+
+ ); +}; + +const OvermapShieldGeneratorStatus = (props, context) => { + const { act, data } = useBackend(context); + const { + running, + overloaded, + mitigation_max, + mitigation_physical, + mitigation_em, + mitigation_heat, + field_integrity, + max_energy, + current_energy, + percentage_energy, + total_segments, + functional_segments, + field_radius, + target_radius, + input_cap_kw, + upkeep_power_usage, + power_usage, + spinup_counter, + } = data; + + return ( +
+ + + {running === 1 && ( + Shutting Down + ) || running === 2 && ( + overloaded && ( + Overloaded + ) || ( + Running + ) + ) || running === 3 && ( + Inactive + ) || running === 4 && ( + + Spinning Up  + {target_radius !== field_radius && ( + (Adjusting Radius) + ) || ( + {spinup_counter * 2}s + )} + + ) || ( + + Offline + + )} + + + + {current_energy} / {max_energy} MJ ({percentage_energy}%) + + + + % + + + {mitigation_em}% EM / {mitigation_physical}% PH / {mitigation_heat}% HE / {mitigation_max}% MAX + + + kW + + + {input_cap_kw && ( + + + {power_usage} / {input_cap_kw} kW + + + ) || ( + + kW (No Limit) + + )} + + +  /  + m² + (radius , target ) + + +
+ ); +}; + +const OvermapShieldGeneratorControls = (props, context) => { + const { act, data } = useBackend(context); + const { + running, + hacked, + idle_multiplier, + idle_valid_values, + } = data; + + return ( +
+ {running >= 2 && ( + + + {running === 3 && ( + + ) || ( + + )} + + ) || ( + + )} + {running && hacked && ( + + ) || null} + + }> + + + + + {idle_valid_values.map(val => ( + + ))} + + +
+ ); +}; \ No newline at end of file diff --git a/tgui/packages/tgui/interfaces/OvermapShipSensors.js b/tgui/packages/tgui/interfaces/OvermapShipSensors.js new file mode 100644 index 00000000000..980b27446eb --- /dev/null +++ b/tgui/packages/tgui/interfaces/OvermapShipSensors.js @@ -0,0 +1,111 @@ +import { round } from 'common/math'; +import { Fragment } from 'inferno'; +import { useBackend } from "../backend"; +import { Box, Button, Flex, Icon, LabeledList, ProgressBar, Section } from "../components"; +import { Window } from "../layouts"; + +export const OvermapShipSensors = (props, context) => { + const { act, data } = useBackend(context); + const { + viewing, + on, + range, + health, + max_health, + heat, + critical_heat, + status, + contacts, + } = data; + + return ( + + +
+ + + + )}> + + + {status} + + + + + + + {health} / {max_health} + + + + + {heat < critical_heat * 0.5 && ( + Temperature low. + ) || heat < critical_heat * 0.75 && ( + Sensor temperature high! + ) || ( + TEMPERATURE CRITICAL: Disable or reduce power immediately! + )} + + + +
+
+ {contacts.length && contacts.map(alien => ( + + )) || ( + + No contacts on sensors. + + )} +
+ {data.status === "MISSING" && ( +
+ +
+ ) || null} +
+
+ ); +}; \ No newline at end of file diff --git a/tgui/packages/tgui/interfaces/PointDefenseControl.js b/tgui/packages/tgui/interfaces/PointDefenseControl.js new file mode 100644 index 00000000000..68bcd56d55b --- /dev/null +++ b/tgui/packages/tgui/interfaces/PointDefenseControl.js @@ -0,0 +1,47 @@ +import { round } from 'common/math'; +import { Fragment } from 'inferno'; +import { useBackend, useLocalState } from "../backend"; +import { Box, Button, Flex, Icon, LabeledList, ProgressBar, Section, Table, AnimatedNumber } from "../components"; +import { Window } from "../layouts"; + +export const PointDefenseControl = (props, context) => { + const { act, data } = useBackend(context); + const { + id, + turrets, + } = data; + return ( + + +
+ {turrets.length && turrets.map(pd => ( +
act("toggle_active", { target: pd.ref })}> + {pd.active ? "Online" : "Offline"} + + }> + + + {pd.effective_range} + + + {pd.reaction_wheel_delay} + + + {pd.recharge_time} + + +
+ )) || ( + + Error: No weapon systems detected. Please check network connection. + + )} +
+
+
+ ); +}; \ No newline at end of file diff --git a/tgui/packages/tgui/interfaces/PrisonerManagement.js b/tgui/packages/tgui/interfaces/PrisonerManagement.js new file mode 100644 index 00000000000..118de9cce78 --- /dev/null +++ b/tgui/packages/tgui/interfaces/PrisonerManagement.js @@ -0,0 +1,101 @@ +import { round } from 'common/math'; +import { Fragment } from 'inferno'; +import { useBackend } from '../backend'; +import { Button, Section, NumberInput, Flex, Box, Table } from '../components'; +import { Window } from '../layouts'; +import { formatTime } from '../format'; + +export const PrisonerManagement = (props, context) => { + const { act, data } = useBackend(context); + const { + locked, + chemImplants, + trackImplants, + } = data; + return ( + + + {locked && ( +
+ This interface is currently locked. + + + +
+ ) || ( + +
act("lock")}> + Lock Interface + + } /> +
+ {chemImplants.length && ( + + + Host + Units Remaining + Inject + + {chemImplants.map(chem => ( + + + {chem.host} + + + {chem.units}u remaining + + + + + + + + ))} +
+ ) || ( + + No chemical implants found. + + )} +
+
+ {trackImplants.length && ( + + + Host + Location + Message + + {trackImplants.map(track => ( + + + {track.host} ({track.id}) + + + {track.loc} + + + + + + ))} +
+ ) || ( + + No chemical implants found. + + )} +
+ + )} + + + ); +}; \ No newline at end of file diff --git a/tgui/packages/tgui/interfaces/RequestConsole.js b/tgui/packages/tgui/interfaces/RequestConsole.js new file mode 100644 index 00000000000..04b7fb402c8 --- /dev/null +++ b/tgui/packages/tgui/interfaces/RequestConsole.js @@ -0,0 +1,332 @@ +import { decodeHtmlEntities } from 'common/string'; +import { Fragment } from 'inferno'; +import { useBackend } from "../backend"; +import { Box, Button, Flex, Icon, LabeledList, ProgressBar, Section, Tabs } from "../components"; +import { Window } from "../layouts"; + +const RCS_MAINMENU = 0; // Settings menu +const RCS_RQASSIST = 1; // Request supplies +const RCS_RQSUPPLY = 2; // Request assistance +const RCS_SENDINFO = 3; // Relay information +const RCS_SENTPASS = 4; // Message sent successfully +const RCS_SENTFAIL = 5; // Message sent unsuccessfully +const RCS_VIEWMSGS = 6; // View messages +const RCS_MESSAUTH = 7; // Authentication before sending +const RCS_ANNOUNCE = 8; // Send announcement + +const RequestConsoleSettings = (props, context) => { + const { act, data } = useBackend(context); + const { + silent, + } = data; + return ( +
+ +
+ ); +}; + +const RequestConsoleSupplies = (props, context) => { + const { act, data } = useBackend(context); + const { + department, + supply_dept, + } = data; + return ( +
+ +
+ ); +}; + +const RequestConsoleAssistance = (props, context) => { + const { act, data } = useBackend(context); + const { + department, + assist_dept, + } = data; + return ( +
+ +
+ ); +}; + +const RequestConsoleRelay = (props, context) => { + const { act, data } = useBackend(context); + const { + department, + info_dept, + } = data; + return ( +
+ +
+ ); +}; + +const RequestConsoleSendMenu = (props, context) => { + const { act } = useBackend(context); + const { + dept_list, + department, + } = props; + return ( + + {dept_list.sort().map(dept => dept !== department && ( + + + + + } /> + ) || null)} + + ); +}; + +const RequestConsoleSendPass = (props, context) => { + const { act, data } = useBackend(context); + return ( +
+ + Message Sent Successfully + + + + +
+ ); +}; + +const RequestConsoleSendFail = (props, context) => { + const { act, data } = useBackend(context); + return ( +
+ + An error occured. Message Not Sent. + + + + +
+ ); +}; + +const RequestConsoleViewMessages = (props, context) => { + const { act, data } = useBackend(context); + const { + message_log, + } = data; + return ( +
+ {(message_log.length && message_log.map((msg, i) => ( + act("print", { print: i + 1 })}> + Print + + }> + {decodeHtmlEntities(msg[1])} + + ))) || ( + + No messages. + + )} +
+ ); +}; + +const RequestConsoleMessageAuth = (props, context) => { + const { act, data } = useBackend(context); + const { + message, + recipient, + priority, + msgStamped, + msgVerified, + } = data; + return ( +
+ + + {message} + + + {priority === 2 ? "High Priority" : (priority === 1 ? "Normal Priority" : "Unknown")} + + + {decodeHtmlEntities(msgVerified) || "No Validation"} + + + {decodeHtmlEntities(msgStamped) || "No Stamp"} + + + + +
+ ); +}; + +const RequestConsoleAnnounce = (props, context) => { + const { act, data } = useBackend(context); + const { + department, + screen, + message_log, + newmessagepriority, + silent, + announcementConsole, + assist_dept, + supply_dept, + info_dept, + message, + recipient, + priority, + msgStamped, + msgVerified, + announceAuth, + } = data; + return ( +
+ {announceAuth && ( + + + ID Verified. Authentication Accepted. + +
act("writeAnnouncement")}> + Edit + + }> + {message || "No Message"} +
+
+ ) || ( + + Swipe your ID card to authenticate yourself. + + )} + + +
+ ); +}; + +let screenToTemplate = {}; +screenToTemplate[RCS_MAINMENU] = RequestConsoleSettings; +screenToTemplate[RCS_RQASSIST] = RequestConsoleAssistance; +screenToTemplate[RCS_RQSUPPLY] = RequestConsoleSupplies; +screenToTemplate[RCS_SENDINFO] = RequestConsoleRelay; +screenToTemplate[RCS_SENTPASS] = RequestConsoleSendPass; +screenToTemplate[RCS_SENTFAIL] = RequestConsoleSendFail; +screenToTemplate[RCS_VIEWMSGS] = RequestConsoleViewMessages; +screenToTemplate[RCS_MESSAUTH] = RequestConsoleMessageAuth; +screenToTemplate[RCS_ANNOUNCE] = RequestConsoleAnnounce; + +export const RequestConsole = (props, context) => { + const { act, data } = useBackend(context); + const { + screen, + newmessagepriority, + announcementConsole, + } = data; + + let BodyElement = screenToTemplate[screen]; + + return ( + + + + act("setScreen", { setScreen: RCS_VIEWMSGS })} + icon="envelope-open-text"> + Messages + + act("setScreen", { setScreen: RCS_RQASSIST })} + icon="share-square"> + Assistance + + act("setScreen", { setScreen: RCS_RQSUPPLY })} + icon="share-square"> + Supplies + + act("setScreen", { setScreen: RCS_SENDINFO })} + icon="share-square-o"> + Report + + {announcementConsole && ( + act("setScreen", { setScreen: RCS_ANNOUNCE })} + icon="volume-up"> + Announce + + ) || null} + act("setScreen", { setScreen: RCS_MAINMENU })} + icon="cog" /> + + {newmessagepriority && ( +
1 ? "NEW PRIORITY MESSAGES" : "There are new messages!"} + color={newmessagepriority > 1 ? "bad" : "average"} bold={newmessagepriority > 1} /> + ) || null} + + + + ); +}; \ No newline at end of file diff --git a/tgui/packages/tgui/interfaces/RogueZones.js b/tgui/packages/tgui/interfaces/RogueZones.js new file mode 100644 index 00000000000..3e01200cd6a --- /dev/null +++ b/tgui/packages/tgui/interfaces/RogueZones.js @@ -0,0 +1,98 @@ +import { useBackend } from "../backend"; +import { Box, Button, LabeledList, ProgressBar, Section } from "../components"; +import { Window } from "../layouts"; + +export const RogueZones = (props, context) => { + const { act, data } = useBackend(context); + const { + timeout_percent, + diffstep, + difficulty, + occupied, + scanning, + updated, + debug, + shuttle_location, + shuttle_at_station, + scan_ready, + can_recall_shuttle, + } = data; + return ( + + +
+ + + {difficulty} + + act("recall_shuttle")}> + Recall Shuttle + + ) || null + }> + {shuttle_location} + + {occupied && ( + + WARNING: Area occupied by {occupied} personnel! + + ) || ( + + No personnel detected. + + )} + +
+
act("scan_for_new")}> + Scan For Asteroids + + }> + + + + + {scanning && ( + + In progress. + + ) || null} + {(updated && !scanning) && ( + + Updated shuttle destination! + + ) || null} + {debug && ( + + Timeout Percent: {timeout_percent} + Diffstep: {diffstep} + Difficulty: {difficulty} + Occupied: {occupied} + Debug: {debug} + Shuttle Location: {shuttle_location} + Shuttle at station: {shuttle_at_station} + Scan Ready: {scan_ready} + + ) || null} + +
+
+
+ ); +}; \ No newline at end of file diff --git a/tgui/packages/tgui/interfaces/SecurityRecords.js b/tgui/packages/tgui/interfaces/SecurityRecords.js new file mode 100644 index 00000000000..7a95841cdf0 --- /dev/null +++ b/tgui/packages/tgui/interfaces/SecurityRecords.js @@ -0,0 +1,320 @@ +import { Fragment } from 'inferno'; +import { useBackend } from "../backend"; +import { Box, Button, Collapsible, Icon, Input, LabeledList, Section, Tabs } from "../components"; +import { ComplexModal, modalOpen, modalRegisterBodyOverride } from "../interfaces/common/ComplexModal"; +import { Window } from "../layouts"; +import { LoginInfo } from './common/LoginInfo'; +import { LoginScreen } from './common/LoginScreen'; +import { TemporaryNotice } from './common/TemporaryNotice'; +import { decodeHtmlEntities } from 'common/string'; + +const doEdit = (context, field) => { + modalOpen(context, 'edit', { + field: field.edit, + value: field.value, + }); +}; + +export const SecurityRecords = (_properties, context) => { + const { data } = useBackend(context); + const { + authenticated, + screen, + } = data; + if (!authenticated) { + return ( + + + + + + ); + } + + let body; + if (screen === 2) { // List Records + body = ; + } else if (screen === 3) { // Record Maintenance + body = ; + } else if (screen === 4) { // View Records + body = ; + } + + return ( + + + + + + +
+ {body} +
+
+
+ ); +}; + +const SecurityRecordsList = (_properties, context) => { + const { act, data } = useBackend(context); + const { + records, + } = data; + return ( + + act('search', { t1: value })} + /> + + {records.map((record, i) => ( +
+ + ); +}; + +const SecurityRecordsViewGeneral = (_properties, context) => { + const { act, data } = useBackend(context); + const { + general, + } = data; + if (!general || !general.fields) { + return ( + + General records lost! + + ); + } + return ( + + + + {general.fields.map((field, i) => ( + + + {field.value} + + {!!field.edit && ( + + + + + + ); +}; + +const SecurityRecordsViewSecurity = (_properties, context) => { + const { act, data } = useBackend(context); + const { + security, + } = data; + if (!security || !security.fields) { + return ( + + Security records lost! +
+
+ ); +}; + +const SecurityRecordsNavigation = (_properties, context) => { + const { act, data } = useBackend(context); + const { + screen, + } = data; + return ( + + act('screen', { screen: 2 })}> + + List Records + + act('screen', { screen: 3 })}> + + Record Maintenance + + + ); +}; + diff --git a/tgui/packages/tgui/interfaces/ShuttleControl.js b/tgui/packages/tgui/interfaces/ShuttleControl.js new file mode 100644 index 00000000000..5c798f9a50d --- /dev/null +++ b/tgui/packages/tgui/interfaces/ShuttleControl.js @@ -0,0 +1,478 @@ +import { toTitleCase } from 'common/string'; +import { Fragment } from 'inferno'; +import { useBackend } from "../backend"; +import { Box, Button, Flex, Icon, LabeledList, ProgressBar, Section, AnimatedNumber } from "../components"; +import { Window } from "../layouts"; + +/* Helpers */ +const getDockingStatus = (docking_status, docking_override) => { + let main = "ERROR"; + let color = "bad"; + let showsOverride = false; + if (docking_status === "docked") { + main = "DOCKED"; + color = "good"; + } else if (docking_status === "docking") { + main = "DOCKING"; + color = "average"; + showsOverride = true; + } else if (docking_status === "undocking") { + main = "UNDOCKING"; + color = "average"; + showsOverride = true; + } else if (docking_status === "undocked") { + main = "UNDOCKED"; + color = "#676767"; + } + + if (showsOverride && docking_override) { + main = main + "-MANUAL"; + } + + return ( + + {main} + + ); +}; + +/* Templates */ +const ShuttleControlSharedShuttleStatus = (props, context) => { + const { act, data } = useBackend(context); + const { + engineName = "Bluespace Drive", + } = props; + const { + shuttle_status, + shuttle_state, + has_docking, + docking_status, + docking_override, + docking_codes, + } = data; + return ( +
+ {shuttle_status} + + + {shuttle_state === "idle" && ( + + IDLE + + ) || shuttle_state === "warmup" && ( + + SPINNING UP + + ) || shuttle_state === "in_transit" && ( + + ENGAGED + + ) || ( + + ERROR + + )} + + {has_docking && ( + + + {getDockingStatus(docking_status, docking_override)} + + + + + + ) || null} + +
+ ); +}; + +const ShuttleControlSharedShuttleControls = (props, context) => { + const { act, data } = useBackend(context); + + const { + can_launch, + can_cancel, + can_force, + } = data; + + return ( +
+ + + + + + + + + + + +
+ ); +}; + +const ShuttleControlConsoleDefault = (props, context) => { + const { act, data } = useBackend(context); + return ( + + + + + ); +}; + +const ShuttleControlConsoleMulti = (props, context) => { + const { act, data } = useBackend(context); + const { + can_cloak, + can_pick, + legit, + cloaked, + destination_name, + } = data; + return ( + + +
+ + {can_cloak && ( + + + + ) || null} + + + + +
+ +
+ ); +}; + +const ShuttleControlConsoleExploration = (props, context) => { + const { act, data } = useBackend(context); + const { + can_pick, + destination_name, + fuel_usage, + fuel_span, + remaining_fuel, + } = data; + return ( + + +
+ + + + + {fuel_usage && ( + + + {remaining_fuel} m/s + + + {fuel_usage} m/s + + + ) || null} + +
+ +
+ ); +}; + +/* Ugh. Just ugh. */ +const ShuttleControlConsoleWeb = (props, context) => { + const { act, data } = useBackend(context); + + const { + autopilot, + can_rename, + shuttle_state, + is_moving, + skip_docking, + docking_status, + docking_override, + shuttle_location, + can_cloak, + cloaked, + can_autopilot, + routes, + is_in_transit, + travel_progress, + time_left, + doors, + sensors, + } = data; + + return ( + + {autopilot && ( +
+ + This vessel will start and stop automatically. + Ensure that all non-cycling capable hatches and doors are closed, + as the automated system may not be able to control them. + Docking and flight controls are locked. To unlock, disable the automated flight system. + +
+ ) || null} +
act("rename_command")}> + Rename + + ) || null + }> + + + {shuttle_state === "idle" && ( + + IDLE + + ) || shuttle_state === "warmup" && ( + + SPINNING UP + + ) || shuttle_state === "in_transit" && ( + + ENGAGED + + ) || ( + + ERROR + + )} + + {!is_moving && ( + + + {toTitleCase(shuttle_location)} + + {!skip_docking && ( + + + + + }> + {getDockingStatus(docking_status, docking_override)} + + ) || null} + {can_cloak && ( + + + + ) || null} + {can_autopilot && ( + + + + ) || null} + + ) || null} + + {!is_moving && ( +
+ + {routes.length && routes.map(route => ( + + + + )) || ( + + No routes found. + + )} + +
+ ) || null} +
+ {is_in_transit && ( +
+ + + + {time_left}s + + + +
+ ) || null} + {Object.keys(doors).length && ( +
+ + {Object.keys(doors).map(key => { + let door = doors[key]; + return ( + + {door.open && ( + + Open + + ) || ( + + Closed + + )} +  -  + {door.bolted && ( + + Bolted + + ) || ( + + Unbolted + + )} + + ); + })} + +
+ ) || null} + {Object.keys(sensors).length && ( +
+ + {Object.keys(sensors).map(key => { + let sensor = sensors[key]; + if (sensor.reading !== -1) { + return ( + + Unable to get sensor air reading. + + ); + } + return ( + + + + {sensor.pressure}kPa + + + {sensor.temp}°C + + + {sensor.oxygen}% + + + {sensor.nitrogen}% + + + {sensor.carbon_dioxide}% + + + {sensor.phoron}% + + {sensor.other && ( + + {sensor.other}% + + ) || null} + + + ); + })} + +
+ ) || null} +
+ ); +}; + +// This may look tempting to convert to require() or some kind of dynamic call +// Don't do it. XSS abound. +const SubtemplateList = { + "ShuttleControlConsoleDefault": , + "ShuttleControlConsoleMulti": , + "ShuttleControlConsoleExploration": , + "ShuttleControlConsoleWeb": , +}; + +export const ShuttleControl = (props, context) => { + const { act, data } = useBackend(context); + const { + subtemplate, + } = data; + return ( + + + {SubtemplateList[subtemplate]} + + + ); +}; \ No newline at end of file diff --git a/tgui/packages/tgui/interfaces/Sleeper.js b/tgui/packages/tgui/interfaces/Sleeper.js index 47ff1088567..96c4ec3c753 100644 --- a/tgui/packages/tgui/interfaces/Sleeper.js +++ b/tgui/packages/tgui/interfaces/Sleeper.js @@ -319,6 +319,10 @@ const SleeperChemicals = (props, context) => { }; const SleeperEmpty = (props, context) => { + const { act, data } = useBackend(context); + const { + isBeakerLoaded, + } = data; return (
@@ -329,6 +333,15 @@ const SleeperEmpty = (props, context) => { size="5" />
No occupant detected. + {isBeakerLoaded && ( + +
diff --git a/tgui/packages/tgui/interfaces/SupplyConsole.js b/tgui/packages/tgui/interfaces/SupplyConsole.js new file mode 100644 index 00000000000..69ee550849e --- /dev/null +++ b/tgui/packages/tgui/interfaces/SupplyConsole.js @@ -0,0 +1,439 @@ +import { filter, sortBy } from 'common/collections'; +import { round } from "common/math"; +import { Fragment } from "inferno"; +import { formatTime } from "../format"; +import { useBackend, useLocalState } from "../backend"; +import { Box, Button, Flex, Icon, LabeledList, ProgressBar, Section, Tabs, Collapsible, AnimatedNumber } from "../components"; +import { ComplexModal, modalRegisterBodyOverride } from '../interfaces/common/ComplexModal'; +import { Window } from "../layouts"; +import { flow } from 'common/fp'; + +const viewCrateContents = (modal, context) => { + const { act, data } = useBackend(context); + const { + supply_points, + } = data; + const { + name, + cost, + manifest, + ref, + random, + } = modal.args; + return ( +
supply_points} + onClick={() => act("request_crate", { ref: ref })} /> + }> +
+ {manifest.map(m => ( + + {m} + + ))} +
+
+ ); +}; + +export const SupplyConsole = (props, context) => { + const { act, data } = useBackend(context); + modalRegisterBodyOverride("view_crate", viewCrateContents); + return ( + + + +
+ + +
+
+
+ ); +}; + +const SupplyConsoleShuttleStatus = (props, context) => { + const { act, data } = useBackend(context); + + const { + supply_points, + shuttle, + shuttle_auth, + } = data; + + let shuttle_buttons = null; + let showShuttleForce = false; + + if (shuttle_auth) { + if (shuttle.launch === 1 && shuttle.mode === 0) { + shuttle_buttons = ( + + + ) || null} + + ); +}; + +export const OvermapPanControls = (props, context) => { + const { act } = useBackend(context); + + const { + disabled, + actToDo, + selected = val => false, + } = props; + + return ( + + +