diff --git a/code/__DEFINES/color/colors.dm b/code/__DEFINES/color/colors.dm index a8896e3f01..d88320d094 100644 --- a/code/__DEFINES/color/colors.dm +++ b/code/__DEFINES/color/colors.dm @@ -123,6 +123,8 @@ #define COLOR_THEME_OPERATIVE "#B8221F" #define COLOR_THEME_GLASS "#75A4C4" #define COLOR_THEME_CLOCKWORK "#CFBA47" +#define COLOR_THEME_TRASENKNOX "#3ce375" +#define COLOR_THEME_DETECTIVE "#c7b08b" ///Colors for eigenstates #define COLOR_PERIWINKLEE "#9999FF" diff --git a/code/__DEFINES/hud.dm b/code/__DEFINES/hud.dm index 94755e3bd2..13882afb77 100644 --- a/code/__DEFINES/hud.dm +++ b/code/__DEFINES/hud.dm @@ -230,3 +230,6 @@ #define SCRN_OBJ_IN_LIST "list" /// In the collapseable palette #define SCRN_OBJ_IN_PALETTE "palette" + +/// The filter name for the hover outline +#define HOVER_OUTLINE_FILTER "hover_outline" diff --git a/code/__HELPERS/cmp.dm b/code/__HELPERS/cmp.dm index 2fbf087288..047888e420 100644 --- a/code/__HELPERS/cmp.dm +++ b/code/__HELPERS/cmp.dm @@ -4,6 +4,13 @@ /proc/cmp_numeric_asc(a,b) return a - b +// please don't ask +/proc/cmp_numeric_text_desc(a, b) + return text2num(b) - text2num(a) + +/proc/cmp_numeric_text_asc(a, b) + return text2num(a) - text2num(b) + /proc/cmp_text_asc(a,b) return sorttext(b,a) diff --git a/code/__HELPERS/type2type.dm b/code/__HELPERS/type2type.dm index 89eb7b75c3..130243db79 100644 --- a/code/__HELPERS/type2type.dm +++ b/code/__HELPERS/type2type.dm @@ -689,5 +689,11 @@ return 'modular_citadel/icons/ui/screen_operative.dmi' if('icons/mob/screen_clockwork.dmi') return 'modular_citadel/icons/ui/screen_clockwork.dmi' + if('icons/mob/screen_glass.dmi') + return 'modular_citadel/icons/ui/screen_glass.dmi' + if('icons/mob/screen_trasenknox.dmi') + return 'modular_citadel/icons/ui/screen_trasenknox.dmi' + if('icons/mob/screen_detective.dmi') + return 'modular_citadel/icons/ui/screen_detective.dmi' else return 'modular_citadel/icons/ui/screen_midnight.dmi' diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm index 798acad4aa..53d69fe01e 100644 --- a/code/_onclick/hud/hud.dm +++ b/code/_onclick/hud/hud.dm @@ -11,7 +11,10 @@ GLOBAL_LIST_INIT(available_ui_styles, list( "Plasmafire" = 'icons/mob/screen_plasmafire.dmi', "Slimecore" = 'icons/mob/screen_slimecore.dmi', "Operative" = 'icons/mob/screen_operative.dmi', - "Clockwork" = 'icons/mob/screen_clockwork.dmi' + "Glass" = 'icons/mob/screen_glass.dmi', + "Clockwork" = 'icons/mob/screen_clockwork.dmi', + "Trasen-Knox" = 'icons/mob/screen_trasenknox.dmi', + "Detective" = 'icons/mob/screen_detective.dmi', )) /proc/ui_style2icon(ui_style) @@ -646,4 +649,4 @@ GLOBAL_LIST_INIT(available_ui_styles, list( /datum/action_group/listed/refresh_actions() . = ..() - owner.palette_actions.refresh_actions() // We effect them, so we gotta refresh em + owner?.palette_actions.refresh_actions() // We effect them, so we gotta refresh em diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm index 6d7c25120a..8e7953bdd5 100644 --- a/code/_onclick/hud/human.dm +++ b/code/_onclick/hud/human.dm @@ -324,11 +324,11 @@ using.hud = src hotkeybuttons += using - using = new /atom/movable/screen/rest() - using.icon = ui_style - using.screen_loc = ui_pull_resist - using.hud = src - static_inventory += using + rest_icon = new /atom/movable/screen/rest() + rest_icon.icon = ui_style + rest_icon.screen_loc = ui_pull_resist + rest_icon.hud = src + static_inventory += rest_icon //END OF CIT CHANGES using = new /atom/movable/screen/human/toggle() diff --git a/code/_onclick/hud/new_player.dm b/code/_onclick/hud/new_player.dm index b01199c6c2..c5d3cbca89 100644 --- a/code/_onclick/hud/new_player.dm +++ b/code/_onclick/hud/new_player.dm @@ -5,6 +5,12 @@ ///Whether the menu is currently on the client's screen or not var/menu_hud_status = TRUE +/datum/hud/new_player/New(mob/dead/new_player/owner) + . = ..() + if(!owner.age_verify()) + return + populate_buttons(owner) + /datum/hud/new_player/proc/populate_buttons(mob/dead/new_player/owner) var/list/buttons = subtypesof(/atom/movable/screen/lobby) for(var/button_type in buttons) diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index 231f8db6f0..72756c9abf 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -154,9 +154,8 @@ if(!icon_empty) icon_empty = icon_state - if(!hud?.mymob || !slot_id || !icon_full) - return ..() - icon_state = hud.mymob.get_item_by_slot(slot_id) ? icon_full : icon_empty + if(hud?.mymob && slot_id && icon_full) + icon_state = hud.mymob.get_item_by_slot(slot_id) ? icon_full : icon_empty return ..() /atom/movable/screen/inventory/proc/add_overlays() @@ -207,7 +206,7 @@ . += blocked_overlay if(held_index == hud.mymob.active_hand_index) - . += "hand_active" + . += (held_index % 2) ? "lhandactive" : "rhandactive" /atom/movable/screen/inventory/hand/Click(location, control, params) @@ -411,6 +410,7 @@ name = "rest" icon = 'icons/mob/screen_midnight.dmi' icon_state = "act_rest" + base_icon_state = "act_rest" plane = HUD_PLANE /atom/movable/screen/rest/Click() @@ -422,10 +422,7 @@ var/mob/living/user = hud?.mymob if(!istype(user)) return ..() - if(!user.resting) - icon_state = "act_rest" - else - icon_state = "act_rest0" + icon_state = "[base_icon_state][user.resting ? 0 : null]" return ..() /atom/movable/screen/throw_catch diff --git a/code/datums/components/crafting/crafting.dm b/code/datums/components/crafting/crafting.dm index 3ed3e521e4..8e9124c306 100644 --- a/code/datums/components/crafting/crafting.dm +++ b/code/datums/components/crafting/crafting.dm @@ -1,17 +1,13 @@ /datum/component/personal_crafting/Initialize() if(ismob(parent)) - RegisterSignal(parent, COMSIG_MOB_CLIENT_LOGIN, .proc/create_mob_button) + RegisterSignal(parent, COMSIG_MOB_HUD_CREATED, .proc/create_mob_button) -/datum/component/personal_crafting/proc/create_mob_button(mob/user, client/CL) +/datum/component/personal_crafting/proc/create_mob_button(mob/user) var/datum/hud/H = user.hud_used - for(var/huds in H.static_inventory) - if(istype(huds, /atom/movable/screen/craft)) - return - //We don't want to be stacking multiple crafting huds on relogs var/atom/movable/screen/craft/C = new() C.icon = H.ui_style H.static_inventory += C - CL.screen += C + user.client.screen += C RegisterSignal(C, COMSIG_CLICK, .proc/component_ui_interact) /datum/component/personal_crafting diff --git a/code/datums/elements/object_reskinning.dm b/code/datums/elements/object_reskinning.dm index 63e8a35d05..2d994a04d0 100644 --- a/code/datums/elements/object_reskinning.dm +++ b/code/datums/elements/object_reskinning.dm @@ -65,7 +65,7 @@ icon = to_reskin.unique_reskin[reskin_option]["icon"] ? to_reskin.unique_reskin[reskin_option]["icon"] : to_reskin.icon, icon_state = to_reskin.unique_reskin[reskin_option]["icon_state"] ? to_reskin.unique_reskin[reskin_option]["icon_state"] : to_reskin.icon_state) items += list("[reskin_option]" = item_image) - sort_list(items) + items = sort_list(items) // Display to the user var/pick = show_radial_menu(user, to_reskin, items, custom_check = CALLBACK(src, .proc/check_reskin_menu, user, to_reskin), radius = 38, require_near = TRUE) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 1da8c7717a..6a7b78b8dd 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -1356,6 +1356,11 @@ if(filter_data && filter_data[name]) return filters[filter_data.Find(name)] +/// Returns the indice in filters of the given filter name. +/// If it is not found, returns null. +/atom/proc/get_filter_index(name) + return filter_data?.Find(name) + /atom/proc/remove_filter(name_or_names) if(!filter_data) return diff --git a/code/game/objects/effects/decals/misc.dm b/code/game/objects/effects/decals/misc.dm index 752a5dff2c..fe216c0623 100644 --- a/code/game/objects/effects/decals/misc.dm +++ b/code/game/objects/effects/decals/misc.dm @@ -1,18 +1,3 @@ -/obj/effect/temp_visual/point - name = "pointer" - icon = 'icons/mob/screen_gen.dmi' - icon_state = "arrow" - layer = POINT_LAYER - duration = 25 - -/obj/effect/temp_visual/point/Initialize(mapload, set_invis = 0) - . = ..() - var/atom/old_loc = loc - loc = get_turf(src) // We don't want to actualy trigger anything when it moves - pixel_x = old_loc.pixel_x - pixel_y = old_loc.pixel_y - invisibility = set_invis - //Used by spraybottles. /obj/effect/decal/chempuff name = "chemicals" diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 0178a8b688..ae94681f56 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -922,13 +922,13 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb /obj/item/MouseDrop(atom/over, src_location, over_location, src_control, over_control, params) . = ..() - remove_filter("hover_outline") //get rid of the hover effect in case the mouse exit isn't called if someone drags and drops an item and somthing goes wrong + remove_filter(HOVER_OUTLINE_FILTER) //get rid of the hover effect in case the mouse exit isn't called if someone drags and drops an item and somthing goes wrong /obj/item/MouseExited(location, control, params) SEND_SIGNAL(src, COMSIG_ITEM_MOUSE_EXIT, location, control, params) deltimer(usr.client.tip_timer) //delete any in-progress timer if the mouse is moved off the item before it finishes closeToolTip(usr) - remove_filter("hover_outline") + remove_filter(HOVER_OUTLINE_FILTER) /obj/item/proc/apply_outline(outline_color = null) if(get(src, /mob) != usr || QDELETED(src) || isobserver(usr)) //cancel if the item isn't in an inventory, is being deleted, or if the person hovering is a ghost (so that people spectating you don't randomly make your items glow) @@ -950,12 +950,16 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb outline_color = COLOR_THEME_CLOCKWORK //if you want free gbp go fix the fact that clockwork's tooltip css is glass' if("glass") outline_color = COLOR_THEME_GLASS + if("trasen-knox") + outline_color = COLOR_THEME_TRASENKNOX + if("detective") + outline_color = COLOR_THEME_DETECTIVE else //this should never happen, hopefully outline_color = COLOR_WHITE if(color) outline_color = COLOR_WHITE //if the item is recolored then the outline will be too, let's make the outline white so it becomes the same color instead of some ugly mix of the theme and the tint - add_filter("hover_outline", 1, list("type" = "outline", "size" = 1, "color" = outline_color)) + add_filter(HOVER_OUTLINE_FILTER, 1, list("type" = "outline", "size" = 1, "color" = outline_color)) // Called when a mob tries to use the item as a tool. // Handles most checks. diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm index 6b9d1e8018..defdfd6402 100644 --- a/code/game/objects/items/stacks/medical.dm +++ b/code/game/objects/items/stacks/medical.dm @@ -217,6 +217,7 @@ /obj/item/stack/medical/gauze/cyborg custom_materials = null is_cyborg = TRUE + source = /datum/robot_energy_storage/medical cost = 250 /obj/item/stack/medical/suture @@ -441,6 +442,7 @@ /obj/item/stack/medical/bone_gel/cyborg custom_materials = null is_cyborg = TRUE + source = /datum/robot_energy_storage/medical cost = 250 /obj/item/stack/medical/aloe diff --git a/code/game/objects/items/stacks/rods.dm b/code/game/objects/items/stacks/rods.dm index 6a0ed45e30..c0fde9ce73 100644 --- a/code/game/objects/items/stacks/rods.dm +++ b/code/game/objects/items/stacks/rods.dm @@ -39,7 +39,7 @@ GLOBAL_LIST_INIT(rod_recipes, list ( \ /obj/item/stack/rods/update_icon_state() var/amount = get_amount() - if(amount <= 5) + if(amount <= 5 && amount >= 1) icon_state = "rods-[amount]" else icon_state = "rods" @@ -77,11 +77,8 @@ GLOBAL_LIST_INIT(rod_recipes, list ( \ /obj/item/stack/rods/cyborg custom_materials = null is_cyborg = TRUE - cost = 250 - -/obj/item/stack/rods/cyborg/ComponentInitialize() - . = ..() - AddElement(/datum/element/update_icon_blocker) + source = /datum/robot_energy_storage/medical + cost = MINERAL_MATERIAL_AMOUNT * 0.125 /obj/item/stack/rods/ten amount = 10 diff --git a/code/game/objects/items/stacks/sheets/glass.dm b/code/game/objects/items/stacks/sheets/glass.dm index 1eb49f350c..929b572e06 100644 --- a/code/game/objects/items/stacks/sheets/glass.dm +++ b/code/game/objects/items/stacks/sheets/glass.dm @@ -52,7 +52,8 @@ GLOBAL_LIST_INIT(glass_recipes, list ( \ /obj/item/stack/sheet/glass/cyborg custom_materials = null is_cyborg = TRUE - cost = 500 + source = /datum/robot_energy_storage/glass + cost = MINERAL_MATERIAL_AMOUNT * 0.25 /obj/item/stack/sheet/glass/fifty amount = 50 @@ -179,9 +180,15 @@ GLOBAL_LIST_INIT(reinforced_glass_recipes, list ( \ /obj/item/stack/sheet/rglass/cyborg custom_materials = null is_cyborg = TRUE - var/datum/robot_energy_storage/glasource - var/metcost = 250 - var/glacost = 500 + source = /datum/robot_energy_storage/metal + var/datum/robot_energy_storage/glasource = /datum/robot_energy_storage/glass + var/metcost = MINERAL_MATERIAL_AMOUNT * 0.125 + var/glacost = MINERAL_MATERIAL_AMOUNT * 0.25 + +/obj/item/stack/sheet/rglass/cyborg/prepare_estorage(obj/item/robot_module/module) + . = ..() + if(glasource) + glasource = module.get_or_create_estorage(glasource) /obj/item/stack/sheet/rglass/cyborg/get_amount() return min(round(source.energy / metcost), round(glasource.energy / glacost)) @@ -189,10 +196,12 @@ GLOBAL_LIST_INIT(reinforced_glass_recipes, list ( \ /obj/item/stack/sheet/rglass/cyborg/use(used, transfer = FALSE) // Requires special checks, because it uses two storages source.use_charge(used * metcost) glasource.use_charge(used * glacost) + update_icon() /obj/item/stack/sheet/rglass/cyborg/add(amount) source.add_charge(amount * metcost) glasource.add_charge(amount * glacost) + update_icon() /obj/item/stack/sheet/rglass/get_main_recipes() . = ..() diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index 070c5122c4..745fa6a321 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -164,7 +164,8 @@ GLOBAL_LIST_INIT(metal_recipes, list ( \ /obj/item/stack/sheet/metal/cyborg custom_materials = null is_cyborg = TRUE - cost = 500 + source = /datum/robot_energy_storage/metal + cost = MINERAL_MATERIAL_AMOUNT * 0.25 /obj/item/stack/sheet/metal/get_main_recipes() . = ..() diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm index 7555763f4e..7eca36247f 100644 --- a/code/game/objects/items/stacks/stack.dm +++ b/code/game/objects/items/stacks/stack.dm @@ -42,6 +42,12 @@ var/matter_amount = 0 /obj/item/stack/Initialize(mapload, new_amount, merge = TRUE) + if(is_cyborg) + if(!istype(loc, /obj/item/robot_module)) + stack_trace("Cyborg stack created outside of a robot module, deleting.") + return INITIALIZE_HINT_QDEL + prepare_estorage(loc) + if(new_amount != null) amount = new_amount while(amount > max_amount) @@ -383,7 +389,9 @@ if(check && zero_amount()) return FALSE if (is_cyborg) - return source.use_charge(used * cost) + . = source.use_charge(used * cost) + update_icon() + return if (amount < used) return FALSE amount -= used @@ -486,9 +494,53 @@ return //get amount from user var/max = get_amount() - var/stackmaterial = round(input(user,"How many sheets do you wish to take out of this stack? (Maximum [max])") as null|num) - max = get_amount() - stackmaterial = min(max, stackmaterial) + var/list/quick_split + for(var/option in list(2, 3, 4, 5, 6, 7, "One", "Five", "Ten", "Custom")) + var/mutable_appearance/option_display = new(src) + option_display.filters = null + option_display.cut_overlays() + option_display.pixel_x = 0 + option_display.pixel_y = 0 + + switch(option) + if("Custom") + var/list/sort_numbers = quick_split + sort_numbers = sort_list(sort_numbers, /proc/cmp_numeric_text_desc) + option_display.maptext = MAPTEXT("?") + quick_split = list("Custom" = option_display) + quick_split += sort_numbers + if("One") + option = 1 + option_display.maptext = MAPTEXT("1") + if("Five") + if(max > 5) + option = 5 + option_display.maptext = MAPTEXT("5") + else + continue + if("Ten") + if(max > 10) + option = 10 + option_display.maptext = MAPTEXT("10") + else + continue + else + if(max % option == 0) + option_display.maptext = MAPTEXT(max / option) + option = max / option + else + continue + if(option != "Custom") + LAZYSET(quick_split, "[option]", option_display) + var/stackmaterial + if(length(quick_split) <= 2) + stackmaterial = round(input(user, "How many sheets do you wish to take out of this stack?\nMax: [max]") as null|num) + else + stackmaterial = show_radial_menu(user, get_atom_on_turf(src), quick_split, require_near = TRUE, tooltips = TRUE) + if(stackmaterial == "Custom") + stackmaterial = round(input(user, "How many sheets do you wish to take out of this stack?\nMax: [max]") as null|num) + stackmaterial = isnum(stackmaterial) ? stackmaterial : text2num(stackmaterial) + stackmaterial = min(get_amount(), stackmaterial) if(stackmaterial == null || stackmaterial <= 0 || !user.canUseTopic(src, BE_CLOSE, TRUE, FALSE)) //, !iscyborg(user) return split_stack(user, stackmaterial) @@ -539,3 +591,12 @@ /obj/item/stack/microwave_act(obj/machinery/microwave/M) if(istype(M) && M.dirty < 100) M.dirty += amount + +/obj/item/stack/proc/prepare_estorage(obj/item/robot_module/module) + if(source) + source = module.get_or_create_estorage(source) + +/obj/item/stack/Moved(old_loc, dir) + . = ..() + if(isturf(loc)) + update_icon() diff --git a/code/game/objects/items/stacks/tiles/tile_types.dm b/code/game/objects/items/stacks/tiles/tile_types.dm index 836ef04f31..84ccdfb1c5 100644 --- a/code/game/objects/items/stacks/tiles/tile_types.dm +++ b/code/game/objects/items/stacks/tiles/tile_types.dm @@ -536,7 +536,8 @@ /obj/item/stack/tile/plasteel/cyborg custom_materials = null // All other Borg versions of items have no Metal or Glass - RR is_cyborg = TRUE - cost = 125 + source = /datum/robot_energy_storage/metal + cost = MINERAL_MATERIAL_AMOUNT * 0.0625 /obj/item/stack/tile/material name = "floor tile" diff --git a/code/game/objects/items/stacks/wrap.dm b/code/game/objects/items/stacks/wrap.dm index 9b8c0fa130..5fa4537794 100644 --- a/code/game/objects/items/stacks/wrap.dm +++ b/code/game/objects/items/stacks/wrap.dm @@ -40,6 +40,12 @@ resistance_flags = FLAMMABLE grind_results = list(/datum/reagent/cellulose = 5) +/obj/item/stack/packageWrap/cyborg + custom_materials = null + is_cyborg = TRUE + source = /datum/robot_energy_storage/wrapping_paper + cost = 1 + /obj/item/stack/packageWrap/suicide_act(mob/living/user) user.visible_message("[user] begins wrapping [user.p_them()]self in \the [src]! It looks like [user.p_theyre()] trying to commit suicide!") if(use(3)) diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 4ccab2df4b..70a58bcffb 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -2631,8 +2631,10 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/pickedui = input(user, "Choose your UI style.", "Character Preference", UI_style) as null|anything in GLOB.available_ui_styles if(pickedui) UI_style = pickedui - if (parent && parent.mob && parent.mob.hud_used) - parent.mob.hud_used.update_ui_style(ui_style2icon(UI_style)) + if (pickedui && parent && parent.mob && parent.mob.hud_used) + QDEL_NULL(parent.mob.hud_used) + parent.mob.create_mob_hud() + parent.mob.hud_used.show_hud(1, parent.mob) if("pda_style") var/pickedPDAStyle = input(user, "Choose your PDA style.", "Character Preference", pda_style) as null|anything in GLOB.pda_styles if(pickedPDAStyle) @@ -3007,7 +3009,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) outline_enabled = !outline_enabled if("outline_color") var/pickedOutlineColor = input(user, "Choose your outline color.", "General Preference", outline_color) as color|null - if(pickedOutlineColor != pickedOutlineColor) + if(pickedOutlineColor != outline_color) outline_color = pickedOutlineColor // nullable if("screentip_pref") var/choice = input(user, "Choose your screentip preference", "Screentipping?", screentip_pref) as null|anything in GLOB.screentip_pref_options diff --git a/code/modules/mining/equipment/marker_beacons.dm b/code/modules/mining/equipment/marker_beacons.dm index d8e54ae322..3ec466dad4 100644 --- a/code/modules/mining/equipment/marker_beacons.dm +++ b/code/modules/mining/equipment/marker_beacons.dm @@ -31,6 +31,12 @@ GLOBAL_LIST_INIT(marker_beacon_colors, list( /obj/item/stack/marker_beacon/thirty //and they're bought in stacks of 1, 10, or 30 amount = 30 +/obj/item/stack/marker_beacon/cyborg + is_cyborg = TRUE + custom_materials = null + source = /datum/robot_energy_storage/beacon + cost = 1 + /obj/item/stack/marker_beacon/Initialize(mapload) . = ..() update_icon() diff --git a/code/modules/mob/living/living_mobility.dm b/code/modules/mob/living/living_mobility.dm index 6aed30ab83..50d377abf7 100644 --- a/code/modules/mob/living/living_mobility.dm +++ b/code/modules/mob/living/living_mobility.dm @@ -16,6 +16,7 @@ /mob/living/proc/update_resting(update_mobility = TRUE) if(update_mobility) update_mobility() + update_rest_hud_icon() //Force mob to rest, does NOT do stamina damage. //It's really not recommended to use this proc to give feedback, hence why silent is defaulting to true. diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm index 7d3427a916..dcddff49d1 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -86,7 +86,7 @@ if(!(m in R.held_items)) . += m -/obj/item/robot_module/proc/get_or_create_estorage(var/storage_type) +/obj/item/robot_module/proc/get_or_create_estorage(storage_type) for(var/datum/robot_energy_storage/S in storages) if(istype(S, storage_type)) return S @@ -95,42 +95,9 @@ /obj/item/robot_module/proc/add_module(obj/item/I, nonstandard, requires_rebuild) rad_flags |= RAD_NO_CONTAMINATE - if(istype(I, /obj/item/stack)) - var/obj/item/stack/S = I - - if(is_type_in_list(S, list(/obj/item/stack/sheet/metal, /obj/item/stack/rods, /obj/item/stack/tile/plasteel))) - if(S.custom_materials?.len && S.custom_materials[SSmaterials.GetMaterialRef(/datum/material/iron)]) - S.cost = S.custom_materials[SSmaterials.GetMaterialRef(/datum/material/iron)] * 0.25 - S.source = get_or_create_estorage(/datum/robot_energy_storage/metal) - - else if(istype(S, /obj/item/stack/sheet/glass)) - S.cost = 500 - S.source = get_or_create_estorage(/datum/robot_energy_storage/glass) - - else if(istype(S, /obj/item/stack/sheet/rglass/cyborg)) - var/obj/item/stack/sheet/rglass/cyborg/G = S - G.source = get_or_create_estorage(/datum/robot_energy_storage/metal) - G.glasource = get_or_create_estorage(/datum/robot_energy_storage/glass) - - else if(istype(S, /obj/item/stack/medical)) - S.cost = 250 - S.source = get_or_create_estorage(/datum/robot_energy_storage/medical) - - else if(istype(S, /obj/item/stack/cable_coil)) - S.cost = 1 - S.source = get_or_create_estorage(/datum/robot_energy_storage/wire) - - else if(istype(S, /obj/item/stack/marker_beacon)) - S.cost = 1 - S.source = get_or_create_estorage(/datum/robot_energy_storage/beacon) - - else if(istype(S, /obj/item/stack/packageWrap)) - S.cost = 1 - S.source = get_or_create_estorage(/datum/robot_energy_storage/wrapping_paper) - - if(S && S.source) - S.set_custom_materials(null) - S.is_cyborg = 1 + var/obj/item/stack/S = I + if(istype(I, /obj/item/stack) && !S.is_cyborg) // Now handled in the type itself + stack_trace("Non-cyborg variant of /obj/item/stack added to a cyborg's modules.") if(I.loc != src) I.forceMove(src) @@ -935,9 +902,9 @@ /obj/item/gps/cyborg, /obj/item/gripper/mining, /obj/item/cyborg_clamp, - /obj/item/stack/marker_beacon, + /obj/item/stack/marker_beacon/cyborg, /obj/item/destTagger, - /obj/item/stack/packageWrap, + /obj/item/stack/packageWrap/cyborg, /obj/item/card/id/miningborg) emag_modules = list(/obj/item/borg/stun) ratvar_modules = list( @@ -1056,7 +1023,7 @@ /obj/item/surgicaldrill, /obj/item/scalpel, /obj/item/bonesetter, - /obj/item/stack/medical/bone_gel, + /obj/item/stack/medical/bone_gel/cyborg, /obj/item/melee/transforming/energy/sword/cyborg/saw, /obj/item/roller/robo, /obj/item/card/emag, @@ -1191,7 +1158,7 @@ /obj/item/surgicaldrill, /obj/item/scalpel, /obj/item/bonesetter, - /obj/item/stack/medical/bone_gel, + /obj/item/stack/medical/bone_gel/cyborg, /obj/item/melee/transforming/energy/sword/cyborg/saw, /obj/item/roller/robo, /obj/item/stack/medical/gauze/cyborg, diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index f2d4f7cd58..1e34bb722d 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -369,27 +369,6 @@ var/msg = "[src] makes eye contact with you." addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, examined_mob, msg), 3) -//same as above -//note: ghosts can point, this is intended -//visible_message will handle invisibility properly -//overridden here and in /mob/dead/observer for different point span classes and sanity checks -/mob/verb/pointed(atom/A as mob|obj|turf in fov_view()) - set name = "Point To" - set category = "Object" - - if(!src || !isturf(src.loc) || !(A in view(src.loc))) - return FALSE - if(istype(A, /obj/effect/temp_visual/point)) - return FALSE - - var/tile = get_turf(A) - if (!tile) - return FALSE - - new /obj/effect/temp_visual/point(A,invisibility) - SEND_SIGNAL(src, COMSIG_MOB_POINTED, A) - return TRUE - /mob/proc/can_resist() return FALSE //overridden in living.dm diff --git a/code/modules/point/point.dm b/code/modules/point/point.dm new file mode 100644 index 0000000000..cfadf391c5 --- /dev/null +++ b/code/modules/point/point.dm @@ -0,0 +1,110 @@ +#define POINT_TIME (2.5 SECONDS) + +/** + * Point at an atom + * + * Intended to enable and standardise the pointing animation for all atoms + * + * Not intended as a replacement for the mob verb + */ +/atom/movable/proc/point_at(atom/pointed_atom) + if(!isturf(loc)) + return + + if (pointed_atom in src) + create_point_bubble(pointed_atom) + return + + var/turf/tile = get_turf(pointed_atom) + if (!tile) + return + + var/turf/our_tile = get_turf(src) + var/obj/visual = new /obj/effect/temp_visual/point(our_tile, invisibility) + + animate(visual, pixel_x = (tile.x - our_tile.x) * world.icon_size + pointed_atom.pixel_x, pixel_y = (tile.y - our_tile.y) * world.icon_size + pointed_atom.pixel_y, time = 1.7, easing = EASE_OUT) + +/atom/movable/proc/create_point_bubble(atom/pointed_atom) + var/obj/effect/thought_bubble_effect = new + + var/mutable_appearance/thought_bubble = mutable_appearance( + 'icons/effects/effects.dmi', + "thought_bubble", + layer = POINT_LAYER, + appearance_flags = KEEP_APART, + ) + + var/mutable_appearance/pointed_atom_appearance = new(pointed_atom.appearance) + pointed_atom_appearance.blend_mode = BLEND_INSET_OVERLAY + pointed_atom_appearance.plane = thought_bubble.plane + pointed_atom_appearance.layer = FLOAT_LAYER + pointed_atom_appearance.pixel_x = 0 + pointed_atom_appearance.pixel_y = 0 + thought_bubble.overlays += pointed_atom_appearance + + var/hover_outline_index = pointed_atom.get_filter_index(HOVER_OUTLINE_FILTER) + if (!isnull(hover_outline_index)) + pointed_atom_appearance.filters.Cut(hover_outline_index, hover_outline_index + 1) + + thought_bubble.pixel_x = 16 + thought_bubble.pixel_y = 32 + thought_bubble.alpha = 200 + thought_bubble.mouse_opacity = MOUSE_OPACITY_TRANSPARENT + + var/mutable_appearance/point_visual = mutable_appearance( + 'icons/mob/screen_gen.dmi', + "arrow", + plane = thought_bubble.plane, + ) + + thought_bubble.overlays += point_visual + + // vis_contents is used to preserve mouse opacity + thought_bubble_effect.appearance = thought_bubble + vis_contents += thought_bubble_effect + + QDEL_IN(thought_bubble_effect, POINT_TIME) + +/obj/effect/temp_visual/point + name = "pointer" + icon = 'icons/mob/screen_gen.dmi' + icon_state = "arrow" + layer = POINT_LAYER + duration = POINT_TIME + +/obj/effect/temp_visual/point/Initialize(mapload, set_invis = 0) + . = ..() + var/atom/old_loc = loc + abstract_move(get_turf(src)) + pixel_x = old_loc.pixel_x + pixel_y = old_loc.pixel_y + invisibility = set_invis + +#undef POINT_TIME + +/** + * Point at an atom + * + * mob verbs are faster than object verbs. See + * [this byond forum post](https://secure.byond.com/forum/?post=1326139&page=2#comment8198716) + * for why this isn't atom/verb/pointed() + * + * note: ghosts can point, this is intended + * + * visible_message will handle invisibility properly + * + * overridden here and in /mob/dead/observer for different point span classes and sanity checks + */ +/mob/verb/pointed(atom/target as mob|obj|turf in fov_view()) + set name = "Point To" + set category = "Object" + + if(client && !(target in view(client.view, src))) + return FALSE + if(istype(target, /obj/effect/temp_visual/point)) + return FALSE + + point_at(target) + + SEND_SIGNAL(src, COMSIG_MOB_POINTED, target) + return TRUE diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index 5aa16c0c29..32c136dd90 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -517,6 +517,7 @@ By design, d1 is the smallest direction and d2 is the highest /obj/item/stack/cable_coil/cyborg is_cyborg = TRUE custom_materials = null + source = /datum/robot_energy_storage/wire cost = 1 /obj/item/stack/cable_coil/cyborg/attack_self(mob/user) diff --git a/code/modules/tooltip/tooltip.html b/code/modules/tooltip/tooltip.html index b66d48d6c6..2f60a2b0b1 100644 --- a/code/modules/tooltip/tooltip.html +++ b/code/modules/tooltip/tooltip.html @@ -80,12 +80,21 @@ .slimecore .wrap {border-color: #18640E;} .slimecore .content {color: #6EA161; border-color: #11450B; background-color: #354E35;} - .operative .wrap {border-color: #1E0101;} - .operative .content {color: #FFFFFF; border-color: #750000; background-color: #350000;} + .operative .wrap {border-color: #13121b;} + .operative .content {color: #b01232; border-color: #13121b; background-color: #282831;} .clockwork .wrap {border-color: #170800;} .clockwork .content {color: #B18B25; border-color: #000000; background-color: #5F380E;} + .glass .wrap {border-color: #273844;} + .glass .content {color: #5b7588; border-color: #273844; background-color: #1f252b;} + + .trasen-knox .wrap {border-color: #998e81;} + .trasen-knox .content {color: #3ce375; border-color: #998e81; background-color: #1e1d21;} + + .detective .wrap {border-color: #2c0F0c;} + .detective .content {color: #c7b08b; border-color: #2c0F0c; background-color: #221c1a;} + diff --git a/icons/effects/effects.dmi b/icons/effects/effects.dmi index be99d57a3d..8334c83224 100644 Binary files a/icons/effects/effects.dmi and b/icons/effects/effects.dmi differ diff --git a/icons/hud/64x16_actions.dmi b/icons/hud/64x16_actions.dmi index ae81ace4d5..23865a80f0 100644 Binary files a/icons/hud/64x16_actions.dmi and b/icons/hud/64x16_actions.dmi differ diff --git a/icons/mob/screen_alien.dmi b/icons/mob/screen_alien.dmi index b20bfaa405..ddb99fdb68 100644 Binary files a/icons/mob/screen_alien.dmi and b/icons/mob/screen_alien.dmi differ diff --git a/icons/mob/screen_clockwork.dmi b/icons/mob/screen_clockwork.dmi index 0cd15937ed..d84503c768 100644 Binary files a/icons/mob/screen_clockwork.dmi and b/icons/mob/screen_clockwork.dmi differ diff --git a/icons/mob/screen_detective.dmi b/icons/mob/screen_detective.dmi new file mode 100644 index 0000000000..5de29ad1e8 Binary files /dev/null and b/icons/mob/screen_detective.dmi differ diff --git a/icons/mob/screen_glass.dmi b/icons/mob/screen_glass.dmi new file mode 100644 index 0000000000..4948171883 Binary files /dev/null and b/icons/mob/screen_glass.dmi differ diff --git a/icons/mob/screen_midnight.dmi b/icons/mob/screen_midnight.dmi index ec583eb485..c180ed4f37 100644 Binary files a/icons/mob/screen_midnight.dmi and b/icons/mob/screen_midnight.dmi differ diff --git a/icons/mob/screen_operative.dmi b/icons/mob/screen_operative.dmi index fd3879e428..8e2eeaa315 100644 Binary files a/icons/mob/screen_operative.dmi and b/icons/mob/screen_operative.dmi differ diff --git a/icons/mob/screen_plasmafire.dmi b/icons/mob/screen_plasmafire.dmi index 7e1fb8308f..18f99515b9 100644 Binary files a/icons/mob/screen_plasmafire.dmi and b/icons/mob/screen_plasmafire.dmi differ diff --git a/icons/mob/screen_retro.dmi b/icons/mob/screen_retro.dmi index e7c40db5d3..8c8b920908 100644 Binary files a/icons/mob/screen_retro.dmi and b/icons/mob/screen_retro.dmi differ diff --git a/icons/mob/screen_slimecore.dmi b/icons/mob/screen_slimecore.dmi index 3d335a846f..91b01910e3 100644 Binary files a/icons/mob/screen_slimecore.dmi and b/icons/mob/screen_slimecore.dmi differ diff --git a/icons/mob/screen_trasenknox.dmi b/icons/mob/screen_trasenknox.dmi new file mode 100644 index 0000000000..bf229f7bad Binary files /dev/null and b/icons/mob/screen_trasenknox.dmi differ diff --git a/modular_citadel/icons/ui/screen_detective.dmi b/modular_citadel/icons/ui/screen_detective.dmi new file mode 100644 index 0000000000..ef012d3e84 Binary files /dev/null and b/modular_citadel/icons/ui/screen_detective.dmi differ diff --git a/modular_citadel/icons/ui/screen_glass.dmi b/modular_citadel/icons/ui/screen_glass.dmi new file mode 100644 index 0000000000..d03ba9edae Binary files /dev/null and b/modular_citadel/icons/ui/screen_glass.dmi differ diff --git a/modular_citadel/icons/ui/screen_operative.dmi b/modular_citadel/icons/ui/screen_operative.dmi index 5e8abb5431..0f9173091b 100644 Binary files a/modular_citadel/icons/ui/screen_operative.dmi and b/modular_citadel/icons/ui/screen_operative.dmi differ diff --git a/modular_citadel/icons/ui/screen_trasenknox.dmi b/modular_citadel/icons/ui/screen_trasenknox.dmi new file mode 100644 index 0000000000..ef418fdf94 Binary files /dev/null and b/modular_citadel/icons/ui/screen_trasenknox.dmi differ diff --git a/tgstation.dme b/tgstation.dme index 2b8e694dd3..45d3f018ad 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -3178,6 +3178,7 @@ #include "code\modules\plumbing\plumbers\reaction_chamber.dm" #include "code\modules\plumbing\plumbers\splitters.dm" #include "code\modules\plumbing\plumbers\synthesizer.dm" +#include "code\modules\point\point.dm" #include "code\modules\pool\pool_controller.dm" #include "code\modules\pool\pool_drain.dm" #include "code\modules\pool\pool_effects.dm"