From d1e22462ade26da0a8d55253ad84b2b0be82785d Mon Sep 17 00:00:00 2001 From: jjpark-kb <55967837+jjpark-kb@users.noreply.github.com> Date: Fri, 17 Jul 2020 17:58:30 -0400 Subject: [PATCH] lots of radial stuff --- code/_globalvars/lists/vending.dm | 78 +++++ code/_onclick/hud/radial.dm | 13 +- code/game/objects/items/cardboard_cutouts.dm | 120 ++++++-- .../circuitboards/machine_circuitboards.dm | 18 +- code/game/objects/items/holy_weapons.dm | 36 ++- code/game/objects/items/storage/boxes.dm | 142 ++++++---- code/game/objects/items/toys.dm | 111 ++++---- code/game/objects/structures/janicart.dm | 92 +++--- code/game/objects/structures/ladders.dm | 14 +- code/modules/cargo/packs.dm | 8 +- code/modules/clothing/masks/gasmask.dm | 42 ++- code/modules/mining/machine_vending.dm | 14 +- icons/obj/cardboard_cutout.dmi | Bin 17940 -> 20315 bytes .../code/game/machinery/vending.dm | 1 - .../circuitboards/machine_circuitboards.dm | 5 - .../mob/living/silicon/robot/robot_modules.dm | 267 ++++++++++++++---- tgstation.dme | 1 + 17 files changed, 684 insertions(+), 278 deletions(-) create mode 100644 code/_globalvars/lists/vending.dm diff --git a/code/_globalvars/lists/vending.dm b/code/_globalvars/lists/vending.dm new file mode 100644 index 00000000..35204a15 --- /dev/null +++ b/code/_globalvars/lists/vending.dm @@ -0,0 +1,78 @@ +// This GLOBAL list is for radials. +GLOBAL_VAR_INIT(vending_m_choices, list( + "Booze-O-Mat" = image(icon = 'icons/obj/vending.dmi', icon_state = "boozeomat"), + "Solar's Best Hot Drinks" = image(icon = 'icons/obj/vending.dmi', icon_state = "coffee"), + "Getmore Chocolate Corp" = image(icon = 'icons/obj/vending.dmi', icon_state = "snack"), + "Robust Softdrinks" = image(icon = 'icons/obj/vending.dmi', icon_state = "Cola_Machine"), + "ShadyCigs Deluxe" = image(icon = 'icons/obj/vending.dmi', icon_state = "cigs"), + "Good Clean Fun" = image(icon = 'icons/obj/vending.dmi', icon_state = "games"), + "AutoDrobe" = image(icon = 'icons/obj/vending.dmi', icon_state = "theater"), + "Vendomat" = image(icon = 'icons/obj/vending.dmi', icon_state = "generic"), + "Engi-Vend" = image(icon = 'icons/obj/vending.dmi', icon_state = "engivend"), + "YouTool" = image(icon = 'icons/obj/vending.dmi', icon_state = "tool"), + "Sustenance Vendor" = image(icon = 'icons/obj/vending.dmi', icon_state = "sustenance"), + "Plasteel Chef's Dinnerware Vendor" = image(icon = 'icons/obj/vending.dmi', icon_state = "dinnerware"), + "PTech" = image(icon = 'icons/obj/vending.dmi', icon_state = "cart"), + "NutriMax" = image(icon = 'icons/obj/vending.dmi', icon_state = "nutri"), + "MegaSeed Servitor" = image(icon = 'icons/obj/vending.dmi', icon_state = "seeds"), + "SecDrobe" = image(icon = 'icons/obj/vending.dmi', icon_state = "secdrobe"), + "MediDrobe" = image(icon = 'icons/obj/vending.dmi', icon_state = "medidrobe"), + "EngiDrobe" = image(icon = 'icons/obj/vending.dmi', icon_state = "engidrobe"), + "AtmosDrobe" = image(icon = 'icons/obj/vending.dmi', icon_state = "atmosdrobe"), + "CargoDrobe" = image(icon = 'icons/obj/vending.dmi', icon_state = "cargodrobe"), + "RoboDrobe" = image(icon = 'icons/obj/vending.dmi', icon_state = "robodrobe"), + "SciDrobe" = image(icon = 'icons/obj/vending.dmi', icon_state = "scidrobe"), + "HyDrobe" = image(icon = 'icons/obj/vending.dmi', icon_state = "hydrobe"), + "CuraDrobe" = image(icon = 'icons/obj/vending.dmi', icon_state = "curadrobe"), + "BarDrobe" = image(icon = 'icons/obj/vending.dmi', icon_state = "bardrobe"), + "ChefDrobe" = image(icon = 'icons/obj/vending.dmi', icon_state = "chefdrobe"), + "JaniDrobe" = image(icon = 'icons/obj/vending.dmi', icon_state = "janidrobe"), + "LawDrobe" = image(icon = 'icons/obj/vending.dmi', icon_state = "lawdrobe"), + "ChapDrobe" = image(icon = 'icons/obj/vending.dmi', icon_state = "chapdrobe"), + "ChemDrobe" = image(icon = 'icons/obj/vending.dmi', icon_state = "chemdrobe"), + "GeneDrobe" = image(icon = 'icons/obj/vending.dmi', icon_state = "genedrobe"), + "ViroDrobe" = image(icon = 'icons/obj/vending.dmi', icon_state = "virodrobe"), + "ClothesMate" = image(icon = 'icons/obj/vending.dmi', icon_state = "clothes"), + "NanoMed Plus" = image(icon = 'icons/obj/vending.dmi', icon_state = "med"), + "NanoMed" = image(icon = 'icons/obj/vending.dmi', icon_state = "wallmed"), + "KinkMate" = image(icon = 'icons/obj/citvending.dmi', icon_state = "kink"), +)) +// This GLOBAL list is just here to be here. +GLOBAL_VAR_INIT(vending_machines, list( + /obj/machinery/vending/boozeomat, + /obj/machinery/vending/coffee, + /obj/machinery/vending/snack, + /obj/machinery/vending/cola, + /obj/machinery/vending/cigarette, + /obj/machinery/vending/games, + /obj/machinery/vending/autodrobe, + /obj/machinery/vending/assist, + /obj/machinery/vending/engivend, + /obj/machinery/vending/tool, + /obj/machinery/vending/sustenance, + /obj/machinery/vending/dinnerware, + /obj/machinery/vending/cart, + /obj/machinery/vending/hydronutrients, + /obj/machinery/vending/hydroseeds, + /obj/machinery/vending/wardrobe/sec_wardrobe, + /obj/machinery/vending/wardrobe/medi_wardrobe, + /obj/machinery/vending/wardrobe/engi_wardrobe, + /obj/machinery/vending/wardrobe/atmos_wardrobe, + /obj/machinery/vending/wardrobe/cargo_wardrobe, + /obj/machinery/vending/wardrobe/robo_wardrobe, + /obj/machinery/vending/wardrobe/science_wardrobe, + /obj/machinery/vending/wardrobe/hydro_wardrobe, + /obj/machinery/vending/wardrobe/curator_wardrobe, + /obj/machinery/vending/wardrobe/bar_wardrobe, + /obj/machinery/vending/wardrobe/chef_wardrobe, + /obj/machinery/vending/wardrobe/jani_wardrobe, + /obj/machinery/vending/wardrobe/law_wardrobe, + /obj/machinery/vending/wardrobe/chap_wardrobe, + /obj/machinery/vending/wardrobe/chem_wardrobe, + /obj/machinery/vending/wardrobe/gene_wardrobe, + /obj/machinery/vending/wardrobe/viro_wardrobe, + /obj/machinery/vending/clothing, + /obj/machinery/vending/medical, + /obj/machinery/vending/wallmed, + /obj/machinery/vending/kink +)) diff --git a/code/_onclick/hud/radial.dm b/code/_onclick/hud/radial.dm index df91223e..bcdd5c85 100644 --- a/code/_onclick/hud/radial.dm +++ b/code/_onclick/hud/radial.dm @@ -255,6 +255,7 @@ GLOBAL_LIST_EMPTY(radial_menus) current_user = M.client //Blank menu_holder = image(icon='icons/effects/effects.dmi',loc=anchor,icon_state="nothing",layer = ABOVE_HUD_LAYER) + menu_holder.plane = ABOVE_HUD_PLANE menu_holder.appearance_flags |= KEEP_APART menu_holder.vis_contents += elements + close_button current_user.images += menu_holder @@ -285,13 +286,16 @@ GLOBAL_LIST_EMPTY(radial_menus) Choices should be a list where list keys are movables or text used for element names and return value and list values are movables/icons/images used for element icons */ -/proc/show_radial_menu(mob/user, atom/anchor, list/choices, uniqueid, radius, datum/callback/custom_check, require_near = FALSE, tooltips = FALSE) +/proc/show_radial_menu(mob/user, atom/anchor, list/choices, uniqueid, radius, datum/callback/custom_check, require_near = FALSE, tooltips = FALSE, no_repeat_close = FALSE) if(!user || !anchor || !length(choices)) return if(!uniqueid) uniqueid = "defmenu_[REF(user)]_[REF(anchor)]" if(GLOB.radial_menus[uniqueid]) + if(!no_repeat_close) + var/datum/radial_menu/menu = GLOB.radial_menus[uniqueid] + menu.finished = TRUE return var/datum/radial_menu/menu = new @@ -308,4 +312,9 @@ GLOBAL_LIST_EMPTY(radial_menus) var/answer = menu.selected_choice qdel(menu) GLOB.radial_menus -= uniqueid - return answer \ No newline at end of file + if(require_near && !in_range(anchor, user)) + return + if(istype(custom_check)) + if(!custom_check.Invoke()) + return + return answer diff --git a/code/game/objects/items/cardboard_cutouts.dm b/code/game/objects/items/cardboard_cutouts.dm index 113b1d63..bc86881c 100644 --- a/code/game/objects/items/cardboard_cutouts.dm +++ b/code/game/objects/items/cardboard_cutouts.dm @@ -6,17 +6,43 @@ icon_state = "cutout_basic" w_class = WEIGHT_CLASS_BULKY resistance_flags = FLAMMABLE - // Possible restyles for the cutout; - // add an entry in change_appearance() if you add to here - var/list/possible_appearances = list("Assistant", "Clown", "Mime", - "Traitor", "Nuke Op", "Cultist", "Clockwork Cultist", - "Revolutionary", "Wizard", "Shadowling", "Xenomorph", "Xenomorph Maid", "Swarmer", - "Ash Walker", "Deathsquad Officer", "Ian", "Slaughter Demon", - "Laughter Demon", "Private Security Officer", "ceo") - var/pushed_over = FALSE //If the cutout is pushed over and has to be righted - var/deceptive = FALSE //If the cutout actually appears as what it portray and not a discolored version + /// Possible restyles for the cutout, add an entry in change_appearance() if you add to here + var/static/list/possible_appearances + /// If the cutout is pushed over and has to be righted + var/pushed_over = FALSE + /// If the cutout actually appears as what it portray and not a discolored version + var/deceptive = FALSE - var/lastattacker = null +/obj/item/cardboard_cutout/Initialize() + . = ..() + if(possible_appearances) + return + possible_appearances = sortList(list( + "Assistant" = image(icon = src.icon, icon_state = "cutout_greytide"), + "Clown" = image(icon = src.icon, icon_state = "cutout_clown"), + "Mime" = image(icon = src.icon, icon_state = "cutout_mime"), + "Traitor" = image(icon = src.icon, icon_state = "cutout_traitor"), + "Nuke Op" = image(icon = src.icon, icon_state = "cutout_fluke"), + "Cultist" = image(icon = src.icon, icon_state = "cutout_cultist"), + "Brass Cultist" = image(icon = src.icon, icon_state = "cutout_servant"), + "Clockwork Cultist" = image(icon = src.icon, icon_state = "cutout_new_servant"), + "Revolutionary" = image(icon = src.icon, icon_state = "cutout_viva"), + "Wizard" = image(icon = src.icon, icon_state = "cutout_wizard"), + "Shadowling" = image(icon = src.icon, icon_state = "cutout_shadowling"), + "Xenomorph" = image(icon = src.icon, icon_state = "cutout_fukken_xeno"), + "Xenomorph Maid" = image(icon = src.icon, icon_state = "cutout_lusty"), + "Swarmer" = image(icon = src.icon, icon_state = "cutout_swarmer"), + "Ash Walker" = image(icon = src.icon, icon_state = "cutout_free_antag"), + "Deathsquad Officer" = image(icon = src.icon, icon_state = "cutout_deathsquad"), + "Ian" = image(icon = src.icon, icon_state = "cutout_ian"), + "Slaughter Demon" = image(icon = 'icons/mob/mob.dmi', icon_state = "daemon"), + "Laughter Demon" = image(icon = 'icons/mob/mob.dmi', icon_state = "bowmon"), + "Private Security Officer" = image(icon = src.icon, icon_state = "cutout_ntsec"), + "Securitron" = image(icon = src.icon, icon_state = "cutout_law"), + "Gondola" = image(icon = src.icon, icon_state = "cutout_gondola"), + "Monkey" = image(icon = src.icon, icon_state = "cutout_monky"), + "CEO" = image(icon = src.icon, icon_state = "cutout_val"), + )) //ATTACK HAND IGNORING PARENT RETURN VALUE /obj/item/cardboard_cutout/attack_hand(mob/living/user) @@ -74,23 +100,23 @@ playsound(src, 'sound/weapons/slice.ogg', 50, 1) if(prob(P.damage)) push_over() + return BULLET_ACT_HIT +/** + * change_appearance: Changes a skin of the cardboard cutout based on a user's choice + * + * Arguments: + * * crayon The crayon used to change and recolor the cardboard cutout + * * user The mob choosing a skin of the cardboard cutout + */ /obj/item/cardboard_cutout/proc/change_appearance(obj/item/toy/crayon/crayon, mob/living/user) - if(!crayon || !user) - return - if(pushed_over) - to_chat(user, "Right [src] first!") - return - if(crayon.check_empty(user)) - return - if(crayon.is_capped) - to_chat(user, "Take the cap off first!") - return - var/new_appearance = input(user, "Choose a new appearance for [src].", "26th Century Deception") as null|anything in possible_appearances - if(!new_appearance || !crayon || !user.canUseTopic(src)) + var/new_appearance = show_radial_menu(user, src, possible_appearances, custom_check = CALLBACK(src, .proc/check_menu, user, crayon), radius = 36, require_near = TRUE) + if(!new_appearance) return if(!do_after(user, 10, FALSE, src, TRUE)) - return + return FALSE + if(!check_menu(user, crayon)) + return FALSE user.visible_message("[user] gives [src] a new look.", "Voila! You give [src] a new look.") crayon.use_charges(1) crayon.check_empty(user) @@ -123,10 +149,14 @@ name = "Unknown" desc = "A cardboard cutout of a cultist." icon_state = "cutout_cultist" + if("Brass Cultist") + name = "[pick(GLOB.first_names_male)] [pick(GLOB.last_names)]" + desc = "A cardboard cutout of a \"servant\" of Ratvar." + icon_state = "cutout_servant" if("Clockwork Cultist") name = "[pick(GLOB.first_names_male)] [pick(GLOB.last_names)]" desc = "A cardboard cutout of a servant of Ratvar." - icon_state = "cutout_servant" + icon_state = "cutout_new_servant" if("Revolutionary") name = "Unknown" desc = "A cardboard cutout of a revolutionary." @@ -179,11 +209,49 @@ name = "Private Security Officer" desc = "A cardboard cutout of a private security officer." icon_state = "cutout_ntsec" - if("ceo") + if("Securitron") + name = "[pick("Officer", "Oftiser", "Sergeant", "General")][pick(" Genesky", " Pingsky", " Beepsky", " Pipsqueak", "-at-Armsky")]" + desc = "A cardboard cutout of a securitron." + icon_state = "cutout_law" + if("Gondola") + name = "gondola" + desc = "A cardboard cutout of a gondola." + icon_state = "cutout_gondola" + if("Monkey") + name = "monkey ([rand(1, 999)])" + desc = "A cardboard cutout of a monkey." + icon_state = "cutout_monky" + if("CEO") name = "Valarie" desc = "The very owner of your soul" icon_state = "cutout_val" - return 1 + else + return FALSE + return TRUE + +/** + * check_menu: Checks if we are allowed to interact with a radial menu + * + * Arguments: + * * user The mob interacting with a menu + * * crayon The crayon used to interact with a menu + */ +/obj/item/cardboard_cutout/proc/check_menu(mob/living/user, obj/item/toy/crayon/crayon) + if(!istype(user)) + return FALSE + if(user.incapacitated()) + return FALSE + if(pushed_over) + to_chat(user, "Right [src] first!") + return FALSE + if(!crayon || !user.is_holding(crayon)) + return FALSE + if(crayon.check_empty(user)) + return FALSE + if(crayon.is_capped) + to_chat(user, "Take the cap off first!") + return FALSE + return TRUE /obj/item/cardboard_cutout/setDir(newdir) dir = SOUTH diff --git a/code/game/objects/items/circuitboards/machine_circuitboards.dm b/code/game/objects/items/circuitboards/machine_circuitboards.dm index dcf3cd12..64ec1883 100644 --- a/code/game/objects/items/circuitboards/machine_circuitboards.dm +++ b/code/game/objects/items/circuitboards/machine_circuitboards.dm @@ -252,16 +252,22 @@ /obj/machinery/vending/wardrobe/viro_wardrobe = "ViroDrobe", /obj/machinery/vending/clothing = "ClothesMate", /obj/machinery/vending/medical = "NanoMed Plus", - /obj/machinery/vending/wallmed = "NanoMed") + /obj/machinery/vending/wallmed = "NanoMed", + /obj/machinery/vending/kink = "\improper KinkMate") /obj/item/circuitboard/machine/vendor/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/screwdriver)) - var/position = vending_names_paths.Find(build_path) - position = (position == vending_names_paths.len) ? 1 : (position + 1) - var/typepath = vending_names_paths[position] - - to_chat(user, "You set the board to \"[vending_names_paths[typepath]]\".") + var/choice = show_radial_menu(user, src, GLOB.vending_m_choices, radius = 46, require_near = TRUE, tooltips = TRUE) + if(!choice) + return + var/static/list/vendinglist = GLOB.vending_m_choices + var/choiceposition = vendinglist.Find(choice) + if(!choiceposition) + return + var/typepath = GLOB.vending_machines[choiceposition] + var/namepath = vending_names_paths[choiceposition] set_type(typepath) + to_chat(user, "You set the board to \"[vending_names_paths[namepath]]\".") else return ..() diff --git a/code/game/objects/items/holy_weapons.dm b/code/game/objects/items/holy_weapons.dm index 65478a84..040cd53c 100644 --- a/code/game/objects/items/holy_weapons.dm +++ b/code/game/objects/items/holy_weapons.dm @@ -244,21 +244,23 @@ if(user.mind && (user.mind.isholy) && !reskinned) reskin_holy_weapon(user) -/obj/item/nullrod/proc/reskin_holy_weapon(mob/M) +/obj/item/nullrod/proc/reskin_holy_weapon(mob/living/L) if(GLOB.holy_weapon_type) return - var/obj/item/nullrod/holy_weapon - var/list/holy_weapons_list = typesof(/obj/item/nullrod) + list( - /obj/item/twohanded/dualsaber/hypereutactic/chaplain - ) + var/obj/item/holy_weapon + var/list/holy_weapons_list = subtypesof(/obj/item/nullrod) var/list/display_names = list() + var/list/nullrod_icons = list() for(var/V in holy_weapons_list) var/obj/item/nullrod/rodtype = V if (initial(rodtype.chaplain_spawnable)) display_names[initial(rodtype.name)] = rodtype + nullrod_icons += list(initial(rodtype.name) = image(icon = initial(rodtype.icon), icon_state = initial(rodtype.icon_state))) - var/choice = input(M,"What theme would you like for your holy weapon?","Holy Weapon Theme") as null|anything in display_names - if(QDELETED(src) || !choice || M.stat || !in_range(M, src) || M.restrained() || !M.canmove || reskinned) + nullrod_icons = sortList(nullrod_icons) + + var/choice = show_radial_menu(L, src , nullrod_icons, custom_check = CALLBACK(src, .proc/check_menu, L), radius = 42, require_near = TRUE) + if(!choice || !check_menu(L)) return var/A = display_names[choice] // This needs to be on a separate var as list member access is not allowed for new @@ -269,9 +271,23 @@ SSblackbox.record_feedback("tally", "chaplain_weapon", 1, "[choice]") if(holy_weapon) - holy_weapon.reskinned = TRUE qdel(src) - M.put_in_active_hand(holy_weapon) + L.put_in_active_hand(holy_weapon) + +/** + * check_menu: Checks if we are allowed to interact with a radial menu + * + * Arguments: + * * user The mob interacting with a menu + */ +/obj/item/nullrod/proc/check_menu(mob/user) + if(!istype(user)) + return FALSE + if(QDELETED(src) || reskinned) + return FALSE + if(user.incapacitated() || !user.is_holding(src)) + return FALSE + return TRUE /obj/item/nullrod/godhand icon_state = "disintegrate" @@ -738,4 +754,4 @@ sharpness = IS_SHARP_ACCURATE w_class = WEIGHT_CLASS_BULKY attack_verb = list("stabbed", "poked", "slashed", "clocked") - hitsound = 'sound/weapons/bladeslice.ogg' \ No newline at end of file + hitsound = 'sound/weapons/bladeslice.ogg' diff --git a/code/game/objects/items/storage/boxes.dm b/code/game/objects/items/storage/boxes.dm index f03d455b..353d8d67 100644 --- a/code/game/objects/items/storage/boxes.dm +++ b/code/game/objects/items/storage/boxes.dm @@ -33,6 +33,7 @@ resistance_flags = FLAMMABLE var/foldable = /obj/item/stack/sheet/cardboard var/illustration = "writing" + rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE //exploits ahoy /obj/item/storage/box/Initialize(mapload) . = ..() @@ -104,25 +105,37 @@ // Ordinary survival box /obj/item/storage/box/survival/PopulateContents() new /obj/item/clothing/mask/breath(src) - new /obj/item/tank/internals/emergency_oxygen(src) new /obj/item/reagent_containers/hypospray/medipen(src) + if(!isplasmaman(loc)) + new /obj/item/tank/internals/emergency_oxygen(src) + else + new /obj/item/tank/internals/plasmaman/belt(src) + /obj/item/storage/box/survival/radio/PopulateContents() ..() // we want the survival stuff too. new /obj/item/radio/off(src) /obj/item/storage/box/survival_mining/PopulateContents() new /obj/item/clothing/mask/gas/explorer(src) - new /obj/item/tank/internals/emergency_oxygen/engi(src) new /obj/item/crowbar/red(src) new /obj/item/reagent_containers/hypospray/medipen(src) + if(!isplasmaman(loc)) + new /obj/item/tank/internals/emergency_oxygen(src) + else + new /obj/item/tank/internals/plasmaman/belt(src) + // Engineer survival box /obj/item/storage/box/engineer/PopulateContents() new /obj/item/clothing/mask/breath(src) - new /obj/item/tank/internals/emergency_oxygen/engi(src) new /obj/item/reagent_containers/hypospray/medipen(src) + if(!isplasmaman(loc)) + new /obj/item/tank/internals/emergency_oxygen/engi(src) + else + new /obj/item/tank/internals/plasmaman/belt(src) + /obj/item/storage/box/engineer/radio/PopulateContents() ..() // we want the regular items too. new /obj/item/radio/off(src) @@ -130,14 +143,22 @@ // Syndie survival box /obj/item/storage/box/syndie/PopulateContents() new /obj/item/clothing/mask/gas/syndicate(src) - new /obj/item/tank/internals/emergency_oxygen/engi(src) + + if(!isplasmaman(loc)) + new /obj/item/tank/internals/emergency_oxygen/engi(src) + else + new /obj/item/tank/internals/plasmaman/belt(src) // Security survival box /obj/item/storage/box/security/PopulateContents() new /obj/item/clothing/mask/gas/sechailer(src) - new /obj/item/tank/internals/emergency_oxygen(src) new /obj/item/reagent_containers/hypospray/medipen(src) + if(!isplasmaman(loc)) + new /obj/item/tank/internals/emergency_oxygen(src) + else + new /obj/item/tank/internals/plasmaman/belt(src) + /obj/item/storage/box/security/radio/PopulateContents() ..() // we want the regular stuff too new /obj/item/radio/off(src) @@ -397,7 +418,7 @@ /obj/item/storage/box/donkpockets/ComponentInitialize() . = ..() - GET_COMPONENT(STR, /datum/component/storage) + var/datum/component/storage/STR = GetComponent(/datum/component/storage) STR.can_hold = typecacheof(list(/obj/item/reagent_containers/food/snacks/donkpocket)) /obj/item/storage/box/donkpockets/PopulateContents() @@ -412,7 +433,7 @@ /obj/item/storage/box/monkeycubes/ComponentInitialize() . = ..() - GET_COMPONENT(STR, /datum/component/storage) + var/datum/component/storage/STR = GetComponent(/datum/component/storage) STR.max_items = 7 STR.can_hold = typecacheof(list(/obj/item/reagent_containers/food/snacks/monkeycube)) @@ -567,7 +588,7 @@ /obj/item/storage/box/snappops/ComponentInitialize() . = ..() - GET_COMPONENT(STR, /datum/component/storage) + var/datum/component/storage/STR = GetComponent(/datum/component/storage) STR.can_hold = typecacheof(list(/obj/item/toy/snappop)) STR.max_items = 8 @@ -585,7 +606,7 @@ /obj/item/storage/box/matches/ComponentInitialize() . = ..() - GET_COMPONENT(STR, /datum/component/storage) + var/datum/component/storage/STR = GetComponent(/datum/component/storage) STR.max_items = 10 STR.can_hold = typecacheof(list(/obj/item/match)) @@ -608,7 +629,7 @@ /obj/item/storage/box/lights/ComponentInitialize() . = ..() - GET_COMPONENT(STR, /datum/component/storage) + var/datum/component/storage/STR = GetComponent(/datum/component/storage) STR.max_items = 21 STR.can_hold = typecacheof(list(/obj/item/light/tube, /obj/item/light/bulb)) STR.max_combined_w_class = 21 @@ -706,11 +727,16 @@ new /obj/item/stack/medical/ointment(src) new /obj/item/reagent_containers/hypospray/medipen(src) +// Clown survival box /obj/item/storage/box/hug/survival/PopulateContents() new /obj/item/clothing/mask/breath(src) - new /obj/item/tank/internals/emergency_oxygen(src) new /obj/item/reagent_containers/hypospray/medipen(src) + if(!isplasmaman(loc)) + new /obj/item/tank/internals/emergency_oxygen(src) + else + new /obj/item/tank/internals/plasmaman/belt(src) + /obj/item/storage/box/rubbershot name = "box of rubber shots" desc = "A box full of rubber shots, designed for riot shotguns." @@ -804,12 +830,6 @@ -#define NODESIGN "None" -#define NANOTRASEN "NanotrasenStandard" -#define SYNDI "SyndiSnacks" -#define HEART "Heart" -#define SMILEY "SmileyFace" - /obj/item/storage/box/papersack name = "paper sack" desc = "A sack neatly crafted out of paper." @@ -817,64 +837,84 @@ item_state = "paperbag_None" resistance_flags = FLAMMABLE foldable = null - var/design = NODESIGN + /// A list of all available papersack reskins + var/list/papersack_designs = list() -/obj/item/storage/box/papersack/update_icon() +/obj/item/storage/box/papersack/Initialize(mapload) + . = ..() + papersack_designs = sortList(list( + "None" = image(icon = src.icon, icon_state = "paperbag_None"), + "NanotrasenStandard" = image(icon = src.icon, icon_state = "paperbag_NanotrasenStandard"), + "SyndiSnacks" = image(icon = src.icon, icon_state = "paperbag_SyndiSnacks"), + "Heart" = image(icon = src.icon, icon_state = "paperbag_Heart"), + "SmileyFace" = image(icon = src.icon, icon_state = "paperbag_SmileyFace") + )) + +/obj/item/storage/box/papersack/update_icon_state() if(contents.len == 0) icon_state = "[item_state]" - else icon_state = "[item_state]_closed" + else + icon_state = "[item_state]_closed" /obj/item/storage/box/papersack/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/pen)) - //if a pen is used on the sack, dialogue to change its design appears - if(contents.len) - to_chat(user, "You can't modify [src] with items still inside!") - return - var/list/designs = list(NODESIGN, NANOTRASEN, SYNDI, HEART, SMILEY, "Cancel") - var/switchDesign = input("Select a Design:", "Paper Sack Design", designs[1]) in designs - if(get_dist(usr, src) > 1) - to_chat(usr, "You have moved too far away!") - return - var/choice = designs.Find(switchDesign) - if(design == designs[choice] || designs[choice] == "Cancel") - return 0 - to_chat(usr, "You make some modifications to [src] using your pen.") - design = designs[choice] - icon_state = "paperbag_[design]" - item_state = "paperbag_[design]" - switch(designs[choice]) - if(NODESIGN) + var/choice = show_radial_menu(user, src , papersack_designs, custom_check = CALLBACK(src, .proc/check_menu, user, W), radius = 36, require_near = TRUE) + if(!choice) + return FALSE + if(icon_state == "paperbag_[choice]") + return FALSE + switch(choice) + if("None") desc = "A sack neatly crafted out of paper." - if(NANOTRASEN) + if("NanotrasenStandard") desc = "A standard Nanotrasen paper lunch sack for loyal employees on the go." - if(SYNDI) + if("SyndiSnacks") desc = "The design on this paper sack is a remnant of the notorious 'SyndieSnacks' program." - if(HEART) + if("Heart") desc = "A paper sack with a heart etched onto the side." - if(SMILEY) + if("SmileyFace") desc = "A paper sack with a crude smile etched onto the side." - return 0 + else + return FALSE + to_chat(user, "You make some modifications to [src] using your pen.") + icon_state = "paperbag_[choice]" + item_state = "paperbag_[choice]" + return FALSE else if(W.is_sharp()) if(!contents.len) if(item_state == "paperbag_None") user.show_message("You cut eyeholes into [src].", 1) new /obj/item/clothing/head/papersack(user.loc) qdel(src) - return 0 + return FALSE else if(item_state == "paperbag_SmileyFace") user.show_message("You cut eyeholes into [src] and modify the design.", 1) new /obj/item/clothing/head/papersack/smiley(user.loc) qdel(src) - return 0 + return FALSE return ..() -#undef NODESIGN -#undef NANOTRASEN -#undef SYNDI -#undef HEART -#undef SMILEY +/** + * check_menu: Checks if we are allowed to interact with a radial menu + * + * Arguments: + * * user The mob interacting with a menu + * * P The pen used to interact with a menu + */ +/obj/item/storage/box/papersack/proc/check_menu(mob/user, obj/item/pen/P) + if(!istype(user)) + return FALSE + if(user.incapacitated()) + return FALSE + if(contents.len) + to_chat(user, "You can't modify [src] with items still inside!") + return FALSE + if(!P || !user.is_holding(P)) + to_chat(user, "You need a pen to modify [src]!") + return FALSE + return TRUE -/obj/item/storage/box/ingredients //This box is for the randomely chosen version the chef spawns with, it shouldn't actually exist. +/obj/item/storage/box/ingredients //This box is for the randomly chosen version the chef spawns with, it shouldn't actually exist. name = "ingredients box" illustration = "fruit" var/theme_name diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index 46fabea8..59e937ce 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -763,79 +763,55 @@ name = "hand of cards" desc = "A number of cards not in a deck, customarily held in ones hand." icon = 'icons/obj/toy.dmi' - icon_state = "nanotrasen_hand2" + icon_state = "none" w_class = WEIGHT_CLASS_TINY var/list/currenthand = list() var/choice = null - /obj/item/toy/cards/cardhand/attack_self(mob/user) - user.set_machine(src) + var/list/handradial = list() interact(user) -/obj/item/toy/cards/cardhand/ui_interact(mob/user) - . = ..() - var/dat = "You have:
" for(var/t in currenthand) - dat += "A [t].
" - dat += "Which card will you remove next?" - var/datum/browser/popup = new(user, "cardhand", "Hand of Cards", 400, 240) - popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) - popup.set_content(dat) - popup.open() + handradial[t] = image(icon = src.icon, icon_state = "sc_[t]_[deckstyle]") - -/obj/item/toy/cards/cardhand/Topic(href, href_list) - if(..()) - return if(usr.stat || !ishuman(usr)) return var/mob/living/carbon/human/cardUser = usr var/O = src - if(href_list["pick"]) - if (cardUser.is_holding(src)) - var/choice = href_list["pick"] - var/obj/item/toy/cards/singlecard/C = new/obj/item/toy/cards/singlecard(cardUser.loc) - src.currenthand -= choice - C.parentdeck = src.parentdeck - C.cardname = choice - C.apply_card_vars(C,O) - C.pickup(cardUser) - cardUser.put_in_hands(C) - cardUser.visible_message("[cardUser] draws a card from [cardUser.p_their()] hand.", "You take the [C.cardname] from your hand.") + var/choice = show_radial_menu(usr,src, handradial, custom_check = CALLBACK(src, .proc/check_menu, user), radius = 36, require_near = TRUE) + if(!choice) + return FALSE + var/obj/item/toy/cards/singlecard/C = new/obj/item/toy/cards/singlecard(cardUser.loc) + currenthand -= choice + handradial -= choice + C.parentdeck = parentdeck + C.cardname = choice + C.apply_card_vars(C,O) + C.pickup(cardUser) + cardUser.put_in_hands(C) + cardUser.visible_message("[cardUser] draws a card from [cardUser.p_their()] hand.", "You take the [C.cardname] from your hand.") - interact(cardUser) - if(src.currenthand.len < 3) - src.icon_state = "[deckstyle]_hand2" - else if(src.currenthand.len < 4) - src.icon_state = "[deckstyle]_hand3" - else if(src.currenthand.len < 5) - src.icon_state = "[deckstyle]_hand4" - if(src.currenthand.len == 1) - var/obj/item/toy/cards/singlecard/N = new/obj/item/toy/cards/singlecard(src.loc) - N.parentdeck = src.parentdeck - N.cardname = src.currenthand[1] - N.apply_card_vars(N,O) - qdel(src) - N.pickup(cardUser) - cardUser.put_in_hands(N) - to_chat(cardUser, "You also take [currenthand[1]] and hold it.") - cardUser << browse(null, "window=cardhand") - return + interact(cardUser) + update_sprite() + if(length(currenthand) == 1) + var/obj/item/toy/cards/singlecard/N = new/obj/item/toy/cards/singlecard(loc) + N.parentdeck = parentdeck + N.cardname = currenthand[1] + N.apply_card_vars(N,O) + qdel(src) + N.pickup(cardUser) + cardUser.put_in_hands(N) + to_chat(cardUser, "You also take [currenthand[1]] and hold it.") /obj/item/toy/cards/cardhand/attackby(obj/item/toy/cards/singlecard/C, mob/living/user, params) if(istype(C)) if(C.parentdeck == src.parentdeck) src.currenthand += C.cardname - user.visible_message("[user] adds a card to [user.p_their()] hand.", "You add the [C.cardname] to your hand.") + user.visible_message("[user] adds a card to [user.p_their()] hand.", "You add the [C.cardname] to your hand.") qdel(C) interact(user) - if(currenthand.len > 4) - src.icon_state = "[deckstyle]_hand5" - else if(currenthand.len > 3) - src.icon_state = "[deckstyle]_hand4" - else if(currenthand.len > 2) - src.icon_state = "[deckstyle]_hand3" + update_sprite(src) else to_chat(user, "You can't mix cards from other decks!") else @@ -844,7 +820,7 @@ /obj/item/toy/cards/cardhand/apply_card_vars(obj/item/toy/cards/newobj,obj/item/toy/cards/sourceobj) ..() newobj.deckstyle = sourceobj.deckstyle - newobj.icon_state = "[deckstyle]_hand2" // Another dumb hack, without this the hand is invisible (or has the default deckstyle) until another card is added. + update_sprite() newobj.card_hitsound = sourceobj.card_hitsound newobj.card_force = sourceobj.card_force newobj.card_throwforce = sourceobj.card_throwforce @@ -853,6 +829,31 @@ newobj.card_attack_verb = sourceobj.card_attack_verb newobj.resistance_flags = sourceobj.resistance_flags +/** + * check_menu: Checks if we are allowed to interact with a radial menu + * + * Arguments: + * * user The mob interacting with a menu + */ +/obj/item/toy/cards/cardhand/proc/check_menu(mob/living/user) + if(!istype(user)) + return FALSE + if(user.incapacitated()) + return FALSE + return TRUE + +/** + * This proc updates the sprite for when you create a hand of cards + */ +/obj/item/toy/cards/cardhand/proc/update_sprite() + cut_overlays() + var/overlay_cards = currenthand.len + + var/k = overlay_cards == 2 ? 1 : overlay_cards - 2 + for(var/i = k; i <= overlay_cards; i++) + var/card_overlay = image(icon=src.icon,icon_state="sc_[currenthand[i]]_[deckstyle]",pixel_x=(1-i+k)*3,pixel_y=(1-i+k)*3) + add_overlay(card_overlay) + /obj/item/toy/cards/singlecard name = "card" desc = "a card" @@ -865,13 +866,13 @@ /obj/item/toy/cards/singlecard/examine(mob/user) + . = ..() if(ishuman(user)) var/mob/living/carbon/human/cardUser = user if(cardUser.is_holding(src)) cardUser.visible_message("[cardUser] checks [cardUser.p_their()] card.", "The card reads: [cardname].") else - to_chat(cardUser, "You need to have the card in your hand to check it!") - + . += "You need to have the card in your hand to check it!" /obj/item/toy/cards/singlecard/verb/Flip() set name = "Flip Card" diff --git a/code/game/objects/structures/janicart.dm b/code/game/objects/structures/janicart.dm index 54b9d650..fa0b7d13 100644 --- a/code/game/objects/structures/janicart.dm +++ b/code/game/objects/structures/janicart.dm @@ -6,11 +6,10 @@ anchored = FALSE density = TRUE //copypaste sorry - var/amount_per_transfer_from_this = 5 //shit I dunno, adding this so syringes stop runtime erroring. --NeoFite - var/obj/item/storage/bag/trash/mybag = null - var/obj/item/mop/mymop = null - var/obj/item/reagent_containers/spray/cleaner/myspray = null - var/obj/item/lightreplacer/myreplacer = null + var/obj/item/storage/bag/trash/mybag + var/obj/item/mop/mymop + var/obj/item/reagent_containers/spray/cleaner/myspray + var/obj/item/lightreplacer/myreplacer var/signs = 0 var/const/max_signs = 4 @@ -32,7 +31,6 @@ /obj/structure/janitorialcart/proc/put_in_cart(obj/item/I, mob/user) if(!user.transferItemToLoc(I, src)) return - updateUsrDialog() to_chat(user, "You put [I] into [src].") return @@ -49,7 +47,6 @@ m.janicart_insert(user, src) else to_chat(user, fail_msg) - else if(istype(I, /obj/item/storage/bag/trash)) if(!mybag) var/obj/item/storage/bag/trash/t=I @@ -91,63 +88,74 @@ . = ..() if(.) return - user.set_machine(src) - var/dat + + var/list/items = list() if(mybag) - dat += "[mybag.name]
" + items += list("Trash bag" = image(icon = mybag.icon, icon_state = mybag.icon_state)) if(mymop) - dat += "[mymop.name]
" + items += list("Mop" = image(icon = mymop.icon, icon_state = mymop.icon_state)) if(myspray) - dat += "[myspray.name]
" + items += list("Spray bottle" = image(icon = myspray.icon, icon_state = myspray.icon_state)) if(myreplacer) - dat += "[myreplacer.name]
" - if(signs) - dat += "[signs] sign\s
" - var/datum/browser/popup = new(user, "janicart", name, 240, 160) - popup.set_content(dat) - popup.open() + items += list("Light replacer" = image(icon = myreplacer.icon, icon_state = myreplacer.icon_state)) + var/obj/item/caution/sign = locate() in src + if(sign) + items += list("Sign" = image(icon = sign.icon, icon_state = sign.icon_state)) - -/obj/structure/janitorialcart/Topic(href, href_list) - if(!in_range(src, usr)) + if(!length(items)) return - if(!isliving(usr)) + items = sortList(items) + var/pick = show_radial_menu(user, src, items, custom_check = CALLBACK(src, .proc/check_menu, user), radius = 38, require_near = TRUE) + if(!pick) return - var/mob/living/user = usr - if(href_list["garbage"]) - if(mybag) + switch(pick) + if("Trash bag") + if(!mybag) + return user.put_in_hands(mybag) to_chat(user, "You take [mybag] from [src].") mybag = null - if(href_list["mop"]) - if(mymop) + if("Mop") + if(!mymop) + return user.put_in_hands(mymop) to_chat(user, "You take [mymop] from [src].") mymop = null - if(href_list["spray"]) - if(myspray) + if("Spray bottle") + if(!myspray) + return user.put_in_hands(myspray) to_chat(user, "You take [myspray] from [src].") myspray = null - if(href_list["replacer"]) - if(myreplacer) + if("Light replacer") + if(!myreplacer) + return user.put_in_hands(myreplacer) to_chat(user, "You take [myreplacer] from [src].") myreplacer = null - if(href_list["sign"]) - if(signs) - var/obj/item/caution/Sign = locate() in src - if(Sign) - user.put_in_hands(Sign) - to_chat(user, "You take \a [Sign] from [src].") - signs-- - else - WARNING("Signs ([signs]) didn't match contents") - signs = 0 + if("Sign") + if(signs <= 0) + return + user.put_in_hands(sign) + to_chat(user, "You take \a [sign] from [src].") + signs-- + else + return update_icon() - updateUsrDialog() +/** + * check_menu: Checks if we are allowed to interact with a radial menu + * + * Arguments: + * * user The mob interacting with a menu + */ +/obj/structure/janitorialcart/proc/check_menu(mob/living/user) + if(!istype(user)) + return FALSE + if(user.incapacitated()) + return FALSE + return TRUE /obj/structure/janitorialcart/update_icon() cut_overlays() diff --git a/code/game/objects/structures/ladders.dm b/code/game/objects/structures/ladders.dm index b3f415ba..f321498b 100644 --- a/code/game/objects/structures/ladders.dm +++ b/code/game/objects/structures/ladders.dm @@ -55,7 +55,7 @@ down.update_icon() up = down = null -/obj/structure/ladder/update_icon() +/obj/structure/ladder/update_icon_state() if(up && down) icon_state = "ladder11" @@ -91,8 +91,13 @@ if (!is_ghost && !in_range(src, user)) return + var/list/tool_list = list( + "Up" = image(icon = 'icons/testing/turf_analysis.dmi', icon_state = "red_arrow", dir = NORTH), + "Down" = image(icon = 'icons/testing/turf_analysis.dmi', icon_state = "red_arrow", dir = SOUTH) + ) + if (up && down) - var/result = alert("Go up or down [src]?", "Ladder", "Up", "Down", "Cancel") + var/result = show_radial_menu(user, src, tool_list, custom_check = CALLBACK(src, .proc/check_menu, user), require_near = TRUE, tooltips = TRUE) if (!is_ghost && !in_range(src, user)) return // nice try switch(result) @@ -112,6 +117,11 @@ if(!is_ghost) add_fingerprint(user) +/obj/structure/ladder/proc/check_menu(mob/user) + if(user.incapacitated() || !user.Adjacent(src)) + return FALSE + return TRUE + /obj/structure/ladder/attack_hand(mob/user) . = ..() if(.) diff --git a/code/modules/cargo/packs.dm b/code/modules/cargo/packs.dm index 861c122a..f10a1288 100644 --- a/code/modules/cargo/packs.dm +++ b/code/modules/cargo/packs.dm @@ -2921,14 +2921,13 @@ crate_name = "security department supply crate" /datum/supply_pack/costumes_toys/kinkmate - name = "Kinkmate construction kit" + name = "Kinkmate kit" cost = 2000 contraband = TRUE contains = list(/obj/item/vending_refill/kink, /obj/item/vending_refill/kink, - /obj/item/vending_refill/kink, - /obj/item/circuitboard/machine/kinkmate) - crate_name = "Kinkmate construction kit" + /obj/item/vending_refill/kink) + crate_name = "Kinkmate kit" ////////////////////////////////////////////////////////////////////////////// //////////////////////////// Miscellaneous /////////////////////////////////// @@ -3193,7 +3192,6 @@ contraband = TRUE contains = list(/obj/item/dildo/custom, /obj/item/dildo/custom, - /obj/item/circuitboard/machine/kinkmate, /obj/item/vending_refill/kink, /obj/item/vending_refill/kink, /obj/item/vending_refill/kink, diff --git a/code/modules/clothing/masks/gasmask.dm b/code/modules/clothing/masks/gasmask.dm index c9ff474a..62bcbc3d 100644 --- a/code/modules/clothing/masks/gasmask.dm +++ b/code/modules/clothing/masks/gasmask.dm @@ -66,18 +66,25 @@ resistance_flags = FLAMMABLE actions_types = list(/datum/action/item_action/adjust) dog_fashion = /datum/dog_fashion/head/clown + var/list/clownmask_designs = list() + +/obj/item/clothing/mask/gas/clown_hat/Initialize(mapload) + .=..() + clownmask_designs = list( + "True Form" = image(icon = src.icon, icon_state = "clown"), + "The Feminist" = image(icon = src.icon, icon_state = "sexyclown"), + "The Madman" = image(icon = src.icon, icon_state = "joker"), + "The Rainbow Color" = image(icon = src.icon, icon_state = "rainbow") + ) /obj/item/clothing/mask/gas/clown_hat/ui_action_click(mob/user) if(!istype(user) || user.incapacitated()) return - var/list/options = list() - options["True Form"] = "clown" - options["The Feminist"] = "sexyclown" - options["The Madman"] = "joker" - options["The Rainbow Color"] ="rainbow" + var/static/list/options = list("True Form" = "clown", "The Feminist" = "sexyclown", + "The Rainbow Color" = "rainbow", "The Madman" = "joker") - var/choice = input(user,"To what form do you wish to Morph this mask?","Morph Mask") in options + var/choice = show_radial_menu(user,src, clownmask_designs, custom_check = FALSE, radius = 36, require_near = TRUE) if(src && choice && !user.incapacitated() && in_range(user,src)) icon_state = options[choice] @@ -86,7 +93,7 @@ var/datum/action/A = X A.UpdateButtonIcon() to_chat(user, "Your Clown Mask has now morphed into [choice], all praise the Honkmother!") - return 1 + return TRUE /obj/item/clothing/mask/gas/sexyclown name = "sexy-clown wig and mask" @@ -106,19 +113,26 @@ flags_cover = MASKCOVERSEYES resistance_flags = FLAMMABLE actions_types = list(/datum/action/item_action/adjust) + var/list/mimemask_designs = list() + + +/obj/item/clothing/mask/gas/mime/Initialize(mapload) + .=..() + mimemask_designs = list( + "Blanc" = image(icon = src.icon, icon_state = "mime"), + "Excité" = image(icon = src.icon, icon_state = "sexymime"), + "Triste" = image(icon = src.icon, icon_state = "sadmime"), + "Effrayé" = image(icon = src.icon, icon_state = "scaredmime") + ) /obj/item/clothing/mask/gas/mime/ui_action_click(mob/user) if(!istype(user) || user.incapacitated()) return - var/list/options = list() - options["Blanc"] = "mime" - options["Triste"] = "sadmime" - options["Effrayé"] = "scaredmime" - options["Excité"] ="sexymime" + var/static/list/options = list("Blanc" = "mime", "Triste" = "sadmime", "Effrayé" = "scaredmime", "Excité" ="sexymime") - var/choice = input(user,"To what form do you wish to Morph this mask?","Morph Mask") in options + var/choice = show_radial_menu(user,src, mimemask_designs, custom_check = FALSE, radius = 36, require_near = TRUE) if(src && choice && !user.incapacitated() && in_range(user,src)) icon_state = options[choice] @@ -127,7 +141,7 @@ var/datum/action/A = X A.UpdateButtonIcon() to_chat(user, "Your Mime Mask has now morphed into [choice]!") - return 1 + return TRUE /obj/item/clothing/mask/gas/monkeymask name = "monkey mask" diff --git a/code/modules/mining/machine_vending.dm b/code/modules/mining/machine_vending.dm index 56504018..3a0d6e87 100644 --- a/code/modules/mining/machine_vending.dm +++ b/code/modules/mining/machine_vending.dm @@ -178,9 +178,14 @@ return ..() /obj/machinery/mineral/equipment_vendor/proc/RedeemVoucher(obj/item/mining_voucher/voucher, mob/redeemer) - var/items = list("Survival Capsule and Explorer's Webbing", "Resonator Kit", "Minebot Kit", "Extraction and Rescue Kit", "Crusher Kit", "Mining Conscription Kit") + var/items = list( "Survival Capsule and Explorer's Webbing" = image(icon = 'icons/obj/storage.dmi', icon_state = "explorerpack"), + "Resonator Kit" = image(icon = 'icons/obj/mining.dmi', icon_state = "resonator"), + "Minebot Kit" = image(icon = 'icons/mob/aibots.dmi', icon_state = "mining_drone"), + "Extraction and Rescue Kit" = image(icon = 'icons/obj/fulton.dmi', icon_state = "extraction_pack"), + "Crusher Kit" = image(icon = 'icons/obj/mining.dmi', icon_state = "mining_hammer"), + "Mining Conscription Kit" = image(icon = 'icons/obj/storage.dmi', icon_state = "duffel")) - var/selection = input(redeemer, "Pick your equipment", "Mining Voucher Redemption") as null|anything in items + var/selection = show_radial_menu(redeemer, src, items, require_near = TRUE, tooltips = TRUE) if(!selection || !Adjacent(redeemer) || QDELETED(voucher) || voucher.loc != redeemer) return var/drop_location = drop_location() @@ -349,9 +354,10 @@ new /obj/item/clothing/glasses/meson/prescription(src) /obj/machinery/mineral/equipment_vendor/proc/RedeemSVoucher(obj/item/suit_voucher/voucher, mob/redeemer) - var/items = list("Exo-suit", "SEVA suit") + var/items = list( "Exo-suit" = image(icon = 'icons/obj/clothing/suits.dmi', icon_state = "exo"), + "SEVA suit" = image(icon = 'icons/obj/clothing/suits.dmi', icon_state = "seva")) - var/selection = input(redeemer, "Pick your suit.", "Suit Voucher Redemption") as null|anything in items + var/selection = show_radial_menu(redeemer, src, items, require_near = TRUE, tooltips = TRUE) if(!selection || !Adjacent(redeemer) || QDELETED(voucher) || voucher.loc != redeemer) return var/drop_location = drop_location() diff --git a/icons/obj/cardboard_cutout.dmi b/icons/obj/cardboard_cutout.dmi index d9f49dc3c0ab3aa91d5efea4d1c18b9d93867872..0f479a3bdda4ac0aa321b714b272b0d3b2a96a9c 100644 GIT binary patch literal 20315 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 z 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

JMZt%P;d_=#As>vSOwLB@)!B(^li>6 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 diff --git a/modular_citadel/code/game/machinery/vending.dm b/modular_citadel/code/game/machinery/vending.dm index 1ea03dfe..caa7c319 100644 --- a/modular_citadel/code/game/machinery/vending.dm +++ b/modular_citadel/code/game/machinery/vending.dm @@ -39,7 +39,6 @@ desc = "A vending machine for all your unmentionable desires." icon = 'icons/obj/citvending.dmi' icon_state = "kink" - circuit = /obj/item/circuitboard/machine/kinkmate product_slogans = "Kinky!;Sexy!;Check me out, big boy!" vend_reply = "Have fun, you shameless pervert!" products = list( diff --git a/modular_citadel/code/game/objects/items/circuitboards/machine_circuitboards.dm b/modular_citadel/code/game/objects/items/circuitboards/machine_circuitboards.dm index e70028f5..e98b31fb 100644 --- a/modular_citadel/code/game/objects/items/circuitboards/machine_circuitboards.dm +++ b/modular_citadel/code/game/objects/items/circuitboards/machine_circuitboards.dm @@ -1,8 +1,3 @@ -/obj/item/circuitboard/machine/kinkmate - name = "Kinkmate Vendor (Machine Board)" - build_path = /obj/machinery/vending/kink - req_components = list(/obj/item/vending_refill/kink = 3) - /obj/item/circuitboard/machine/autoylathe name = "Autoylathe (Machine Board)" build_path = /obj/machinery/autoylathe diff --git a/modular_citadel/code/modules/mob/living/silicon/robot/robot_modules.dm b/modular_citadel/code/modules/mob/living/silicon/robot/robot_modules.dm index a038476e..468e458f 100644 --- a/modular_citadel/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/modular_citadel/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -27,6 +27,19 @@ var/moduleselect_alternate_icon var/dogborg = FALSE +/** + * check_menu: Checks if we are allowed to interact with a radial menu + * + * Arguments: + * * user The mob interacting with a menu + */ +/obj/item/robot_module/proc/check_menu(mob/user) + if(!istype(user)) + return FALSE + if(user.incapacitated() || !user.Adjacent(src)) + return FALSE + return TRUE + /obj/item/robot_module/k9 name = "Security K-9 Unit" basic_modules = list( @@ -62,13 +75,23 @@ /obj/item/robot_module/k9/be_transformed_to(obj/item/robot_module/old_module) var/mob/living/silicon/robot/R = loc - var/list/sechoundmodels = list("Default") - if(R.client && R.client.ckey in list("nezuli")) - sechoundmodels += "Alina" - var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in sechoundmodels - if(!borg_icon) - return FALSE - switch(borg_icon) + var/static/list/k9_models + if(!k9_models) + k9_models = list() + var/list/L = list("Default" = "k9") + for(var/a in L) + var/image/wide = image(icon = 'modular_citadel/icons/mob/widerobot.dmi', icon_state = L[a]) + wide.pixel_x = -16 + k9_models[a] = wide + if(R.client?.ckey == "nezuli") + var/image/bad_snowflake = image(icon = 'modular_citadel/icons/mob/widerobot.dmi', icon_state = "alina-sec") + bad_snowflake.pixel_x = -16 + k9_models["Alina"] = bad_snowflake + k9_models = sortList(k9_models) + var/k9_borg_icon = show_radial_menu(R, R , k9_models, custom_check = CALLBACK(src, .proc/check_menu, R), radius = 42, require_near = TRUE, tooltips = TRUE) + if(!k9_borg_icon) + return + switch(k9_borg_icon) if("Default") cyborg_base_icon = "k9" moduleselect_icon = "k9" @@ -113,13 +136,23 @@ /obj/item/robot_module/medihound/be_transformed_to(obj/item/robot_module/old_module) var/mob/living/silicon/robot/R = loc - var/list/medhoundmodels = list("Default", "Dark") - if(R.client && R.client.ckey in list("nezuli")) - medhoundmodels += "Alina" - var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in medhoundmodels - if(!borg_icon) - return FALSE - switch(borg_icon) + var/static/list/medihound_models + if(!medihound_models) + medihound_models = list() + var/list/L = list("Default" = "medihound", "Dark" = "medihounddark") + for(var/a in L) + var/image/wide = image(icon = 'modular_citadel/icons/mob/widerobot.dmi', icon_state = L[a]) + wide.pixel_x = -16 + medihound_models[a] = wide + if(R.client?.ckey == "nezuli") + var/image/bad_snowflake = image(icon = 'modular_citadel/icons/mob/widerobot.dmi', icon_state = "alina-med") + bad_snowflake.pixel_x = -16 + medihound_models["Alina"] = bad_snowflake + medihound_models = sortList(medihound_models) + var/medihound_borg_icon = show_radial_menu(R, R , medihound_models, custom_check = CALLBACK(src, .proc/check_menu, R), radius = 42, require_near = TRUE, tooltips = TRUE) + if(!medihound_borg_icon) + return + switch(medihound_borg_icon) if("Default") cyborg_base_icon = "medihound" if("Dark") @@ -234,10 +267,25 @@ /obj/item/robot_module/medical/be_transformed_to(obj/item/robot_module/old_module) var/mob/living/silicon/robot/R = loc - var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in list("Default", "Heavy", "Sleek", "Marina", "Droid", "Eyebot", "BootyF", "BootyM", "BootyS", "Haydee") - if(!borg_icon) - return FALSE - switch(borg_icon) + var/static/list/med_models + if(!med_models) + med_models = list( + "Default" = image(icon = 'icons/mob/robots.dmi', icon_state = "medical"), + "Droid" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "medical"), + "Sleek" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "sleekmed"), + "Marina" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "marinamed"), + "Eyebot" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "eyebotmed"), + "Heavy" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "heavymed"), + "BootyF" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "bootymedical"), + "BootyM" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "bootymedicalM"), + "BootyS" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "bootymedicalS"), + "Haydee" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "haydeemedical") + ) + med_models = sortList(med_models) + var/medi_borg_icon = show_radial_menu(R, R , med_models, custom_check = CALLBACK(src, .proc/check_menu, R), radius = 42, require_near = TRUE, tooltips = TRUE) + if(!medi_borg_icon) + return + switch(medi_borg_icon) if("Default") cyborg_base_icon = "medical" if("Droid") @@ -276,11 +324,23 @@ /obj/item/robot_module/janitor/be_transformed_to(obj/item/robot_module/old_module) var/mob/living/silicon/robot/R = loc - var/list/janimodels = list("Default", "Sleek", "Marina", "Can", "Heavy", "BootyF", "BootyM", "BootyS") - var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in janimodels - if(!borg_icon) - return FALSE - switch(borg_icon) + var/static/list/jani_models + if(!jani_models) + jani_models = list( + "Default" = image(icon = 'icons/mob/robots.dmi', icon_state = "janitor"), + "Sleek" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "sleekjan"), + "Marina" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "marinajan"), + "Can" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "canjan"), + "Heavy" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "heavyres"), + "BootyF" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "bootyjanitor"), + "BootyM" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "bootyjanitorM"), + "BootyS" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "bootyjanitorS") + ) + jani_models = sortList(jani_models) + var/jani_borg_icon = show_radial_menu(R, R , jani_models, custom_check = CALLBACK(src, .proc/check_menu, R), radius = 42, require_near = TRUE, tooltips = TRUE) + if(!jani_borg_icon) + return + switch(jani_borg_icon) if("Default") cyborg_base_icon = "janitor" if("Marina") @@ -311,10 +371,20 @@ /obj/item/robot_module/peacekeeper/be_transformed_to(obj/item/robot_module/old_module) var/mob/living/silicon/robot/R = loc - var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in list("Default", "Spider", "BootyF", "BootyM", "BootyS") - if(!borg_icon) - return FALSE - switch(borg_icon) + var/static/list/peace_models + if(!peace_models) + peace_models = list( + "Default" = image(icon = 'icons/mob/robots.dmi', icon_state = "peace"), + "Spider" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "whitespider"), + "BootyF" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "bootypeace"), + "BootyM" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "bootypeaceM"), + "BootyS" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "bootypeaceS") + ) + peace_models = sortList(peace_models) + var/peace_borg_icon = show_radial_menu(R, R , peace_models, custom_check = CALLBACK(src, .proc/check_menu, R), radius = 42, require_near = TRUE, tooltips = TRUE) + if(!peace_borg_icon) + return + switch(peace_borg_icon) if("Default") cyborg_base_icon = "peace" if("Spider") @@ -336,10 +406,25 @@ /obj/item/robot_module/security/be_transformed_to(obj/item/robot_module/old_module) var/mob/living/silicon/robot/R = loc - var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in list("Default", "Default - Treads", "Heavy", "Sleek", "Can", "Marina", "Spider", "BootyF", "BootyM", "BootyS") - if(!borg_icon) - return FALSE - switch(borg_icon) + var/static/list/sec_models + if(!sec_models) + sec_models = list( + "Default" = image(icon = 'icons/mob/robots.dmi', icon_state = "sec"), + "Default - Treads" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "sec-tread"), + "Sleek" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "sleeksec"), + "Marina" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "marinasec"), + "Can" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "cansec"), + "Spider" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "spidersec"), + "Heavy" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "heavysec"), + "BootyF" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "bootysecurity"), + "BootyM" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "bootysecurityM"), + "BootyS" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "bootysecurityS") + ) + sec_models = sortList(sec_models) + var/sec_borg_icon = show_radial_menu(R, R , sec_models, custom_check = CALLBACK(src, .proc/check_menu, R), radius = 42, require_near = TRUE, tooltips = TRUE) + if(!sec_borg_icon) + return + switch(sec_borg_icon) if("Default") cyborg_base_icon = "sec" if("Default - Treads") @@ -377,10 +462,25 @@ /obj/item/robot_module/butler/be_transformed_to(obj/item/robot_module/old_module) var/mob/living/silicon/robot/R = loc - var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in list("Waitress", "Heavy", "Sleek", "Butler", "Tophat", "Kent", "Bro", "BootyF", "BootyM", "BootyS") - if(!borg_icon) - return FALSE - switch(borg_icon) + var/static/list/butler_models + if(!butler_models) + butler_models = list( + "Waitress" = image(icon = 'icons/mob/robots.dmi', icon_state = "service_f"), + "Butler" = image(icon = 'icons/mob/robots.dmi', icon_state = "service_m"), + "Bro" = image(icon = 'icons/mob/robots.dmi', icon_state = "brobot"), + "Kent" = image(icon = 'icons/mob/robots.dmi', icon_state = "kent"), + "Tophat" = image(icon = 'icons/mob/robots.dmi', icon_state = "tophat"), + "Sleek" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "sleekserv"), + "Heavy" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "heavyserv"), + "BootyF" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "bootyservice"), + "BootyM" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "bootyserviceM"), + "BootyS" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "bootyserviceS") + ) + butler_models = sortList(butler_models) + var/butler_borg_icon = show_radial_menu(R, R , butler_models, custom_check = CALLBACK(src, .proc/check_menu, R), radius = 42, require_near = TRUE, tooltips = TRUE) + if(!butler_borg_icon) + return + switch(butler_borg_icon) if("Waitress") cyborg_base_icon = "service_f" if("Butler") @@ -419,13 +519,36 @@ /obj/item/robot_module/engineering/be_transformed_to(obj/item/robot_module/old_module) var/mob/living/silicon/robot/R = loc - var/list/engymodels = list("Default", "Default - Treads", "Heavy", "Sleek", "Marina", "Can", "Spider", "Loader","Handy", "Pup Dozer", "BootyF", "BootyM", "BootyS") - if(R.client && R.client.ckey in list("nezuli")) - engymodels += "Alina" - var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in engymodels - if(!borg_icon) - return FALSE - switch(borg_icon) + var/static/list/eng_models + if(!eng_models) + eng_models = list( + "Default" = image(icon = 'icons/mob/robots.dmi', icon_state = "engineer"), + "Default - Treads" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "engi-tread"), + "Loader" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "loaderborg"), + "Handy" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "handyeng"), + "Sleek" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "sleekeng"), + "Can" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "caneng"), + "Marina" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "marinaeng"), + "Spider" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "spidereng"), + "Heavy" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "heavyeng"), + "BootyF" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "bootyengineer"), + "BootyM" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "bootyengineerM"), + "BootyS" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "bootyengineerS") + ) + var/list/L = list("Pupdozer" = "pupdozer") + for(var/a in L) + var/image/wide = image(icon = 'modular_citadel/icons/mob/widerobot.dmi', icon_state = L[a]) + wide.pixel_x = -16 + eng_models[a] = wide + if(R.client?.ckey == "nezuli") + var/image/bad_snowflake = image(icon = 'modular_citadel/icons/mob/widerobot.dmi', icon_state = "alina-sec") + bad_snowflake.pixel_x = -16 + eng_models["Alina"] = bad_snowflake + eng_models = sortList(eng_models) + var/eng_borg_icon = show_radial_menu(R, R , eng_models, custom_check = CALLBACK(src, .proc/check_menu, R), radius = 42, require_near = TRUE, tooltips = TRUE) + if(!eng_borg_icon) + return + switch(eng_borg_icon) if("Default") cyborg_base_icon = "engineer" if("Default - Treads") @@ -487,10 +610,26 @@ /obj/item/robot_module/miner/be_transformed_to(obj/item/robot_module/old_module) var/mob/living/silicon/robot/R = loc - var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in list("Lavaland", "Heavy", "Sleek", "Marina", "Can", "Spider", "Asteroid", "Droid", "BootyF", "BootyM", "BootyS") - if(!borg_icon) - return FALSE - switch(borg_icon) + var/static/list/miner_models + if(!miner_models) + miner_models = list( + "Lavaland" = image(icon = 'icons/mob/robots.dmi', icon_state = "miner"), + "Asteroid" = image(icon = 'icons/mob/robots.dmi', icon_state = "minerOLD"), + "Droid" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "miner"), + "Sleek" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "sleekmin"), + "Can" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "canmin"), + "Marina" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "marinamin"), + "Spider" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "spidermin"), + "Heavy" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "heavymin"), + "BootyF" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "bootyminer"), + "BootyM" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "bootyminerM"), + "BootyS" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "bootyminerS") + ) + miner_models = sortList(miner_models) + var/miner_borg_icon = show_radial_menu(R, R , miner_models, custom_check = CALLBACK(src, .proc/check_menu, R), radius = 42, require_near = TRUE, tooltips = TRUE) + if(!miner_borg_icon) + return + switch(miner_borg_icon) if("Lavaland") cyborg_base_icon = "miner" if("Asteroid") @@ -531,12 +670,21 @@ /obj/item/robot_module/standard/be_transformed_to(obj/item/robot_module/old_module) var/mob/living/silicon/robot/R = loc - var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in list("Standard", "BootyF", "BootyM", "BootyS") - if(!borg_icon) - return FALSE - switch(borg_icon) + var/static/list/stand_models + if(!stand_models) + stand_models = list( + "Standard" = image(icon = 'icons/mob/robots.dmi', icon_state = "robot"), + "BootyF" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "bootystandard"), + "BootyM" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "bootystandardM"), + "BootyS" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "bootystandardS") + ) + stand_models = sortList(stand_models) + var/stand_borg_icon = show_radial_menu(R, R , stand_models, custom_check = CALLBACK(src, .proc/check_menu, R), radius = 42, require_near = TRUE, tooltips = TRUE) + if(!stand_borg_icon) + return + switch(stand_borg_icon) if("Standard") - cyborg_base_icon = "standard" + cyborg_base_icon = "robot" if("BootyF") cyborg_base_icon = "bootystandard" cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi' @@ -553,10 +701,19 @@ /obj/item/robot_module/clown/be_transformed_to(obj/item/robot_module/old_module) var/mob/living/silicon/robot/R = loc - var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in list("Standard", "BootyF", "BootyM", "BootyS") - if(!borg_icon) - return FALSE - switch(borg_icon) + var/static/list/clown_models + if(!clown_models) + clown_models = list( + "Standard" = image(icon = 'icons/mob/robots.dmi', icon_state = "clown"), + "BootyF" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "bootystandard"), + "BootyM" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "bootystandardM"), + "BootyS" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "bootystandardS") + ) + clown_models = sortList(clown_models) + var/clown_borg_icon = show_radial_menu(R, R , clown_models, custom_check = CALLBACK(src, .proc/check_menu, R), radius = 42, require_near = TRUE, tooltips = TRUE) + if(!clown_borg_icon) + return + switch(clown_borg_icon) if("Standard") cyborg_base_icon = "clown" if("BootyF") diff --git a/tgstation.dme b/tgstation.dme index 4cbf1000..707d6240 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -168,6 +168,7 @@ #include "code\_globalvars\lists\objects.dm" #include "code\_globalvars\lists\poll_ignore.dm" #include "code\_globalvars\lists\typecache.dm" +#include "code\_globalvars\lists\vending.dm" #include "code\_js\byjax.dm" #include "code\_js\menus.dm" #include "code\_onclick\adjacent.dm"