From 15bcc0f6d5272cd2957a273d1032987783a5bcac Mon Sep 17 00:00:00 2001 From: Matt Atlas Date: Fri, 24 Apr 2020 17:00:30 +0200 Subject: [PATCH] Radials, Tooltips, RCD and Borg Selection (#8710) --- SQL/migrate/V046__radials.sql | 7 + aurorastation.dme | 3 + code/_helpers/lists.dm | 6 + code/_onclick/hud/radial.dm | 315 ++++++++++++++++++ code/_onclick/hud/radial_persistent.dm | 71 ++++ code/game/objects/items/weapons/RFD.dm | 59 ++-- code/game/objects/items/weapons/tools.dm | 10 +- code/modules/client/client defines.dm | 3 +- code/modules/client/client procs.dm | 9 +- .../client/preference_setup/global/01_ui.dm | 35 +- code/modules/client/preferences.dm | 2 + code/modules/client/ui_style.dm | 14 +- code/modules/heavy_vehicle/mech_movement.dm | 2 +- .../modules/mob/living/silicon/robot/login.dm | 2 +- .../modules/mob/living/silicon/robot/robot.dm | 31 +- .../mob/living/silicon/robot/robot_modules.dm | 2 - code/modules/tooltip/tooltip.dm | 115 +++++++ code/modules/tooltip/tooltip.html | 249 ++++++++++++++ html/changelogs/mattatlas-radials.yml | 42 +++ icons/mob/screen/radial.dmi | Bin 0 -> 16655 bytes icons/obj/rfd.dmi | Bin 0 -> 2449 bytes icons/obj/tools.dmi | Bin 25067 -> 14155 bytes interface/skin.dmf | 9 + 23 files changed, 923 insertions(+), 63 deletions(-) create mode 100644 SQL/migrate/V046__radials.sql create mode 100644 code/_onclick/hud/radial.dm create mode 100644 code/_onclick/hud/radial_persistent.dm create mode 100644 code/modules/tooltip/tooltip.dm create mode 100644 code/modules/tooltip/tooltip.html create mode 100644 html/changelogs/mattatlas-radials.yml create mode 100644 icons/mob/screen/radial.dmi create mode 100644 icons/obj/rfd.dmi diff --git a/SQL/migrate/V046__radials.sql b/SQL/migrate/V046__radials.sql new file mode 100644 index 00000000000..05294a2a95e --- /dev/null +++ b/SQL/migrate/V046__radials.sql @@ -0,0 +1,7 @@ +-- +-- Adds support for underwear updates in PR #8710. +-- What else do you think this does? +-- + +ALTER TABLE `ss13_player_preferences` + ADD `tooltip_style` ENUM('Midnight', 'Plasmafire', 'Retro', 'Slimecore', 'Operative', 'Clockwork') NULL DEFAULT 'Midnight'; diff --git a/aurorastation.dme b/aurorastation.dme index 39d019a09fb..66820e30554 100644 --- a/aurorastation.dme +++ b/aurorastation.dme @@ -112,6 +112,8 @@ #include "code\_onclick\hud\movable_screen_objects.dm" #include "code\_onclick\hud\other_mobs.dm" #include "code\_onclick\hud\parallax.dm" +#include "code\_onclick\hud\radial.dm" +#include "code\_onclick\hud\radial_persistent.dm" #include "code\_onclick\hud\robot.dm" #include "code\_onclick\hud\screen_objects.dm" #include "code\_onclick\hud\spell_screen_objects.dm" @@ -2686,6 +2688,7 @@ #include "code\modules\telesci\telepad.dm" #include "code\modules\telesci\telesci_computer.dm" #include "code\modules\tgs\includes.dm" +#include "code\modules\tooltip\tooltip.dm" #include "code\modules\turbolift\turbolift.dm" #include "code\modules\turbolift\turbolift_areas.dm" #include "code\modules\turbolift\turbolift_console.dm" diff --git a/code/_helpers/lists.dm b/code/_helpers/lists.dm index 726cade4711..94edcc52092 100644 --- a/code/_helpers/lists.dm +++ b/code/_helpers/lists.dm @@ -144,6 +144,12 @@ return picked return null +//Returns the first element from the list and removes it from the list +/proc/popleft(list/L) + if(length(L)) + . = L[1] + L.Cut(1,2) + //Returns the next element in parameter list after first appearance of parameter element. If it is the last element of the list or not present in list, returns first element. /proc/next_in_list(element, list/L) for(var/i=1, i icon + var/list/choices_values = list() //choice_id -> choice + var/list/page_data = list() //list of choices per page + + + var/selected_choice + var/list/obj/screen/elements = list() + var/obj/screen/radial/center/close_button + var/client/current_user + var/atom/anchor + var/image/menu_holder + var/finished = FALSE + var/datum/callback/custom_check_callback + var/next_check = 0 + var/check_delay = DEFAULT_CHECK_DELAY + + var/radius = 32 + var/starting_angle = 0 + var/ending_angle = 360 + var/zone = 360 + var/min_angle = 45 //Defaults are setup for this value, if you want to make the menu more dense these will need changes. + var/max_elements + var/pages = 1 + var/current_page = 1 + + var/hudfix_method = TRUE //TRUE to change anchor to user, FALSE to shift by py_shift + var/py_shift = 0 + var/entry_animation = TRUE + +//If we swap to vis_contens inventory these will need a redo +/datum/radial_menu/proc/check_screen_border(mob/user) + var/atom/movable/AM = anchor + if(!istype(AM) || !AM.screen_loc) + return + if(AM in user.client.screen) + if(hudfix_method) + anchor = user + else + py_shift = 32 + restrict_to_dir(NORTH) //I was going to parse screen loc here but that's more effort than it's worth. + +//Sets defaults +//These assume 45 deg min_angle +/datum/radial_menu/proc/restrict_to_dir(dir) + switch(dir) + if(NORTH) + starting_angle = 270 + ending_angle = 135 + if(SOUTH) + starting_angle = 90 + ending_angle = 315 + if(EAST) + starting_angle = 0 + ending_angle = 225 + if(WEST) + starting_angle = 180 + ending_angle = 45 + +/datum/radial_menu/proc/setup_menu(use_tooltips) + if(ending_angle > starting_angle) + zone = ending_angle - starting_angle + else + zone = 360 - starting_angle + ending_angle + + max_elements = round(zone / min_angle) + var/paged = max_elements < choices.len + if(elements.len < max_elements) + var/elements_to_add = max_elements - elements.len + for(var/i in 1 to elements_to_add) //Create all elements + var/obj/screen/radial/slice/new_element = new /obj/screen/radial/slice + new_element.tooltips = use_tooltips + new_element.parent = src + elements += new_element + + var/page = 1 + page_data = list(null) + var/list/current = list() + var/list/choices_left = choices.Copy() + while(choices_left.len) + if(current.len == max_elements) + page_data[page] = current + page++ + page_data.len++ + current = list() + if(paged && current.len == max_elements - 1) + current += NEXT_PAGE_ID + continue + else + current += popleft(choices_left) + if(paged && current.len < max_elements) + current += NEXT_PAGE_ID + + page_data[page] = current + pages = page + current_page = 1 + update_screen_objects(anim = entry_animation) + +/datum/radial_menu/proc/update_screen_objects(anim = FALSE) + var/list/page_choices = page_data[current_page] + var/angle_per_element = round(zone / page_choices.len) + for(var/i in 1 to elements.len) + var/obj/screen/radial/E = elements[i] + var/angle = Wrap(starting_angle + (i - 1) * angle_per_element,0,360) + if(i > page_choices.len) + HideElement(E) + else + SetElement(E,page_choices[i],angle,anim = anim,anim_order = i) + +/datum/radial_menu/proc/HideElement(obj/screen/radial/slice/E) + E.overlays.Cut() + E.alpha = 0 + E.name = "None" + E.maptext = null + E.mouse_opacity = 0 + E.choice = null + E.next_page = FALSE + +/datum/radial_menu/proc/SetElement(obj/screen/radial/slice/E,choice_id,angle,anim,anim_order) + //Position + var/py = round(cos(angle) * radius) + py_shift + var/px = round(sin(angle) * radius) + if(anim) + var/timing = anim_order * 0.5 + var/matrix/starting = matrix() + starting.Scale(0.1,0.1) + E.transform = starting + var/matrix/TM = matrix() + animate(E,pixel_x = px,pixel_y = py, transform = TM, time = timing) + else + E.pixel_y = py + E.pixel_x = px + + //Visuals + E.alpha = 255 + E.mouse_opacity = 1 + E.overlays.Cut() + if(choice_id == NEXT_PAGE_ID) + E.name = "Next Page" + E.next_page = TRUE + E.overlays.Add("radial_next") + else + if(istext(choices_values[choice_id])) + E.name = choices_values[choice_id] + else + var/atom/movable/AM = choices_values[choice_id] //Movables only + E.name = AM.name + E.choice = choice_id + E.maptext = null + E.next_page = FALSE + if(choices_icons[choice_id]) + E.overlays.Add(choices_icons[choice_id]) + +/datum/radial_menu/New() + close_button = new + close_button.parent = src + +/datum/radial_menu/proc/Reset() + choices.Cut() + choices_icons.Cut() + choices_values.Cut() + current_page = 1 + +/datum/radial_menu/proc/element_chosen(choice_id,mob/user) + selected_choice = choices_values[choice_id] + +/datum/radial_menu/proc/get_next_id() + return "c_[choices.len]" + +/datum/radial_menu/proc/set_choices(list/new_choices, use_tooltips) + if(choices.len) + Reset() + for(var/E in new_choices) + var/id = get_next_id() + choices += id + choices_values[id] = E + if(new_choices[E]) + var/I = extract_image(new_choices[E]) + if(I) + choices_icons[id] = I + setup_menu(use_tooltips) + + +/datum/radial_menu/proc/extract_image(E) + var/mutable_appearance/MA = new /mutable_appearance(E) + if(MA) + MA.layer = HUD_LAYER + MA.appearance_flags |= RESET_TRANSFORM + return MA + + +/datum/radial_menu/proc/next_page() + if(pages > 1) + current_page = Wrap(current_page + 1,1,pages+1) + update_screen_objects() + +/datum/radial_menu/proc/show_to(mob/M) + if(current_user) + hide() + if(!M.client || !anchor) + return + current_user = M.client + //Blank + menu_holder = image(icon = 'icons/effects/effects.dmi', loc = anchor, icon_state = "nothing", layer = HUD_LAYER) + menu_holder.appearance_flags |= KEEP_APART + menu_holder.vis_contents += elements + close_button + current_user.images += menu_holder + +/datum/radial_menu/proc/hide() + if(current_user) + current_user.images -= menu_holder + +/datum/radial_menu/proc/wait(atom/user, atom/anchor, require_near = FALSE) + while (current_user && !finished && !selected_choice) + if(require_near && !in_range(anchor, user)) + return + if(custom_check_callback && next_check < world.time) + if(!custom_check_callback.Invoke()) + return + else + next_check = world.time + check_delay + stoplag(1) + +/datum/radial_menu/Destroy() + Reset() + hide() + QDEL_NULL(custom_check_callback) + return ..() + +/* + Presents radial menu to user anchored to anchor (or user if the anchor is currently in users screen) + 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, no_repeat_close = FALSE) + if(!user || !anchor || !length(choices)) + return + if(!uniqueid) + uniqueid = "defmenu_[SOFTREF(user)]_[SOFTREF(anchor)]" + + if(radial_menus[uniqueid]) + if(!no_repeat_close) + var/datum/radial_menu/menu = radial_menus[uniqueid] + menu.finished = TRUE + return + + var/datum/radial_menu/menu = new + radial_menus[uniqueid] = menu + if(radius) + menu.radius = radius + if(istype(custom_check)) + menu.custom_check_callback = custom_check + menu.anchor = anchor + menu.check_screen_border(user) //Do what's needed to make it look good near borders or on hud + menu.set_choices(choices, tooltips) + menu.show_to(user) + menu.wait(user, anchor, require_near) + var/answer = menu.selected_choice + qdel(menu) + radial_menus -= uniqueid + return answer + +#define RADIAL_INPUT(user, choices) show_radial_menu(user, user, choices) diff --git a/code/_onclick/hud/radial_persistent.dm b/code/_onclick/hud/radial_persistent.dm new file mode 100644 index 00000000000..3666cc8b7f3 --- /dev/null +++ b/code/_onclick/hud/radial_persistent.dm @@ -0,0 +1,71 @@ +/* + A derivative of radial menu which persists onscreen until closed and invokes a callback each time an element is clicked +*/ + +/obj/screen/radial/persistent/center + name = "Close Menu" + icon_state = "radial_center" + +/obj/screen/radial/persistent/center/Click(location, control, params) + if(usr.client == parent.current_user) + parent.element_chosen(null,usr) + +/obj/screen/radial/persistent/center/MouseEntered(location, control, params) + . = ..() + icon_state = "radial_center_focus" + +/obj/screen/radial/persistent/center/MouseExited(location, control, params) + . = ..() + icon_state = "radial_center" + +/datum/radial_menu/persistent + var/uniqueid + var/datum/callback/select_proc_callback + +/datum/radial_menu/persistent/New() + close_button = new /obj/screen/radial/persistent/center + close_button.parent = src + +/datum/radial_menu/persistent/element_chosen(choice_id,mob/user) + select_proc_callback.Invoke(choices_values[choice_id]) + +/datum/radial_menu/persistent/proc/change_choices(list/newchoices, tooltips) + if(!newchoices.len) + return + Reset() + set_choices(newchoices,tooltips) + +/datum/radial_menu/persistent/Destroy() + QDEL_NULL(select_proc_callback) + radial_menus -= uniqueid + Reset() + hide() + return ..() + +/* + Creates a persistent radial menu and shows it to the user, anchored to anchor (or user if the anchor is currently in users screen). + 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 + Select_proc is the proc to be called each time an element on the menu is clicked, and should accept the chosen element as its final argument + Clicking the center button will return a choice of null +*/ +/proc/show_radial_menu_persistent(mob/user, atom/anchor, list/choices, datum/callback/select_proc, uniqueid, radius, tooltips = FALSE) + if(!user || !anchor || !length(choices) || !select_proc) + return + if(!uniqueid) + uniqueid = "defmenu_\ref[user]_\ref[anchor]" + + if(radial_menus[uniqueid]) + return + + var/datum/radial_menu/persistent/menu = new + menu.uniqueid = uniqueid + radial_menus[uniqueid] = menu + if(radius) + menu.radius = radius + menu.select_proc_callback = select_proc + menu.anchor = anchor + menu.check_screen_border(user) //Do what's needed to make it look good near borders or on hud + menu.set_choices(choices, tooltips) + menu.show_to(user) + return menu diff --git a/code/game/objects/items/weapons/RFD.dm b/code/game/objects/items/weapons/RFD.dm index d5a9a9f0192..6a1b693269d 100644 --- a/code/game/objects/items/weapons/RFD.dm +++ b/code/game/objects/items/weapons/RFD.dm @@ -2,7 +2,7 @@ /obj/item/rfd name = "\improper Rapid-Fabrication-Device" desc = "A device used for rapid fabrication. The matter decompression matrix is untuned, rendering it useless." - icon = 'icons/obj/tools.dmi' + icon = 'icons/obj/rfd.dmi' icon_state = "rfd" item_state = "rfd" opacity = 0 @@ -17,24 +17,17 @@ origin_tech = list(TECH_ENGINEERING = 4, TECH_MATERIAL = 2) matter = list(DEFAULT_WALL_MATERIAL = 50000) drop_sound = 'sound/items/drop/gun.ogg' - var/datum/effect_system/sparks/spark_system var/stored_matter = 30 // Starts off full. var/working = 0 var/mode = 1 var/number_of_modes = 1 - var/modes = null + var/list/modes var/crafting = FALSE /obj/item/rfd/Initialize() . = ..() - src.spark_system = bind_spark(src, 5) update_icon() -/obj/item/rfd/Destroy() - qdel(spark_system) - spark_system = null - return ..() - /obj/item/rfd/attack() return 0 @@ -48,10 +41,12 @@ /obj/item/rfd/attack_self(mob/user) //Change the mode - if(++mode > number_of_modes) mode = 1 - to_chat(user, "Changed mode to '[modes[mode]]'") + if(++mode > number_of_modes) + mode = 1 + to_chat(user, SPAN_NOTICE("The mode selection dial is now at [modes[mode]].")) playsound(src.loc, 'sound/effects/pop.ogg', 50, 0) - if(prob(20)) src.spark_system.queue() + if(prob(20)) + spark(get_turf(loc), 3, alldirs) /obj/item/rfd/attackby(obj/item/W, mob/user) @@ -127,13 +122,37 @@ RFD Construction-Class /obj/item/rfd/construction name = "\improper Rapid-Fabrication-Device C-Class" desc = "A RFD, modified to construct walls and floors." - modes = list("Floor & Walls","Airlock","Deconstruct") - number_of_modes = 3 + var/list/radial_modes = list() var/canRwall = 0 var/disabled = 0 +/obj/item/rfd/construction/Initialize() + . = ..() + radial_modes = list( + "Floors and Walls" = image(icon = 'icons/mob/screen/radial.dmi', icon_state = "wallfloor"), + "Airlock" = image(icon = 'icons/mob/screen/radial.dmi', icon_state = "airlock"), + "Deconstruct" = image(icon = 'icons/mob/screen/radial.dmi', icon_state = "delete") + ) + +/obj/item/rfd/construction/attack_self(mob/user) + var/current_mode = show_radial_menu(user, src, radial_modes, radius = 42, require_near = TRUE, tooltips = TRUE) + switch(current_mode) + if("Floors and Walls") + mode = 1 + if("Airlock") + mode = 2 + if("Deconstruct") + mode = 3 + else + mode = 1 + to_chat(user, SPAN_NOTICE("You switch the selection dial to \"[current_mode]\".")) + playsound(src.loc, 'sound/effects/pop.ogg', 50, 0) + if(prob(20)) + spark(get_turf(src), 3, alldirs) + /obj/item/rfd/construction/afterattack(atom/A, mob/user, proximity) - if(!proximity) return + if(!proximity) + return if(disabled && !isrobot(user)) return 0 if(istype(get_area(A),/area/shuttle)||istype(get_area(A),/turf/space/transit)) @@ -141,7 +160,7 @@ RFD Construction-Class var/turf/t = get_turf(A) if (isNotStationLevel(t.z)) return 0 - return alter_turf(A,user,(mode == 3)) + return alter_turf(A, user, (mode == 3)) /obj/item/rfd/construction/proc/alter_turf(var/turf/T,var/mob/user,var/deconstruct) @@ -186,14 +205,14 @@ RFD Construction-Class return 0 if(!useResource(build_cost, user)) - user << "The \'Low Ammo\' light on the device blinks yellow." + to_chat(user, SPAN_WARNING("The \'Low Ammo\' light on the device blinks yellow.")) flick("[icon_state]-empty", src) return 0 - playsound(src.loc, 'sound/machines/click.ogg', 50, 1) + playsound(get_turf(src), 'sound/machines/hydraulic_long.ogg', 50, 1) working = 1 - to_chat(user, "[(deconstruct ? "Deconstructing" : "Building")] [build_type]...") + user.visible_message(SPAN_NOTICE("[user] holds \the [src] towards \the [T]."), SPAN_NOTICE("You start [deconstruct ? "deconstructing" : "constructing"] \a [build_type]...")) if(build_delay && !do_after(user, build_delay)) working = 0 @@ -210,7 +229,7 @@ RFD Construction-Class else qdel(T) - playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1) + playsound(get_turf(src), 'sound/effects/magnetclamp.ogg', 50, 1) return 1 /obj/item/rfd/construction/borg diff --git a/code/game/objects/items/weapons/tools.dm b/code/game/objects/items/weapons/tools.dm index 7cc7a01fe8c..21d55f490b7 100644 --- a/code/game/objects/items/weapons/tools.dm +++ b/code/game/objects/items/weapons/tools.dm @@ -688,7 +688,7 @@ /obj/item/powerdrill name = "impact wrench" - desc = " The screwdriver's big brother." + desc = "The screwdriver's big brother." icon = 'icons/obj/tools.dmi' item_icons = list( slot_l_hand_str = 'icons/mob/items/lefthand_tools.dmi', @@ -696,23 +696,23 @@ ) icon_state = "powerdrillyellow" item_state = "powerdrillyellow" - var/drillcolor = null force = 8 attack_verb = list("gored", "drilled", "screwed", "punctured") w_class = ITEMSIZE_SMALL toolspeed = 3 usesound = 'sound/items/drill_use.ogg' - + var/drillcolor = null + var/current_tool = 1 var/list/tools = list( "screwdriverbit", "wrenchbit" ) - var/current_tool = 1 + /obj/item/powerdrill/Initialize() . = ..() - switch(pick("red","blue","yellow","green")) + switch(pick("red", "blue", "yellow", "green")) if ("red") drillcolor = "red" if ("blue") diff --git a/code/modules/client/client defines.dm b/code/modules/client/client defines.dm index dfa4a0d8a81..05ec0b79cdb 100644 --- a/code/modules/client/client defines.dm +++ b/code/modules/client/client defines.dm @@ -19,7 +19,8 @@ ///////// //OTHER// ///////// - var/datum/preferences/prefs = null + var/datum/preferences/prefs + var/datum/tooltip/tooltips var/move_delay = 1 var/moving = null var/adminobs = null diff --git a/code/modules/client/client procs.dm b/code/modules/client/client procs.dm index cb0b54c39ce..f830c1e003e 100644 --- a/code/modules/client/client procs.dm +++ b/code/modules/client/client procs.dm @@ -373,10 +373,8 @@ prefs.client = src // Safety reasons here. prefs.last_ip = address //these are gonna be used for banning prefs.last_id = computer_id //these are gonna be used for banning -#if DM_VERSION >= 511 if (byond_version >= 511 && prefs.clientfps) fps = prefs.clientfps -#endif // DM_VERSION >= 511 if(SStheming) SStheming.apply_theme_from_perfs(src) @@ -425,6 +423,9 @@ del(src) return 0 + if(!tooltips) + tooltips = new /datum/tooltip(src) + if(holder) add_admin_verbs() @@ -575,6 +576,10 @@ if(prefs) prefs.ShowChoices(usr) +/client/proc/apply_fps(var/client_fps) + if(world.byond_version >= 511 && byond_version >= 511 && client_fps >= 0 && client_fps <= 1000) + vars["fps"] = prefs.clientfps + //I honestly can't find a good place for this atm. //If the webint interaction gets more features, I'll move it. - Skull132 /client/verb/view_linking_requests() diff --git a/code/modules/client/preference_setup/global/01_ui.dm b/code/modules/client/preference_setup/global/01_ui.dm index 68a0dc602ca..d80aa5e437a 100644 --- a/code/modules/client/preference_setup/global/01_ui.dm +++ b/code/modules/client/preference_setup/global/01_ui.dm @@ -30,7 +30,8 @@ "html_UI_style", "skin_theme", "ooccolor", - "clientfps" + "clientfps", + "tooltip_style" ), "args" = list("ckey") ) @@ -49,6 +50,7 @@ "skin_theme", "ooccolor", "clientfps", + "tooltip_style", "ckey" = 1 ) ) @@ -62,7 +64,8 @@ "html_UI_style" = pref.html_UI_style, "skin_theme" = pref.skin_theme, "ooccolor" = pref.ooccolor, - "clientfps" = pref.clientfps + "clientfps" = pref.clientfps, + "tooltip_style" = pref.tooltip_style ) /datum/category_item/player_setup_item/player_global/ui/sanitize_preferences() @@ -81,6 +84,7 @@ dat += "Custom UI (recommended for White UI):
" dat += "-Color: [pref.UI_style_color] [HTML_RECT(pref.UI_style_color)] - reset
" dat += "-Alpha(transparency): [pref.UI_style_alpha] - reset
" + dat += "Tooltip Style: [pref.tooltip_style]
" dat += "HTML UI Style: [pref.html_UI_style]
" dat += "Main UI Style: [pref.skin_theme]
" dat += "-FPS: [pref.clientfps] - reset
" @@ -132,16 +136,27 @@ pref.ooccolor = new_ooccolor return TOPIC_REFRESH - else if ("select_fps") - #if DM_VERSION >= 511 - var/desiredfps = input(user, "Choose your desired fps.\n(0 = synced with server tick rate (currently:[world.fps]))", "Character Preference") as null|num - pref.clientfps = sanitize_integer(desiredfps, 0, 1000, initial(pref.clientfps)) - user.client.fps = pref.clientfps - #else - to_user_chat("\nThis server does not currently support client side fps. You can set now for when it does.") - #endif // DM_VERSION >= 511 + else if(href_list["select_fps"]) + var/version_message + if (user.client && user.client.byond_version < 511) + version_message = "\nYou need to be using byond version 511 or later to take advantage of this feature, your version of [user.client.byond_version] is too low" + if (world.byond_version < 511) + version_message += "\nThis server does not currently support client side fps. You can set now for when it does." + var/new_fps = input(user, "Choose your desired fps.[version_message]\n(0 = synced with server tick rate (currently:[world.fps]))", "Global Preference") as num|null + if (isnum(new_fps) && CanUseTopic(user)) + pref.clientfps = Clamp(new_fps, 0, 1000) + var/mob/target_mob = preference_mob() + if(target_mob && target_mob.client) + target_mob.client.apply_fps(pref.clientfps) + return TOPIC_REFRESH + else if(href_list["select_tooltip_style"]) + var/tooltip_style_new = input(user, "Choose a new tooltip style.", "Global Preference", pref.tooltip_style) as null|anything in all_tooltip_styles + if(!tooltip_style_new || !CanUseTopic(user)) + return TOPIC_NOACTION + pref.tooltip_style = tooltip_style_new + return TOPIC_REFRESH else if(href_list["reset"]) switch(href_list["reset"]) diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index fe5ffc2d875..5996f9cc228 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -28,6 +28,8 @@ datum/preferences var/UI_style_alpha = 255 var/html_UI_style = "Nano" var/skin_theme = "Light" + //Style for popup tooltips + var/tooltip_style = "Midnight" var/motd_hash = "" //Hashes for the new server greeting window. var/memo_hash = "" diff --git a/code/modules/client/ui_style.dm b/code/modules/client/ui_style.dm index 6beb7842644..89172ff0705 100644 --- a/code/modules/client/ui_style.dm +++ b/code/modules/client/ui_style.dm @@ -1,6 +1,4 @@ - - -/var/all_ui_styles = list( +var/all_ui_styles = list( "Midnight" = 'icons/mob/screen/midnight.dmi', "Orange" = 'icons/mob/screen/orange.dmi', "old" = 'icons/mob/screen/old.dmi', @@ -8,12 +6,20 @@ "old-noborder" = 'icons/mob/screen/old-noborder.dmi' ) +var/all_tooltip_styles = list( + "Midnight", //Default for everyone is the first one, + "Plasmafire", + "Retro", + "Slimecore", + "Operative", + "Clockwork" + ) + /proc/ui_style2icon(ui_style) if(ui_style in all_ui_styles) return all_ui_styles[ui_style] return all_ui_styles["White"] - /client/verb/change_ui() set name = "Change UI" set category = "Preferences" diff --git a/code/modules/heavy_vehicle/mech_movement.dm b/code/modules/heavy_vehicle/mech_movement.dm index c8205c8b70a..4d9df07a706 100644 --- a/code/modules/heavy_vehicle/mech_movement.dm +++ b/code/modules/heavy_vehicle/mech_movement.dm @@ -68,7 +68,7 @@ if(exosuit.emp_damage >= EMP_MOVE_DISRUPT && prob(30)) failed = TRUE if(failed) - moving_dir = pick(GLOB.cardinal - exosuit.dir) + moving_dir = pick(cardinal - exosuit.dir) exosuit.get_cell().use(exosuit.legs.power_use * CELLRATE) if(exosuit.dir != moving_dir) diff --git a/code/modules/mob/living/silicon/robot/login.dm b/code/modules/mob/living/silicon/robot/login.dm index 005b7183307..5670dce50d2 100644 --- a/code/modules/mob/living/silicon/robot/login.dm +++ b/code/modules/mob/living/silicon/robot/login.dm @@ -8,4 +8,4 @@ // Forces synths to select an icon relevant to their module if(module && !icon_selected) - choose_icon(icon_selection_tries, module_sprites) \ No newline at end of file + choose_icon() \ No newline at end of file diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index e1b805a3d5d..ff59f00112b 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -12,7 +12,6 @@ var/icontype //Persistent icontype tracking allows for cleaner icon updates var/module_sprites[0] //Used to store the associations between sprite names and sprite index. var/icon_selected = 0 //If icon selection has been completed yet - var/icon_selection_tries = -1//Remaining attempts to select icon before a selection is forced var/spawn_sound = 'sound/voice/liveagain.ogg' var/pitch_toggle = TRUE var/datum/effect/effect/system/ion_trail_follow/ion_trail @@ -1072,39 +1071,37 @@ /mob/living/silicon/robot/proc/choose_icon() set category = "Robot Commands" set name = "Choose Icon" + set waitfor = 0 if(!length(module_sprites)) to_chat(src, SPAN_DANGER("Something is badly wrong with the sprite selection. Harass a coder.")) return + if(icon_selected) verbs -= /mob/living/silicon/robot/proc/choose_icon return - if(icon_selection_tries == -1) - icon_selection_tries = round(module_sprites.len*0.5) - - if(length(module_sprites) == 1 || !client) if(!(icontype in module_sprites)) icontype = module_sprites[1] if(!client) return else - icontype = input(src, "Select an icon! [icon_selection_tries ? "You have [icon_selection_tries] more chance\s." : "This is your last try."]", "Icon Selection") in module_sprites - playsound(get_turf(src), 'sound/effects/pop.ogg', 100, TRUE) - spark(get_turf(src), 5, alldirs) + var/list/options = list() + for(var/i in module_sprites) + var/image/radial_button = image(icon = src.icon, icon_state = module_sprites[i]) + radial_button.overlays.Add(image(icon = src.icon, icon_state = "eyes-[module_sprites[i]]-help")) + options[i] = radial_button + icontype = show_radial_menu(src, src, options, radius = 42, tooltips = TRUE) + + if(!icontype) + return + icon_state = module_sprites[icontype] updateicon() - - if(length(module_sprites) > 1 && icon_selection_tries >= 1 && client) - icon_selection_tries-- - var/choice = input(src, "Look at your icon - is this what you want?", "Icon Confirmation") in list("Yes", "No") - if(choice == "No") - choose_icon() - return - icon_selected = TRUE - icon_selection_tries = 0 + playsound(get_turf(src), 'sound/effects/pop.ogg', 10, TRUE) + spark(get_turf(src), 5, alldirs) verbs -= /mob/living/silicon/robot/proc/choose_icon to_chat(src, SPAN_NOTICE("Your icon has been set. You now require a module reset to change it.")) diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm index dd784ded060..4f473bbcbc2 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -65,7 +65,6 @@ var/global/list/robot_modules = list( R.set_module_sprites(sprites) R.icon_selected = FALSE - R.icon_selection_tries = -1 R.choose_icon() for(var/obj/item/I in modules) @@ -81,7 +80,6 @@ var/global/list/robot_modules = list( R.radio.recalculateChannels() R.set_module_sprites(list("Default" = "robot")) R.icon_selected = FALSE - R.icon_selection_tries = -1 R.choose_icon() /obj/item/robot_module/Destroy() diff --git a/code/modules/tooltip/tooltip.dm b/code/modules/tooltip/tooltip.dm new file mode 100644 index 00000000000..4b861173bdb --- /dev/null +++ b/code/modules/tooltip/tooltip.dm @@ -0,0 +1,115 @@ +/* +Tooltips v1.1 - 22/10/15 +Developed by Wire (#goonstation on irc.synirc.net) +- Added support for screen_loc pixel offsets. Should work. Maybe. +- Added init function to more efficiently send base vars +Configuration: +- Set control to the correct skin element (remember to actually place the skin element) +- Set file to the correct path for the .html file (remember to actually place the html file) +- Attach the datum to the user client on login, e.g. + +/client/New() + src.tooltips = new /datum/tooltip(src) + +Usage: +- Define mouse event procs on your (probably HUD) object and simply call the show and hide procs respectively: + +/obj/screen/hud + MouseEntered(location, control, params) + usr.client.tooltip.show(params, title = src.name, content = src.desc) + MouseExited() + usr.client.tooltip.hide() + +Customization: +- Theming can be done by passing the theme var to show() and using css in the html file to change the look +- For your convenience some pre-made themes are included +Notes: +- You may have noticed 90% of the work is done via javascript on the client. Gotta save those cycles man. +- This is entirely untested in any other codebase besides goonstation so I have no idea if it will port nicely. Good luck! + - After testing and discussion (Wire, Remie, MrPerson, AnturK) ToolTips are ok and work for /tg/station13 +*/ + +/datum/tooltip + var/client/owner + var/control = "mainwindow.tooltip" + var/showing = FALSE + var/queueHide = FALSE + var/init = FALSE + +/datum/tooltip/New(client/C) + if(C) + owner = C + show_browser(owner, file2text('code/modules/tooltip/tooltip.html'), "window=[control]") + ..() + +/datum/tooltip/proc/show(atom/movable/thing, params = null, title = null, content = null, theme = "default", special = "none") + if(!thing || !params || (!title && !content) || !owner || !isnum(world.icon_size)) + return FALSE + if(!init) + //Initialize some vars + init = TRUE + send_output(owner, list2params(list(world.icon_size, control)), "[control]:tooltip.init") + + showing = TRUE + + if(title && content) + title = "

[title]

" + content = "

[content]

" + else if(title && !content) + title = "

[title]

" + else if(!title && content) + content = "

[content]

" + + // Strip macros from item names + title = replacetext(title, "\proper", "") + title = replacetext(title, "\improper", "") + + //Make our dumb param object + if(params[1] != "i") //Byond Bug: http://www.byond.com/forum/?post=2352648 + params = "icon-x=16;icon-y=16;[params]" //Put in some placeholders + params = {"{ "cursor": "[params]", "screenLoc": "[thing.screen_loc]" }"} + + //Send stuff to the tooltip + var/view_size = getviewsize(owner.view) + send_output(owner, list2params(list(params, view_size[1] , view_size[2], "[title][content]", theme, special)), "[control]:tooltip.update") + + //ifa hide() was hit while we were showing, run hide() again to avoid stuck tooltips + showing = FALSE + if(queueHide) + hide() + + return TRUE + +/datum/tooltip/proc/hide() + if(queueHide) + addtimer(CALLBACK(src, .proc/do_hide), 1) + else + do_hide() + + queueHide = showing ? TRUE : FALSE + + return TRUE + +/datum/tooltip/proc/do_hide() + winshow(owner, control, FALSE) + +/* TG SPECIFIC CODE */ + +//Open a tooltip for user, at a location based on params +//Theme is a CSS class in tooltip.html, by default this wrapper chooses a CSS class based on the user's UI_style (Midnight, Plasmafire, Retro, etc) +//Includes sanity.checks +/proc/openToolTip(mob/user = null, atom/movable/tip_src = null, params = null, title = "", content = "", theme = "") + if(istype(user)) + if(user.client && user.client.tooltips) + if(!theme && user.client.prefs && user.client.prefs.tooltip_style) + theme = lowertext(user.client.prefs.tooltip_style) + if(!theme) + theme = "midnight" + user.client.tooltips.show(tip_src, params, title, content, theme) + +//Arbitrarily close a user's tooltip +//Includes sanity checks. +/proc/closeToolTip(mob/user) + if(istype(user)) + if(user.client && user.client.tooltips) + user.client.tooltips.hide() \ No newline at end of file diff --git a/code/modules/tooltip/tooltip.html b/code/modules/tooltip/tooltip.html new file mode 100644 index 00000000000..67fb8a77f10 --- /dev/null +++ b/code/modules/tooltip/tooltip.html @@ -0,0 +1,249 @@ + + + + Tooltip + + + + + +
+
+
+ + + + diff --git a/html/changelogs/mattatlas-radials.yml b/html/changelogs/mattatlas-radials.yml new file mode 100644 index 00000000000..0881e964580 --- /dev/null +++ b/html/changelogs/mattatlas-radials.yml @@ -0,0 +1,42 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# maptweak +# spellcheck (typo fixes) +# experiment +# balance +# admin +# backend +# security +# refactor +################################# + +# Your name. +author: MattAtlas + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. +# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. +changes: + - rscadd: "Ported radials and tooltips from Nebula and TG." + - rscdel: "Implemented radial menus for borg sprite selection and the RCD." diff --git a/icons/mob/screen/radial.dmi b/icons/mob/screen/radial.dmi new file mode 100644 index 0000000000000000000000000000000000000000..d2d032fbbb42c293979651b5ea67a4dd31bf0bd3 GIT binary patch literal 16655 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%0DZ$|XkQ1Hfs%~?wL>>|_hkTxKY3wN74;#<- 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 literal 0 HcmV?d00001 diff --git a/icons/obj/rfd.dmi b/icons/obj/rfd.dmi new file mode 100644 index 0000000000000000000000000000000000000000..7511b7c1e74431bea69125047fbf898aa1529cc3 GIT binary patch literal 2449 zcmZuwc|4SB8-5*~BO_W+$ugldcEcy;WEzbvOB$lZ8Z*Wklcg-fB+HbqOleB8Op_2o zR3r>-wuFi#A!R$9rQ-2;H8r*Pcq0Nq9YeGa;aj0OB(h;HKw)$kFJNDb!QxlV+)1B;=5kk={(s-Uq={jVcT}b z{C;#=tPR>F)(mP45Izx9s~j*k%*F=-czi%8g}hX_r=5Lzc!+qb7WsjFii8VIe-*Nq z*3}B(^W257Wt`*7OBWP28>!(fJ1*SJ!aB+Q*9v}3Jdje5O`}vzN$pDOS8)lj%(|ZA zpH+^L(8ti>uC9K*dfIo#jytV4zJZ|^5l*OjWftUx%?)>)F<$A1F*l9+!u6wiL zT-NuDovZ)jdWpHzGi|Qoif5-0SA42i3wb{IOBB3RVI{u=_XbUKjU;qVx{m5xp_1g{7%ib)21}zi=P15i4HjIR%CS89YW~NF z8H~Vbs+I&322g3a{ShS%nF8;WA(We*w7@Bo=IxO)5dN_7TOFxFX*K`#*%^HbKVMZy zSe)kf)*?)n?HMbaHy^>(AnYXgYjiYUm$r~eTDjzpOWb0cExqasSUS-94)qQBk2feWmNsX037PP~}kcIAX zGDeXX@=F2WoFanW@+}#8Z2*f;*A&7c8RU0ZSRCsWoC!_oOac|8&o_bEeK#`&4gPcE zMke&~oWA!IqE}$Ww>dBa)y@1vc<*&D4^{nnO22jqN=+i&?GqyAD5Ggp~+xb5#7!22>wt zS1Z4k`1R@jO_}nLYE)*JN1w#R(%91m$;Uqe4j4%P2-0wWpYx0}Hg~xcDogx39QhF@ z{NL~+P3qUhcJ2-@MS{gJ>2Fqx#3TNayoxAXRUhW6)FJa%6@tMcY%mo8F$);M)fuyJ zn6UM%3X)3twvPe@JA&!&zmyY1Db(50;1Z9j2giTTfm3eMQOAoQ|-;P`Yx!XCOu$PjbztMq$JgUDGHaKm}PZMRSyh?axld{FPLTao-OTmtzuM{ zcr%_+U9NyWof6~)A7rTb4(UG+8b1Jj+NACv^{3d2V%7EPRFrzE>-mULz+%7B$##y! z_IUviF?5=aNeJwvbXktjaSPW2gNUsnfnJW+8~14{so(@t?o)D zMaFHeK@(Y@b{6IR0*RuoA+#FHy01lbdmEMf}}f z$N36T!0Eh^LY)yPVodq@bXTMVi1~z7$n0EIJitX1&5cU`L-E|pL~pD_g0$G`4#=|c zy4m2VrV6-tV=Ax){k8_dzVu=0)4i`5R($RIx$`@B<4Nmg*77>8nh3JBaMW literal 0 HcmV?d00001 diff --git a/icons/obj/tools.dmi b/icons/obj/tools.dmi index d92b24718093069dda6743c27cf28f0b89cf3fc7..8e9f572d64177c76793c326c6092204c6c932740 100644 GIT binary patch literal 14155 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

t%OsEoxn#Z%@{M+1t+x6qf5y+*)4nCx&`B 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 GxBn08@*!{l literal 25067 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