diff --git a/.github/workflows/generate_documentation.yml b/.github/workflows/generate_documentation.yml index 3ca7c00a8c..23b95711ba 100644 --- a/.github/workflows/generate_documentation.yml +++ b/.github/workflows/generate_documentation.yml @@ -1,12 +1,17 @@ name: Generate documentation on: - push: - branches: - - master + schedule: + - cron: "44 */6 * * *" + workflow_dispatch: +permissions: + contents: read jobs: generate_documentation: - if: "!contains(github.event.head_commit.message, '[ci skip]')" - runs-on: ubuntu-20.04 + permissions: + contents: write # for JamesIves/github-pages-deploy-action to push changes in repo + if: ( !contains(github.event.head_commit.message, '[ci skip]') ) + runs-on: ubuntu-22.04 + concurrency: gen-docs steps: - uses: actions/checkout@v4 - name: Setup cache @@ -22,10 +27,9 @@ jobs: touch dmdoc/.nojekyll echo https://splurt-station.github.io/S.P.L.U.R.T-Station-13/ > dmdoc/CNAME - name: Deploy - uses: JamesIves/github-pages-deploy-action@3.7.1 + uses: JamesIves/github-pages-deploy-action@v4.7.3 with: - BRANCH: gh-pages - CLEAN: true - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - SINGLE_COMMIT: true - FOLDER: dmdoc + branch: gh-pages + clean: true + single-commit: true + folder: dmdoc diff --git a/code/__DEFINES/color/colors.dm b/code/__DEFINES/color/colors.dm index cc11a1aeaa..1b819a72c3 100644 --- a/code/__DEFINES/color/colors.dm +++ b/code/__DEFINES/color/colors.dm @@ -30,6 +30,7 @@ #define COLOR_YELLOW "#FFFF00" #define COLOR_VIVID_YELLOW "#FBFF23" #define COLOR_VERY_SOFT_YELLOW "#FAE48E" +#define COLOR_GOLD "#FFD700" #define COLOR_OLIVE "#808000" #define COLOR_VIBRANT_LIME "#00FF00" @@ -126,6 +127,7 @@ #define COLOR_THEME_TRASENKNOX "#3ce375" #define COLOR_THEME_DETECTIVE "#c7b08b" #define COLOR_THEME_LITEWEB "#226611" +#define COLOR_THEME_CORRU "#00FFFF" ///Colors for eigenstates #define COLOR_PERIWINKLEE "#9999FF" diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm index 28e0d9d159..84b845c4ff 100644 --- a/code/__DEFINES/dcs/signals.dm +++ b/code/__DEFINES/dcs/signals.dm @@ -217,6 +217,8 @@ #define COMSIG_TURF_MULTIZ_DEL "turf_multiz_del" ///from base of turf/multiz_turf_new: (turf/source, direction) #define COMSIG_TURF_MULTIZ_NEW "turf_multiz_new" +/// from base of turf/proc/afterShuttleMove: (turf/new_turf) +#define COMSIG_TURF_AFTER_SHUTTLE_MOVE "turf_after_shuttle_move" // /atom/movable signals #define COMSIG_MOVABLE_PRE_MOVE "movable_pre_move" ///from base of atom/movable/Moved(): (/atom) diff --git a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_mouse.dm b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_mouse.dm index 2b0c9c297e..381367fd92 100644 --- a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_mouse.dm +++ b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_mouse.dm @@ -23,3 +23,5 @@ #define COMPONENT_NO_MOUSEDROP (1<<0) ///from base of atom/MouseDrop_T: (/atom/from, /mob/user) #define COMSIG_MOUSEDROPPED_ONTO "mousedropped_onto" //from base of atom/MouseDrop_T: (/atom/from, /mob/user) +/// From /atom/movable/screen/click(): (atom/target, atom/location, control, params, mob/user) +#define COMSIG_SCREEN_ELEMENT_CLICK "screen_element_click" diff --git a/code/__DEFINES/dcs/signals/signals_global.dm b/code/__DEFINES/dcs/signals/signals_global.dm index 3e0e1d2296..eeb71f90f1 100644 --- a/code/__DEFINES/dcs/signals/signals_global.dm +++ b/code/__DEFINES/dcs/signals/signals_global.dm @@ -1,2 +1,5 @@ /// a person somewhere has thrown something : (mob/living/carbon/carbon_thrower, target) #define COMSIG_GLOB_CARBON_THROW_THING "!throw_thing" + +/// Global signal sent before we decide what job everyone has +#define COMSIG_GLOB_PRE_JOBS_ASSIGNED "!pre_roles_assigned" diff --git a/code/__DEFINES/dcs/signals/signals_hud.dm b/code/__DEFINES/dcs/signals/signals_hud.dm index c771204773..63a55f95ca 100644 --- a/code/__DEFINES/dcs/signals/signals_hud.dm +++ b/code/__DEFINES/dcs/signals/signals_hud.dm @@ -2,3 +2,5 @@ #define COMSIG_HUD_LOBBY_COLLAPSED "hud_lobby_collapsed" /// Sent from /atom/movable/screen/lobby/button/collapse/proc/expand_buttons() : () #define COMSIG_HUD_LOBBY_EXPANDED "hud_lobby_expanded" +/// Sent from /atom/movable/screen/lobby/button/ready/Click() : () +#define COMSIG_HUD_PLAYER_READY_TOGGLE "hud_player_ready_toggle" diff --git a/code/__DEFINES/hud.dm b/code/__DEFINES/hud.dm index 1f6da7526a..215ff77623 100644 --- a/code/__DEFINES/hud.dm +++ b/code/__DEFINES/hud.dm @@ -94,11 +94,12 @@ #define ui_palette_scroll_offset(north_offset) ("WEST+1:8,NORTH-[6+north_offset]:28") //Middle right (status indicators) -#define ui_healthdoll "EAST-1:28,CENTER-2:13" -#define ui_health "EAST-1:28,CENTER-1:15" -#define ui_internal "EAST-1:28,CENTER+1:19"//CIT CHANGE - moves internal icon up a little bit to accommodate for the stamina meter -#define ui_mood "EAST-1:28,CENTER-3:10" -// #define ui_spacesuit "EAST-1:28,CENTER-4:10" +#define ui_healthdoll "EAST-1:28,CENTER-2:17" +#define ui_health "EAST-1:28,CENTER-1:19" +#define ui_internal "EAST-1:28,CENTER+1:21" // RIP, although nobody will remember this, unsmart coders have used this for other stuff. DO NOT REMOVE UNLESS RENAMING OR REPLACING. +#define ui_mood "EAST-1:28,CENTER:21" +#define ui_stamina "EAST-1:28,CENTER-3:14" +// #define ui_spacesuit "EAST-1:28,CENTER-4:14" //Pop-up inventory #define ui_shoes "WEST+1:8,SOUTH:5" @@ -208,7 +209,6 @@ #define ui_ghost_spawners "SOUTH: 6, CENTER+1:24" // LEGACY. SAME LOC AS PAI //UI position overrides for 1:1 screen layout. (default is 7:5) -#define ui_stamina "EAST-1:28,CENTER:17" // replacing internals button #define ui_overridden_resist "EAST-3:24,SOUTH+1:7" #define ui_clickdelay "CENTER,SOUTH+1:-31" #define ui_resistdelay "EAST-3:24,SOUTH+1:4" @@ -231,6 +231,8 @@ #define SCRN_OBJ_IN_LIST "list" /// In the collapseable palette #define SCRN_OBJ_IN_PALETTE "palette" +///Inserted first in the list +#define SCRN_OBJ_INSERT_FIRST "first" /// The filter name for the hover outline #define HOVER_OUTLINE_FILTER "hover_outline" diff --git a/code/__DEFINES/language.dm b/code/__DEFINES/language.dm index 5973185620..91f9f8572b 100644 --- a/code/__DEFINES/language.dm +++ b/code/__DEFINES/language.dm @@ -4,10 +4,21 @@ #define LANGUAGE_HIDE_ICON_IF_NOT_UNDERSTOOD 8 // LANGUAGE SOURCE DEFINES -#define LANGUAGE_ALL "all" // For use in full removal only. -#define LANGUAGE_ATOM "atom" -#define LANGUAGE_MIND "mind" +/// For use in full removal only. +#define LANGUAGE_ALL "all" +// Generic language sources. +/// Language is linked to the movable directly. +#define LANGUAGE_ATOM "atom" +/// Language is linked to the mob's mind. +/// If a mind transfer happens, language follows. +#define LANGUAGE_MIND "mind" +/// Language is linked to the mob's species. +/// If a species change happens, language goes away. +/// If applied to a non-human (no species) atom, this is effectively the same as [LANGUAGE_ATOM]. +#define LANGUAGE_SPECIES "species" +// More specific language sources. +// Only ever goes away when dismissed directly. #define LANGUAGE_ABSORB "absorb" #define LANGUAGE_APHASIA "aphasia" #define LANGUAGE_BLOODSUCKER "bloodsucker" @@ -24,8 +35,10 @@ #define LANGUAGE_STONER "stoner" #define LANGUAGE_VASSAL "vassal" #define LANGUAGE_VOICECHANGE "voicechange" -//#define LANGUAGE_MULTILINGUAL "multilingual" +#define LANGUAGE_MULTILINGUAL "multilingual" -//SKYRAT LANGUAGES -#define LANGUAGE_ADDITIONAL "additional" -#define LANGUAGE_NINJA "ninja" +// Language flags. Used in granting and removing languages. +/// This language can be spoken. +#define SPOKEN_LANGUAGE (1<<0) +/// This language can be understood. +#define UNDERSTOOD_LANGUAGE (1<<1) diff --git a/code/__DEFINES/tgui.dm b/code/__DEFINES/tgui.dm index 069e771861..744700a4f2 100644 --- a/code/__DEFINES/tgui.dm +++ b/code/__DEFINES/tgui.dm @@ -30,8 +30,9 @@ #define TGUI_WINDOW_INDEX(window_id) text2num(copytext(window_id, 13)) /// Creates a message packet for sending via output() +// This is {"type":type,"payload":payload}, but pre-encoded. This is much faster +// than doing it the normal way. +// To ensure this is correct, this is unit tested in tgui_create_message. #define TGUI_CREATE_MESSAGE(type, payload) ( \ - url_encode(json_encode(list( \ - "type" = type, \ - "payload" = payload, \ - )))) + "%7b%22type%22%3a%22[type]%22%2c%22payload%22%3a[url_encode(json_encode(payload))]%7d" \ +) diff --git a/code/__HELPERS/_lists.dm b/code/__HELPERS/_lists.dm index 3b092fd3b7..a8373205ca 100644 --- a/code/__HELPERS/_lists.dm +++ b/code/__HELPERS/_lists.dm @@ -743,6 +743,13 @@ else L1[key] = other_value +/// Turns an associative list into a flat list of keys +/proc/assoc_to_keys(list/input) + var/list/keys = list() + for(var/key in input) + UNTYPED_LIST_ADD(keys, key) + return keys + /proc/assoc_list_strip_value(list/input) var/list/ret = list() for(var/key in input) diff --git a/code/__HELPERS/admin.dm b/code/__HELPERS/admin.dm new file mode 100644 index 0000000000..63df20ce46 --- /dev/null +++ b/code/__HELPERS/admin.dm @@ -0,0 +1,9 @@ +/// Returns if the given client is an admin, REGARDLESS of if they're deadminned or not. +/proc/is_admin(client/client) + return !isnull(GLOB.admin_datums[client.ckey]) || !isnull(GLOB.deadmins[client.ckey]) + +/// Sends a message in the event that someone attempts to elevate their permissions through invoking a certain proc. +/proc/alert_to_permissions_elevation_attempt(mob/user) + var/message = " has tried to elevate permissions!" + message_admins(key_name_admin(user) + message) + log_admin(key_name(user) + message) diff --git a/code/__HELPERS/type2type.dm b/code/__HELPERS/type2type.dm index 5df7b9f875..ac8046a68b 100644 --- a/code/__HELPERS/type2type.dm +++ b/code/__HELPERS/type2type.dm @@ -707,7 +707,9 @@ return 'modular_citadel/icons/ui/screen_trasenknox.dmi' if('icons/mob/screen_detective.dmi') return 'modular_citadel/icons/ui/screen_detective.dmi' - if('modular_sand/icons/mob/screen_liteweb.dmi') - return 'modular_sand/icons/mob/screen_liteweb.dmi' + if('modular_sand/icons/hud/screen_liteweb/base.dmi') + return 'modular_sand/icons/hud/screen_liteweb/base.dmi' + if('modular_sand/icons/hud/screen_corru/base.dmi') + return 'modular_sand/icons/hud/screen_corru/base.dmi' else return 'modular_citadel/icons/ui/screen_midnight.dmi' diff --git a/code/__SANDCODE/DEFINES/language.dm b/code/__SANDCODE/DEFINES/language.dm index 56d6e245ad..d36090448e 100644 --- a/code/__SANDCODE/DEFINES/language.dm +++ b/code/__SANDCODE/DEFINES/language.dm @@ -4,3 +4,5 @@ * "i want fancy merp language" */ #define LANGUAGE_SERGAL "Sagaru" + +#define LANGUAGE_NINJA "ninja" diff --git a/code/__SANDCODE/DEFINES/lewd.dm b/code/__SANDCODE/DEFINES/lewd.dm index db32e3e5d2..ebc7ad5b0d 100644 --- a/code/__SANDCODE/DEFINES/lewd.dm +++ b/code/__SANDCODE/DEFINES/lewd.dm @@ -34,6 +34,17 @@ GLOBAL_LIST_INIT(lewd_kiss_sounds, list( 'modular_sand/sound/interactions/kiss4.ogg', 'modular_sand/sound/interactions/kiss5.ogg' )) +GLOBAL_LIST_INIT(interaction_speeds, list( + 4 SECONDS, + 2 SECONDS, + 1 SECONDS, + 0.8 SECONDS, + 0.5 SECONDS, // lowest value must always be over or equal to the subsystem wait/cooldown for interaction +)) + +#define INTERACTION_NORMAL 0 +#define INTERACTION_LEWD 1 +#define INTERACTION_EXTREME 2 #define CUM_TARGET_MOUTH "mouth" #define CUM_TARGET_THROAT "throat" @@ -90,8 +101,21 @@ GLOBAL_LIST_INIT(lewd_kiss_sounds, list( #define INTERACTION_FLAG_USER_NOT_TIRED (1<<5) /// Copy-paste prevention for additional details +/// Fills containers #define INTERACTION_FILLS_CONTAINERS list( \ "info" = "You can fill a container if you have it in your active hand or are pulling it", \ "icon" = "flask", \ - "color" = "transparent" \ + "color" = "white" \ ) +/// Can drink from +#define INTERACTION_MAY_CONTAIN_DRINK list( \ + "info" = "May contain reagents", \ + "icon" = "cow", \ + "color" = "white" \ +) +/// Causes pregnancies +#define INTERACTION_MAY_CAUSE_PREGNANCY list( \ + "info" = "May cause pregnancies", \ + "icon" = "person-pregnant", \ + "color" = "white" \ +) diff --git a/code/_onclick/hud/action_button.dm b/code/_onclick/hud/action_button.dm index f5826579c8..20180be547 100644 --- a/code/_onclick/hud/action_button.dm +++ b/code/_onclick/hud/action_button.dm @@ -5,10 +5,11 @@ var/datum/hud/our_hud var/actiontooltipstyle = "" screen_loc = null + mouse_over_pointer = MOUSE_HAND_POINTER var/button_icon_state var/appearance_cache - + var/mutable_appearance/button_overlay /// Where we are currently placed on the hud. SCRN_OBJ_DEFAULT asks the linked action what it thinks var/location = SCRN_OBJ_DEFAULT /// A unique bitflag, combined with the name of our linked action this lets us persistently remember any user changes to our position @@ -199,6 +200,7 @@ icon = 'icons/hud/64x16_actions.dmi' icon_state = "screen_gen_palette" screen_loc = ui_action_palette + mouse_over_pointer = MOUSE_HAND_POINTER var/datum/hud/our_hud var/expanded = FALSE /// Id of any currently running timers that set our color matrix @@ -211,7 +213,7 @@ our_hud = null return ..() -/atom/movable/screen/button_palette/Initialize(mapload) +/atom/movable/screen/button_palette/Initialize(mapload, datum/hud/hud_owner) . = ..() update_appearance() @@ -233,11 +235,12 @@ var/list/settings = our_hud.get_action_buttons_icons() var/ui_icon = "[settings["bg_icon"]]" - var/list/ui_segments = splittext(ui_icon, ".") - var/list/ui_paths = splittext(ui_segments[1], "/") - var/ui_name = ui_paths[length(ui_paths)] + var/static/regex/R + if(!R) + R = new(@"(screen_.+?)[\./]") + R.Find(ui_icon) - icon_state = "[ui_name]_palette" + icon_state = "[R.group[1]]_palette" /atom/movable/screen/button_palette/MouseEntered(location, control, params) . = ..() @@ -324,6 +327,7 @@ GLOBAL_LIST_INIT(palette_removed_matrix, list(1.4,0,0,0, 0.7,0.4,0,0, 0.4,0,0.6, /atom/movable/screen/palette_scroll icon = 'icons/mob/screen_gen.dmi' screen_loc = ui_palette_scroll + mouse_over_pointer = MOUSE_HAND_POINTER /// How should we move the palette's actions? /// Positive scrolls down the list, negative scrolls back var/scroll_direction = 0 diff --git a/code/_onclick/hud/ai.dm b/code/_onclick/hud/ai.dm index 419de492ef..b264de2cd9 100644 --- a/code/_onclick/hud/ai.dm +++ b/code/_onclick/hud/ai.dm @@ -1,5 +1,6 @@ /atom/movable/screen/ai icon = 'icons/mob/screen_ai.dmi' + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/ai/Click() if(isobserver(usr) || usr.incapacitated()) @@ -193,109 +194,91 @@ var/atom/movable/screen/using // Language menu - using = new /atom/movable/screen/language_menu + using = new /atom/movable/screen/language_menu(null, src) using.screen_loc = ui_ai_language_menu - using.hud = src static_inventory += using //AI core - using = new /atom/movable/screen/ai/aicore() + using = new /atom/movable/screen/ai/aicore(null, src) using.screen_loc = ui_ai_core - using.hud = src static_inventory += using //Camera list - using = new /atom/movable/screen/ai/camera_list() + using = new /atom/movable/screen/ai/camera_list(null, src) using.screen_loc = ui_ai_camera_list - using.hud = src static_inventory += using //Track - using = new /atom/movable/screen/ai/camera_track() + using = new /atom/movable/screen/ai/camera_track(null, src) using.screen_loc = ui_ai_track_with_camera - using.hud = src static_inventory += using //Camera light - using = new /atom/movable/screen/ai/camera_light() + using = new /atom/movable/screen/ai/camera_light(null, src) using.screen_loc = ui_ai_camera_light - using.hud = src static_inventory += using //Crew Monitoring - using = new /atom/movable/screen/ai/crew_monitor() + using = new /atom/movable/screen/ai/crew_monitor(null, src) using.screen_loc = ui_ai_crew_monitor - using.hud = src static_inventory += using //Crew Manifest - using = new /atom/movable/screen/ai/crew_manifest() + using = new /atom/movable/screen/ai/crew_manifest(null, src) using.screen_loc = ui_ai_crew_manifest - using.hud = src static_inventory += using //Alerts - using = new /atom/movable/screen/ai/alerts() + using = new /atom/movable/screen/ai/alerts(null, src) using.screen_loc = ui_ai_alerts - using.hud = src static_inventory += using //Announcement - using = new /atom/movable/screen/ai/announcement() + using = new /atom/movable/screen/ai/announcement(null, src) using.screen_loc = ui_ai_announcement - using.hud = src static_inventory += using //Shuttle - using = new /atom/movable/screen/ai/call_shuttle() + using = new /atom/movable/screen/ai/call_shuttle(null, src) using.screen_loc = ui_ai_shuttle - using.hud = src static_inventory += using //Laws - using = new /atom/movable/screen/ai/state_laws() + using = new /atom/movable/screen/ai/state_laws(null, src) using.screen_loc = ui_ai_state_laws - using.hud = src static_inventory += using //PDA message - using = new /atom/movable/screen/ai/pda_msg_send() + using = new /atom/movable/screen/ai/pda_msg_send(null, src) using.screen_loc = ui_ai_pda_send - using.hud = src static_inventory += using //PDA log - using = new /atom/movable/screen/ai/pda_msg_show() + using = new /atom/movable/screen/ai/pda_msg_show(null, src) using.screen_loc = ui_ai_pda_log - using.hud = src static_inventory += using //Take image - using = new /atom/movable/screen/ai/image_take() + using = new /atom/movable/screen/ai/image_take(null, src) using.screen_loc = ui_ai_take_picture - using.hud = src static_inventory += using //View images - using = new /atom/movable/screen/ai/image_view() + using = new /atom/movable/screen/ai/image_view(null, src) using.screen_loc = ui_ai_view_images - using.hud = src static_inventory += using //Medical/Security sensors - using = new /atom/movable/screen/ai/sensors() + using = new /atom/movable/screen/ai/sensors(null, src) using.screen_loc = ui_ai_sensor - using.hud = src static_inventory += using //Multicamera mode - using = new /atom/movable/screen/ai/multicam() + using = new /atom/movable/screen/ai/multicam(null, src) using.screen_loc = ui_ai_multicam - using.hud = src static_inventory += using //Add multicamera camera - using = new /atom/movable/screen/ai/add_multicam() + using = new /atom/movable/screen/ai/add_multicam(null, src) using.screen_loc = ui_ai_add_multicam - using.hud = src static_inventory += using diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm index 6a1ed142a2..20d7b18c46 100644 --- a/code/_onclick/hud/alert.dm +++ b/code/_onclick/hud/alert.dm @@ -91,6 +91,8 @@ name = "Alert" desc = "Something seems to have gone wrong with this alert, so report this bug please" mouse_opacity = MOUSE_OPACITY_ICON + /// do we glow to represent we do stuff when clicked + var/clickable_glow = FALSE var/timeout = 0 //If set to a number, this alert will clear itself after that many deciseconds var/severity = 0 var/alerttooltipstyle = "" @@ -100,6 +102,12 @@ /// Boolean. If TRUE, the Click() proc will attempt to Click() on the master first if there is a master. var/click_master = TRUE +/atom/movable/screen/alert/Initialize(mapload, datum/hud/hud_owner) + . = ..() + if(clickable_glow) + add_filter("clickglow", 2, outline_filter(color = COLOR_GOLD, size = 1)) + mouse_over_pointer = MOUSE_HAND_POINTER + /atom/movable/screen/alert/MouseEntered(location,control,params) if(!QDELETED(src)) openToolTip(usr,src,params,title = name,content = desc,theme = alerttooltipstyle) @@ -186,7 +194,7 @@ /atom/movable/screen/alert/thirsty name = "Thirsty" desc = "Some water would be good right about now." - icon = 'modular_sand/icons/mob/screen_alert.dmi' + icon = 'modular_sand/icons/hud/screen_alert.dmi' icon_state = "thirsty" /atom/movable/screen/alert/starving @@ -197,7 +205,7 @@ /atom/movable/screen/alert/dehydrated name = "Dehydrated" desc = "You're severely dehydrated." - icon = 'modular_sand/icons/mob/screen_alert.dmi' + icon = 'modular_sand/icons/hud/screen_alert.dmi' icon_state = "dehydrated" */ @@ -260,13 +268,14 @@ or something covering your eyes." name = "Mind Control" desc = "Your mind has been hijacked! Click to view the mind control command." icon_state = "mind_control" + clickable_glow = TRUE var/command /atom/movable/screen/alert/mind_control/Click() - var/mob/living/L = usr - if(L != owner) + . = ..() + if(!.) return - to_chat(L, "[command]") + to_chat(usr, "[command]") /atom/movable/screen/alert/hypnosis name = "Hypnosis" @@ -284,11 +293,16 @@ or something covering your eyes." desc = "Something got lodged into your flesh and is causing major bleeding. It might fall out with time, but surgery is the safest way. \ If you're feeling frisky, examine yourself and click the underlined item to pull the object out." icon_state = "embeddedobject" + clickable_glow = TRUE /atom/movable/screen/alert/embeddedobject/Click() - if(isliving(usr) && usr == owner) - var/mob/living/carbon/M = usr - return M.help_shake_act(M) + . = ..() + if(!.) + return + if(!isliving(usr)) + return + var/mob/living/carbon/M = usr + return M.help_shake_act(M) /atom/movable/screen/alert/weightless name = "Weightless" @@ -312,10 +326,14 @@ or shoot a gun to move around via Newton's 3rd Law of Motion." name = "On Fire" desc = "You're on fire. Stop, drop and roll to put the fire out or move to a vacuum area." icon_state = "fire" + clickable_glow = TRUE /atom/movable/screen/alert/fire/Click() + . = ..() + if(!.) + return var/mob/living/L = usr - if(!istype(L) || !L.can_resist() || L != owner) + if(!istype(L) || !L.can_resist()) return L.MarkResistTime() if(CHECK_MOBILITY(L, MOBILITY_MOVE)) @@ -323,8 +341,29 @@ or shoot a gun to move around via Newton's 3rd Law of Motion." /atom/movable/screen/alert/give // information set when the give alert is made icon_state = "default" + clickable_glow = TRUE var/mob/living/carbon/offerer var/obj/item/receiving + /// Additional text displayed in the description of the alert. + var/additional_desc_text = "Click this alert to take it, or shift click it to examine it." + /// Text to override what appears in screentips for the alert + var/screentip_override_text + /// Whether the offered item can be examined by shift-clicking the alert + var/examinable = TRUE + +/atom/movable/screen/alert/give/Initialize(mapload, datum/hud/hud_owner) + . = ..() + register_context() + +/atom/movable/screen/alert/give/Destroy() + offerer = null + receiving = null + return ..() + +/atom/movable/screen/alert/give/add_context(atom/source, list/context, obj/item/held_item, mob/user) + LAZYSET(context[SCREENTIP_CONTEXT_LMB], INTENT_ANY, screentip_override_text || "Take [receiving.name]") + LAZYSET(context[SCREENTIP_CONTEXT_SHIFT_LMB], INTENT_ANY, "Examine") + return CONTEXTUAL_SCREENTIP_SET /** * Handles assigning most of the variables for the alert that pops up when an item is offered @@ -354,6 +393,16 @@ or shoot a gun to move around via Newton's 3rd Law of Motion." CRASH("User for [src] is of type \[[usr.type]\]. This should never happen.") handle_transfer() +/atom/movable/screen/alert/give/examine(mob/user) + if(!examinable) + return ..() + + return list( + span_boldnotice(name), + span_info("[offerer] is offering you the following item (click the alert to take it!):"), + "
[jointext(receiving.examine(user), "\n")]", + ) + /// An overrideable proc used simply to hand over the item when claimed, this is a proc so that high-fives can override them since nothing is actually transferred /atom/movable/screen/alert/give/proc/handle_transfer() var/mob/living/carbon/taker = owner @@ -367,6 +416,11 @@ or shoot a gun to move around via Newton's 3rd Law of Motion." to_chat(owner, span_warning("You moved out of range of [offerer]!")) owner.clear_alert("[offerer]") +/atom/movable/screen/alert/give/highfive + additional_desc_text = "Click this alert to slap it." + screentip_override_text = "High Five" + examinable = FALSE + /atom/movable/screen/alert/give/highfive/setup(mob/living/carbon/taker, mob/living/carbon/offerer, obj/item/receiving) . = ..() name = "[offerer] is offering a high-five!" @@ -417,6 +471,9 @@ or shoot a gun to move around via Newton's 3rd Law of Motion." /// Families handshakes /atom/movable/screen/alert/give/secret_handshake icon_state = "default" + additional_desc_text = "Click this alert to accept." + screentip_override_text = "Handshake" + examinable = FALSE /atom/movable/screen/alert/give/secret_handshake/setup(mob/living/carbon/taker, mob/living/carbon/offerer, obj/item/receiving) name = "[offerer] is offering a Handshake" @@ -468,7 +525,7 @@ or shoot a gun to move around via Newton's 3rd Law of Motion." var/angle = 0 var/mob/living/simple_animal/hostile/construct/Cviewer = null -/atom/movable/screen/alert/bloodsense/Initialize(mapload) +/atom/movable/screen/alert/bloodsense/Initialize(mapload, datum/hud/hud_owner) . = ..() narnar = new('icons/mob/screen_alert.dmi', "mini_nar") START_PROCESSING(SSprocessing, src) @@ -679,18 +736,21 @@ so as to remain in compliance with the most up-to-date laws." complete, you will have exclusive control of it, and you will gain \ additional processing time to unlock more malfunction abilities." icon_state = "hackingapc" - timeout = 600 + timeout = 60 SECONDS + clickable_glow = TRUE var/atom/target = null /atom/movable/screen/alert/hackingapc/Click() - if(!usr || !usr.client || usr != owner) + . = ..() + if(!.) return if(!target) return var/mob/living/silicon/ai/AI = usr var/turf/T = get_turf(target) - if(T) - AI.eyeobj.setLoc(T) + if(!T) + return + AI.eyeobj.setLoc(T) //MECHS @@ -706,25 +766,30 @@ so as to remain in compliance with the most up-to-date laws." name = "Revival" desc = "Someone is trying to revive you. Re-enter your corpse if you want to be revived!" icon_state = "template" - timeout = 300 + timeout = 30 SECONDS + clickable_glow = TRUE /atom/movable/screen/alert/notify_cloning/Click() - if(!usr || !usr.client || usr != owner) + . = ..() + if(!.) return - var/mob/dead/observer/G = usr - G.reenter_corpse() + var/mob/dead/observer/dead_owner = usr + dead_owner.reenter_corpse() /atom/movable/screen/alert/notify_action name = "Body created" desc = "A body was created. You can enter it." icon_state = "template" - timeout = 300 + timeout = 30 SECONDS + clickable_glow = TRUE var/atom/target = null var/action = NOTIFY_JUMP /atom/movable/screen/alert/notify_action/Click() - if(!usr || !usr.client || usr != owner) + . = ..() + if(!.) return + if(!target) return var/mob/dead/observer/G = usr @@ -742,29 +807,43 @@ so as to remain in compliance with the most up-to-date laws." //OBJECT-BASED -/atom/movable/screen/alert/restrained/buckled +/atom/movable/screen/alert/buckled name = "Buckled" desc = "You've been buckled to something. Click the alert to unbuckle unless you're handcuffed." icon_state = "buckled" + clickable_glow = TRUE + +/atom/movable/screen/alert/restrained + clickable_glow = TRUE /atom/movable/screen/alert/restrained/handcuffed name = "Handcuffed" desc = "You're handcuffed and can't act. If anyone drags you, you won't be able to move. Click the alert to free yourself." + click_master = FALSE /atom/movable/screen/alert/restrained/legcuffed name = "Legcuffed" desc = "You're legcuffed, which slows you down considerably. Click the alert to free yourself." + click_master = FALSE /atom/movable/screen/alert/restrained/Click() + . = ..() + if(!.) + return + var/mob/living/L = usr - if(!istype(L) || !L.can_resist() || L != owner) + if(!istype(L) || !L.can_resist()) return L.MarkResistTime() return L.resist_restraints() -/atom/movable/screen/alert/restrained/buckled/Click() +/atom/movable/screen/alert/buckled/Click() + . = ..() + if(!.) + return + var/mob/living/L = usr - if(!istype(L) || !L.can_resist() || L != owner) + if(!istype(L) || !L.can_resist()) return L.MarkResistTime() return L.resist_buckle() @@ -778,10 +857,14 @@ so as to remain in compliance with the most up-to-date laws." name = "Knotted Shoes" desc = "Someone tied your shoelaces together! Click the alert or your shoes to undo the knot." icon_state = "shoealert" + clickable_glow = TRUE /atom/movable/screen/alert/shoes/Click() + . = ..() + if(!.) + return var/mob/living/carbon/C = usr - if(!istype(C) || !C.can_resist() || C != owner || !C.shoes) + if(!istype(C) || !C.can_resist() || !C.shoes) return C.MarkResistTime() C.shoes.handle_tying(C) @@ -827,9 +910,9 @@ so as to remain in compliance with the most up-to-date laws." return FALSE if(usr != owner) return FALSE - var/paramslist = params2list(params) - if(paramslist["shift"]) // screen objects don't do the normal Click() stuff so we'll cheat - to_chat(usr, "[name] - [desc]") + var/modifiers = params2list(params) + if(LAZYACCESS(modifiers, SHIFT_CLICK)) // screen objects don't do the normal Click() stuff so we'll cheat + to_chat(usr, examine_block("[jointext(examine(usr), "\n")]")) return FALSE if(master && click_master) return usr.client.Click(master, location, control, params) @@ -842,3 +925,9 @@ so as to remain in compliance with the most up-to-date laws." master = null owner = null screen_loc = "" + +/atom/movable/screen/alert/examine(mob/user) + return list( + span_boldnotice(name), + span_info(desc), + ) diff --git a/code/_onclick/hud/alien.dm b/code/_onclick/hud/alien.dm index 8a494a05b9..49d0087a7d 100644 --- a/code/_onclick/hud/alien.dm +++ b/code/_onclick/hud/alien.dm @@ -39,84 +39,71 @@ //begin buttons - using = new /atom/movable/screen/swap_hand() + using = new /atom/movable/screen/swap_hand(null, src) using.icon = ui_style using.icon_state = "swap_1" using.screen_loc = ui_swaphand_position(owner,1) - using.hud = src static_inventory += using - using = new /atom/movable/screen/swap_hand() + using = new /atom/movable/screen/swap_hand(null, src) using.icon = ui_style using.icon_state = "swap_2" using.screen_loc = ui_swaphand_position(owner,2) - using.hud = src static_inventory += using - action_intent = new /atom/movable/screen/act_intent/alien() + action_intent = new /atom/movable/screen/act_intent/alien(null, src) action_intent.icon_state = mymob.a_intent - action_intent.hud = src static_inventory += action_intent if(isalienhunter(mymob)) var/mob/living/carbon/alien/humanoid/hunter/H = mymob - H.leap_icon = new /atom/movable/screen/alien/leap() + H.leap_icon = new /atom/movable/screen/alien/leap(null, src) H.leap_icon.screen_loc = ui_alien_storage_r static_inventory += H.leap_icon - using = new/atom/movable/screen/language_menu + using = new/atom/movable/screen/language_menu(null, src) using.screen_loc = ui_alien_language_menu - using.hud = src static_inventory += using - using = new /atom/movable/screen/drop() + using = new /atom/movable/screen/drop(null, src) using.icon = ui_style using.screen_loc = ui_drop_throw - using.hud = src static_inventory += using - using = new /atom/movable/screen/resist() + using = new /atom/movable/screen/resist(null, src) using.icon = ui_style using.screen_loc = ui_pull_resist - using.hud = src hotkeybuttons += using - throw_icon = new /atom/movable/screen/throw_catch() + throw_icon = new /atom/movable/screen/throw_catch(null, src) throw_icon.icon = ui_style throw_icon.screen_loc = ui_drop_throw - throw_icon.hud = src hotkeybuttons += throw_icon - pull_icon = new /atom/movable/screen/pull() + pull_icon = new /atom/movable/screen/pull(null, src) pull_icon.icon = ui_style - pull_icon.hud = src pull_icon.update_icon() pull_icon.screen_loc = ui_pull_resist static_inventory += pull_icon //begin indicators - healths = new /atom/movable/screen/healths/alien() - healths.hud = src + healths = new /atom/movable/screen/healths/alien(null, src) infodisplay += healths - alien_plasma_display = new /atom/movable/screen/alien/plasma_display() - alien_plasma_display.hud = src + alien_plasma_display = new /atom/movable/screen/alien/plasma_display(null, src) infodisplay += alien_plasma_display if(!isalienqueen(mymob)) - alien_queen_finder = new /atom/movable/screen/alien/alien_queen_finder - alien_queen_finder.hud = src + alien_queen_finder = new /atom/movable/screen/alien/alien_queen_finder(null, src) infodisplay += alien_queen_finder - zone_select = new /atom/movable/screen/zone_sel/alien() - zone_select.hud = src + zone_select = new /atom/movable/screen/zone_sel/alien(null, src) zone_select.update_icon() static_inventory += zone_select for(var/atom/movable/screen/inventory/inv in (static_inventory + toggleable_inventory)) if(inv.slot_id) - inv.hud = src inv_slots[TOBITSHIFT(inv.slot_id) + 1] = inv inv.update_icon() diff --git a/code/_onclick/hud/alien_larva.dm b/code/_onclick/hud/alien_larva.dm index 17d3ad35e4..50848bb37e 100644 --- a/code/_onclick/hud/alien_larva.dm +++ b/code/_onclick/hud/alien_larva.dm @@ -5,32 +5,26 @@ ..() var/atom/movable/screen/using - action_intent = new /atom/movable/screen/act_intent/alien() + action_intent = new /atom/movable/screen/act_intent/alien(null, src) action_intent.icon_state = mymob.a_intent - action_intent.hud = src static_inventory += action_intent - healths = new /atom/movable/screen/healths/alien() - healths.hud = src + healths = new /atom/movable/screen/healths/alien(null, src) infodisplay += healths - alien_queen_finder = new /atom/movable/screen/alien/alien_queen_finder() - alien_queen_finder.hud = src + alien_queen_finder = new /atom/movable/screen/alien/alien_queen_finder(null, src) infodisplay += alien_queen_finder - pull_icon = new /atom/movable/screen/pull() + pull_icon = new /atom/movable/screen/pull(null, src) pull_icon.icon = 'icons/mob/screen_alien.dmi' - pull_icon.hud = src pull_icon.update_icon() pull_icon.screen_loc = ui_pull_resist hotkeybuttons += pull_icon - using = new/atom/movable/screen/language_menu + using = new/atom/movable/screen/language_menu(null, src) using.screen_loc = ui_alien_language_menu - using.hud = src static_inventory += using - zone_select = new /atom/movable/screen/zone_sel/alien() - zone_select.hud = src + zone_select = new /atom/movable/screen/zone_sel/alien(null, src) zone_select.update_icon() static_inventory += zone_select diff --git a/code/_onclick/hud/blob_overmind.dm b/code/_onclick/hud/blob_overmind.dm index f4d6ffc919..7ce0086974 100644 --- a/code/_onclick/hud/blob_overmind.dm +++ b/code/_onclick/hud/blob_overmind.dm @@ -1,6 +1,7 @@ /atom/movable/screen/blob icon = 'icons/mob/blob.dmi' + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/blob/MouseEntered(location,control,params) openToolTip(usr,src,params,title = name,content = desc, theme = "blob") @@ -126,61 +127,50 @@ ..() var/atom/movable/screen/using - blobpwrdisplay = new /atom/movable/screen() + blobpwrdisplay = new /atom/movable/screen(null, src) blobpwrdisplay.name = "blob power" blobpwrdisplay.icon_state = "block" blobpwrdisplay.screen_loc = ui_health blobpwrdisplay.mouse_opacity = MOUSE_OPACITY_TRANSPARENT blobpwrdisplay.layer = ABOVE_HUD_LAYER blobpwrdisplay.plane = ABOVE_HUD_PLANE - blobpwrdisplay.hud = src infodisplay += blobpwrdisplay - healths = new /atom/movable/screen/healths/blob() - healths.hud = src + healths = new /atom/movable/screen/healths/blob(null, src) infodisplay += healths - using = new /atom/movable/screen/blob/BlobHelp() + using = new /atom/movable/screen/blob/BlobHelp(null, src) using.screen_loc = "WEST:6,NORTH:-3" - using.hud = src static_inventory += using - using = new /atom/movable/screen/blob/JumpToNode() + using = new /atom/movable/screen/blob/JumpToNode(null, src) using.screen_loc = ui_inventory - using.hud = src static_inventory += using - using = new /atom/movable/screen/blob/JumpToCore() + using = new /atom/movable/screen/blob/JumpToCore(null, src) using.screen_loc = ui_zonesel - using.hud = src static_inventory += using - using = new /atom/movable/screen/blob/Blobbernaut() + using = new /atom/movable/screen/blob/Blobbernaut(null, src) using.screen_loc = ui_belt - using.hud = src static_inventory += using - using = new /atom/movable/screen/blob/ResourceBlob() + using = new /atom/movable/screen/blob/ResourceBlob(null, src) using.screen_loc = ui_back - using.hud = src static_inventory += using - using = new /atom/movable/screen/blob/NodeBlob() + using = new /atom/movable/screen/blob/NodeBlob(null, src) using.screen_loc = ui_hand_position(2) - using.hud = src static_inventory += using - using = new /atom/movable/screen/blob/FactoryBlob() + using = new /atom/movable/screen/blob/FactoryBlob(null, src) using.screen_loc = ui_hand_position(1) - using.hud = src static_inventory += using - using = new /atom/movable/screen/blob/ReadaptStrain() + using = new /atom/movable/screen/blob/ReadaptStrain(null, src) using.screen_loc = ui_storage1 - using.hud = src static_inventory += using - using = new /atom/movable/screen/blob/RelocateCore() + using = new /atom/movable/screen/blob/RelocateCore(null, src) using.screen_loc = ui_storage2 - using.hud = src static_inventory += using diff --git a/code/_onclick/hud/blobbernauthud.dm b/code/_onclick/hud/blobbernauthud.dm index 430e8e81e7..f82be53afa 100644 --- a/code/_onclick/hud/blobbernauthud.dm +++ b/code/_onclick/hud/blobbernauthud.dm @@ -2,10 +2,8 @@ /datum/hud/blobbernaut/New(mob/owner) ..() - blobpwrdisplay = new /atom/movable/screen/healths/blob/naut/core() - blobpwrdisplay.hud = src + blobpwrdisplay = new /atom/movable/screen/healths/blob/naut/core(null, src) infodisplay += blobpwrdisplay - healths = new /atom/movable/screen/healths/blob/naut() - healths.hud = src + healths = new /atom/movable/screen/healths/blob/naut(null, src) infodisplay += healths diff --git a/code/_onclick/hud/clockwork_marauder.dm b/code/_onclick/hud/clockwork_marauder.dm index de9cb65c75..51d1fbb4a9 100644 --- a/code/_onclick/hud/clockwork_marauder.dm +++ b/code/_onclick/hud/clockwork_marauder.dm @@ -7,14 +7,14 @@ ..() var/atom/movable/screen/using - healths = new /atom/movable/screen/healths/clock() + healths = new /atom/movable/screen/healths/clock(null, src) infodisplay += healths - hosthealth = new /atom/movable/screen/healths/clock() + hosthealth = new /atom/movable/screen/healths/clock(null, src) hosthealth.screen_loc = ui_internal infodisplay += hosthealth - using = new /atom/movable/screen/marauder/emerge() + using = new /atom/movable/screen/marauder/emerge(null, src) using.screen_loc = ui_zonesel static_inventory += using diff --git a/code/_onclick/hud/constructs.dm b/code/_onclick/hud/constructs.dm index 31f1060f17..70f40aace3 100644 --- a/code/_onclick/hud/constructs.dm +++ b/code/_onclick/hud/constructs.dm @@ -3,13 +3,11 @@ /datum/hud/constructs/New(mob/owner) ..() - pull_icon = new /atom/movable/screen/pull() + pull_icon = new /atom/movable/screen/pull(null, src) pull_icon.icon = ui_style - pull_icon.hud = src pull_icon.update_icon() pull_icon.screen_loc = ui_construct_pull static_inventory += pull_icon - healths = new /atom/movable/screen/healths/construct() - healths.hud = src + healths = new /atom/movable/screen/healths/construct(null, src) infodisplay += healths diff --git a/code/_onclick/hud/credits.dm b/code/_onclick/hud/credits.dm index e991ebc47b..eb6bdfe995 100644 --- a/code/_onclick/hud/credits.dm +++ b/code/_onclick/hud/credits.dm @@ -39,7 +39,7 @@ var/client/parent var/matrix/target -/atom/movable/screen/credit/Initialize(mapload, credited, client/P, icon/I) +/atom/movable/screen/credit/Initialize(mapload, datum/hud/hud_owner, credited, client/P, icon/I) . = ..() icon = I parent = P diff --git a/code/_onclick/hud/devil.dm b/code/_onclick/hud/devil.dm index 574f5dd1fd..fb5028145c 100644 --- a/code/_onclick/hud/devil.dm +++ b/code/_onclick/hud/devil.dm @@ -6,51 +6,44 @@ ..() var/atom/movable/screen/using - using = new /atom/movable/screen/drop() + using = new /atom/movable/screen/drop(null, src) using.icon = ui_style using.screen_loc = ui_drone_drop - using.hud = src static_inventory += using - pull_icon = new /atom/movable/screen/pull() + pull_icon = new /atom/movable/screen/pull(null, src) pull_icon.icon = ui_style - pull_icon.hud = src pull_icon.update_icon() pull_icon.screen_loc = ui_drone_pull static_inventory += pull_icon build_hand_slots() - using = new /atom/movable/screen/inventory() + using = new /atom/movable/screen/inventory(null, src) using.name = "hand" using.icon = ui_style using.icon_state = "swap_1_m" using.screen_loc = ui_swaphand_position(owner,1) using.layer = HUD_LAYER using.plane = HUD_PLANE - using.hud = src static_inventory += using - using = new /atom/movable/screen/inventory() + using = new /atom/movable/screen/inventory(null, src) using.name = "hand" using.icon = ui_style using.icon_state = "swap_2" using.screen_loc = ui_swaphand_position(owner,2) using.layer = HUD_LAYER using.plane = HUD_PLANE - using.hud = src static_inventory += using - zone_select = new /atom/movable/screen/zone_sel() + zone_select = new /atom/movable/screen/zone_sel(null, src) zone_select.icon = ui_style - zone_select.hud = src zone_select.update_icon() - lingchemdisplay = new /atom/movable/screen/ling/chems() - lingchemdisplay.hud = src + lingchemdisplay = new /atom/movable/screen/ling/chems(null, src) - devilsouldisplay = new /atom/movable/screen/devil/soul_counter - devilsouldisplay.hud = src + devilsouldisplay = new /atom/movable/screen/devil/soul_counter(null, src) infodisplay += devilsouldisplay diff --git a/code/_onclick/hud/drones.dm b/code/_onclick/hud/drones.dm index a2cae89864..a6632b553f 100644 --- a/code/_onclick/hud/drones.dm +++ b/code/_onclick/hud/drones.dm @@ -2,7 +2,7 @@ ..() var/atom/movable/screen/inventory/inv_box - inv_box = new /atom/movable/screen/inventory() + inv_box = new /atom/movable/screen/inventory(null, src) inv_box.name = "internal storage" inv_box.icon = ui_style inv_box.icon_state = "suit_storage" @@ -11,7 +11,7 @@ inv_box.slot_id = ITEM_SLOT_DEX_STORAGE static_inventory += inv_box - inv_box = new /atom/movable/screen/inventory() + inv_box = new /atom/movable/screen/inventory(null, src) inv_box.name = "head/mask" inv_box.icon = ui_style inv_box.icon_state = "mask" @@ -22,7 +22,6 @@ for(var/atom/movable/screen/inventory/inv in (static_inventory + toggleable_inventory)) if(inv.slot_id) - inv.hud = src inv_slots[TOBITSHIFT(inv.slot_id) + 1] = inv inv.update_icon() diff --git a/code/_onclick/hud/families.dm b/code/_onclick/hud/families.dm index 6cc9f4ef32..af2f432aaf 100644 --- a/code/_onclick/hud/families.dm +++ b/code/_onclick/hud/families.dm @@ -9,10 +9,7 @@ /// Boolean, have the cops arrived? If so, the icon stops changing and remains the same. var/cops_arrived = 0 -/atom/movable/screen/wanted/New() - return ..() - -/atom/movable/screen/wanted/Initialize(mapload) +/atom/movable/screen/wanted/Initialize(mapload, datum/hud/hud_owner) . = ..() update_icon() diff --git a/code/_onclick/hud/generic_dextrous.dm b/code/_onclick/hud/generic_dextrous.dm index 1762bee1fc..54cb0513c0 100644 --- a/code/_onclick/hud/generic_dextrous.dm +++ b/code/_onclick/hud/generic_dextrous.dm @@ -3,63 +3,55 @@ ..() var/atom/movable/screen/using - using = new /atom/movable/screen/drop() + using = new /atom/movable/screen/drop(null, src) using.icon = ui_style using.screen_loc = ui_drone_drop - using.hud = src static_inventory += using - pull_icon = new /atom/movable/screen/pull() + pull_icon = new /atom/movable/screen/pull(null, src) pull_icon.icon = ui_style - pull_icon.hud = src pull_icon.update_icon() pull_icon.screen_loc = ui_drone_pull static_inventory += pull_icon build_hand_slots() - using = new /atom/movable/screen/swap_hand() + using = new /atom/movable/screen/swap_hand(null, src) using.icon = ui_style using.icon_state = "swap_1_m" using.screen_loc = ui_swaphand_position(owner,1) - using.hud = src static_inventory += using - using = new /atom/movable/screen/swap_hand() + using = new /atom/movable/screen/swap_hand(null, src) using.icon = ui_style using.icon_state = "swap_2" using.screen_loc = ui_swaphand_position(owner,2) - using.hud = src static_inventory += using if(mymob.possible_a_intents) if(mymob.possible_a_intents.len == 4) // All possible intents - full intent selector - action_intent = new /atom/movable/screen/act_intent/segmented + action_intent = new /atom/movable/screen/act_intent/segmented(null, src) else - action_intent = new /atom/movable/screen/act_intent - action_intent.icon = ui_style - action_intent.icon_state = mymob.a_intent - action_intent.hud = src + action_intent = new /atom/movable/screen/act_intent(null, src) + action_intent.icon = ui_style_modular(ui_style) + action_intent.update_icon() static_inventory += action_intent - zone_select = new /atom/movable/screen/zone_sel() + zone_select = new /atom/movable/screen/zone_sel(null, src) zone_select.icon = ui_style - zone_select.hud = src zone_select.update_icon() static_inventory += zone_select - using = new /atom/movable/screen/area_creator + using = new /atom/movable/screen/area_creator(null, src) using.icon = ui_style - using.hud = src static_inventory += using mymob.client.screen = list() for(var/atom/movable/screen/inventory/inv in (static_inventory + toggleable_inventory)) if(inv.slot_id) - inv.hud = src inv_slots[TOBITSHIFT(inv.slot_id) + 1] = inv inv.update_icon() diff --git a/code/_onclick/hud/ghost.dm b/code/_onclick/hud/ghost.dm index bb637ed445..ea36022dfb 100644 --- a/code/_onclick/hud/ghost.dm +++ b/code/_onclick/hud/ghost.dm @@ -1,5 +1,6 @@ /atom/movable/screen/ghost icon = 'icons/mob/screen_ghost.dmi' + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/ghost/MouseEntered() flick(icon_state + "_anim", src) @@ -48,34 +49,28 @@ ..() var/atom/movable/screen/using - using = new /atom/movable/screen/ghost/jumptomob() + using = new /atom/movable/screen/ghost/jumptomob(null, src) using.screen_loc = ui_ghost_jumptomob - using.hud = src static_inventory += using - using = new /atom/movable/screen/ghost/orbit() + using = new /atom/movable/screen/ghost/orbit(null, src) using.screen_loc = ui_ghost_orbit - using.hud = src static_inventory += using - using = new /atom/movable/screen/ghost/reenter_corpse() + using = new /atom/movable/screen/ghost/reenter_corpse(null, src) using.screen_loc = ui_ghost_reenter_corpse - using.hud = src static_inventory += using - using = new /atom/movable/screen/ghost/teleport() + using = new /atom/movable/screen/ghost/teleport(null, src) using.screen_loc = ui_ghost_teleport - using.hud = src static_inventory += using - using = new /atom/movable/screen/ghost/spawners() + using = new /atom/movable/screen/ghost/spawners(null, src) using.screen_loc = ui_ghost_spawners - using.hud = src static_inventory += using - using = new /atom/movable/screen/language_menu + using = new /atom/movable/screen/language_menu(null, src) using.icon = ui_style - using.hud = src static_inventory += using /datum/hud/ghost/show_hud(version = 0, mob/viewmob) diff --git a/code/_onclick/hud/guardian.dm b/code/_onclick/hud/guardian.dm index 2af02d8437..0443dc3deb 100644 --- a/code/_onclick/hud/guardian.dm +++ b/code/_onclick/hud/guardian.dm @@ -3,33 +3,27 @@ ..() var/atom/movable/screen/using - healths = new /atom/movable/screen/healths/guardian() - healths.hud = src + healths = new /atom/movable/screen/healths/guardian(null, src) infodisplay += healths - using = new /atom/movable/screen/guardian/Manifest() + using = new /atom/movable/screen/guardian/Manifest(null, src) using.screen_loc = ui_hand_position(2) - using.hud = src static_inventory += using - using = new /atom/movable/screen/guardian/Recall() + using = new /atom/movable/screen/guardian/Recall(null, src) using.screen_loc = ui_hand_position(1) - using.hud = src static_inventory += using - using = new owner.toggle_button_type() + using = new owner.toggle_button_type(null, src) using.screen_loc = ui_storage1 - using.hud = src static_inventory += using - using = new /atom/movable/screen/guardian/ToggleLight() + using = new /atom/movable/screen/guardian/ToggleLight(null, src) using.screen_loc = ui_inventory - using.hud = src static_inventory += using - using = new /atom/movable/screen/guardian/Communicate() + using = new /atom/movable/screen/guardian/Communicate(null, src) using.screen_loc = ui_back - using.hud = src static_inventory += using /datum/hud/dextrous/guardian/New(mob/living/simple_animal/hostile/guardian/owner) //for a dextrous guardian @@ -38,7 +32,7 @@ if(istype(owner, /mob/living/simple_animal/hostile/guardian/dextrous)) var/atom/movable/screen/inventory/inv_box - inv_box = new /atom/movable/screen/inventory() + inv_box = new /atom/movable/screen/inventory(null, src) inv_box.name = "internal storage" inv_box.icon = ui_style inv_box.icon_state = "suit_storage" @@ -46,32 +40,32 @@ inv_box.slot_id = ITEM_SLOT_DEX_STORAGE static_inventory += inv_box - using = new /atom/movable/screen/guardian/Communicate() + using = new /atom/movable/screen/guardian/Communicate(null, src) using.screen_loc = ui_sstore1 static_inventory += using else - using = new /atom/movable/screen/guardian/Communicate() + using = new /atom/movable/screen/guardian/Communicate(null, src) using.screen_loc = ui_id static_inventory += using - healths = new /atom/movable/screen/healths/guardian() + healths = new /atom/movable/screen/healths/guardian(null, src) infodisplay += healths - using = new /atom/movable/screen/guardian/Manifest() + using = new /atom/movable/screen/guardian/Manifest(null, src) using.screen_loc = ui_belt static_inventory += using - using = new /atom/movable/screen/guardian/Recall() + using = new /atom/movable/screen/guardian/Recall(null, src) using.screen_loc = ui_back static_inventory += using - using = new owner.toggle_button_type() + using = new owner.toggle_button_type(null, src) using.screen_loc = ui_storage2 static_inventory += using - using = new /atom/movable/screen/guardian/ToggleLight() + using = new /atom/movable/screen/guardian/ToggleLight(null, src) using.screen_loc = ui_inventory static_inventory += using @@ -93,6 +87,7 @@ /atom/movable/screen/guardian icon = 'icons/mob/guardian.dmi' + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/guardian/Manifest icon_state = "manifest" diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm index dbc6ffe4c5..437df49f23 100644 --- a/code/_onclick/hud/hud.dm +++ b/code/_onclick/hud/hud.dm @@ -15,7 +15,8 @@ GLOBAL_LIST_INIT(available_ui_styles, list( "Clockwork" = 'icons/mob/screen_clockwork.dmi', "Trasen-Knox" = 'icons/mob/screen_trasenknox.dmi', "Detective" = 'icons/mob/screen_detective.dmi', - "Liteweb" = 'modular_sand/icons/mob/screen_liteweb.dmi' + "Liteweb" = 'modular_sand/icons/hud/screen_liteweb/base.dmi', + "Corru" = 'modular_sand/icons/hud/screen_corru/base.dmi' )) /proc/ui_style2icon(ui_style) @@ -44,7 +45,7 @@ GLOBAL_LIST_INIT(available_ui_styles, list( var/atom/movable/screen/synth/coolant_counter/coolant_display var/atom/movable/screen/action_intent - var/atom/movable/screen/zone_select + var/atom/movable/screen/zone_sel/zone_select var/atom/movable/screen/pull_icon var/atom/movable/screen/rest_icon var/atom/movable/screen/throw_icon @@ -88,7 +89,6 @@ GLOBAL_LIST_INIT(available_ui_styles, list( var/atom/movable/screen/healths var/atom/movable/screen/healthdoll - var/atom/movable/screen/internals var/atom/movable/screen/wanted/wanted_lvl // subtypes can override this to force a specific UI style @@ -111,12 +111,12 @@ GLOBAL_LIST_INIT(available_ui_styles, list( hand_slots = list() for(var/mytype in subtypesof(/atom/movable/screen/plane_master)) - var/atom/movable/screen/plane_master/instance = new mytype() + var/atom/movable/screen/plane_master/instance = new mytype(null, src) plane_masters["[instance.plane]"] = instance instance.backdrop(mymob) for(var/mytype in subtypesof(/atom/movable/plane_master_controller)) - var/atom/movable/plane_master_controller/controller_instance = new mytype(src) + var/atom/movable/plane_master_controller/controller_instance = new mytype(null, src) plane_master_controllers[controller_instance.name] = controller_instance screentip_text = new(null, src) @@ -152,7 +152,6 @@ GLOBAL_LIST_INIT(available_ui_styles, list( healths = null healthdoll = null wanted_lvl = null - internals = null hunger = null thirst = null @@ -345,14 +344,13 @@ GLOBAL_LIST_INIT(available_ui_styles, list( hand_slots = list() var/atom/movable/screen/inventory/hand/hand_box for(var/i in 1 to mymob.held_items.len) - hand_box = new /atom/movable/screen/inventory/hand() + hand_box = new /atom/movable/screen/inventory/hand(null, src) hand_box.name = mymob.get_held_index_name(i) hand_box.icon = ui_style hand_box.icon_state = "hand_[mymob.held_index_to_dir(i)]" hand_box.screen_loc = ui_hand_position(i) hand_box.held_index = i hand_slots["[i]"] = hand_box - hand_box.hud = src static_inventory += hand_box hand_box.update_icon() @@ -386,6 +384,9 @@ GLOBAL_LIST_INIT(available_ui_styles, list( listed_actions.insert_action(button) if(SCRN_OBJ_IN_PALETTE) palette_actions.insert_action(button) + if(SCRN_OBJ_INSERT_FIRST) + listed_actions.insert_action(button, index = 1) + position = SCRN_OBJ_IN_LIST else // If we don't have it as a define, this is a screen_loc, and we should be floating floating_actions += button button.screen_loc = position diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm index 5ebde532dc..86ccd00759 100644 --- a/code/_onclick/hud/human.dm +++ b/code/_onclick/hud/human.dm @@ -3,7 +3,9 @@ /atom/movable/screen/human/toggle name = "toggle" + base_icon_state = "toggle" icon_state = "toggle" + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/human/toggle/Click() @@ -33,9 +35,19 @@ targetmob.hud_used.extra_inventory_update(usr) // Sandstorm edit END + update_icon() + +/atom/movable/screen/human/toggle/update_icon_state() + . = ..() + icon_state = check_on() ? "[base_icon_state]_on" : "[base_icon_state]" + +/atom/movable/screen/human/toggle/proc/check_on() + return hud.inventory_shown + // Sandstorm edit /atom/movable/screen/human/toggle/extra name = "toggle extra" + base_icon_state = "toggle_extra" icon_state = "toggle_extra" /atom/movable/screen/human/toggle/extra/Click() @@ -55,11 +67,17 @@ usr.client.screen += targetmob.hud_used.extra_inventory targetmob.hud_used.extra_inventory_update(usr) + + update_icon() // +/atom/movable/screen/human/toggle/extra/check_on() + return hud.extra_shown + /atom/movable/screen/human/equip name = "equip" icon_state = "act_equip" + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/human/equip/Click() if(ismecha(usr.loc)) // stops inventory actions in a mech @@ -102,6 +120,7 @@ /atom/movable/screen/ling/sting name = "current sting" screen_loc = ui_lingstingdisplay + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/ling/sting/Click() if(isobserver(usr)) @@ -217,54 +236,48 @@ var/atom/movable/screen/using var/atom/movable/screen/inventory/inv_box - using = new/atom/movable/screen/language_menu + using = new/atom/movable/screen/language_menu(null, src) using.icon = ui_style if(!widescreenlayout) // CIT CHANGE using.screen_loc = ui_boxlang // CIT CHANGE - using.hud = src static_inventory += using - using = new /atom/movable/screen/area_creator + using = new /atom/movable/screen/area_creator(null, src) using.icon = ui_style if(!widescreenlayout) // CIT CHANGE using.screen_loc = ui_boxarea // CIT CHANGE - using.hud = src static_inventory += using - using = new /atom/movable/screen/voretoggle() //We fancy Vore now + using = new /atom/movable/screen/voretoggle(null, src) //We fancy Vore now using.icon = tg_ui_icon_to_cit_ui(ui_style) using.screen_loc = ui_voremode if(!widescreenlayout) using.screen_loc = ui_boxvore - using.hud = src static_inventory += using - action_intent = new /atom/movable/screen/act_intent/segmented - action_intent.icon_state = mymob.a_intent - action_intent.hud = src + action_intent = new /atom/movable/screen/act_intent/segmented(null, src) + action_intent.icon = ui_style_modular(ui_style) + action_intent.icon_state = "[action_intent.base_icon_state]_[mymob.a_intent]" static_inventory += action_intent assert_move_intent_ui(owner, TRUE) // clickdelay - clickdelay = new - clickdelay.hud = src + clickdelay = new(null, src) clickdelay.screen_loc = ui_clickdelay static_inventory += clickdelay // resistdelay - resistdelay = new - resistdelay.hud = src + resistdelay = new(null, src) resistdelay.screen_loc = ui_resistdelay static_inventory += resistdelay - using = new /atom/movable/screen/drop() + using = new /atom/movable/screen/drop(null, src) using.icon = ui_style using.screen_loc = ui_drop_throw - using.hud = src static_inventory += using - inv_box = new /atom/movable/screen/inventory() + inv_box = new /atom/movable/screen/inventory(null, src) inv_box.name = "uniform" inv_box.icon = ui_style inv_box.slot_id = ITEM_SLOT_ICLOTHING @@ -273,7 +286,7 @@ inv_box.screen_loc = ui_iclothing toggleable_inventory += inv_box - inv_box = new /atom/movable/screen/inventory() + inv_box = new /atom/movable/screen/inventory(null, src) inv_box.name = "suit" inv_box.icon = ui_style inv_box.slot_id = ITEM_SLOT_OCLOTHING @@ -284,21 +297,19 @@ build_hand_slots() - using = new /atom/movable/screen/swap_hand() + using = new /atom/movable/screen/swap_hand(null, src) using.icon = ui_style using.icon_state = "swap_1" using.screen_loc = ui_swaphand_position(owner,1) - using.hud = src static_inventory += using - using = new /atom/movable/screen/swap_hand() + using = new /atom/movable/screen/swap_hand(null, src) using.icon = ui_style using.icon_state = "swap_2" using.screen_loc = ui_swaphand_position(owner,2) - using.hud = src static_inventory += using - inv_box = new /atom/movable/screen/inventory() + inv_box = new /atom/movable/screen/inventory(null, src) inv_box.name = "id" inv_box.icon = ui_style inv_box.icon_state = "id" @@ -307,7 +318,7 @@ inv_box.slot_id = ITEM_SLOT_ID static_inventory += inv_box - inv_box = new /atom/movable/screen/inventory() + inv_box = new /atom/movable/screen/inventory(null, src) inv_box.name = "mask" inv_box.icon = ui_style inv_box.icon_state = "mask" @@ -316,7 +327,7 @@ inv_box.slot_id = ITEM_SLOT_MASK toggleable_inventory += inv_box - inv_box = new /atom/movable/screen/inventory() + inv_box = new /atom/movable/screen/inventory(null, src) inv_box.name = "neck" inv_box.icon = ui_style inv_box.icon_state = "neck" @@ -325,7 +336,7 @@ inv_box.slot_id = ITEM_SLOT_NECK toggleable_inventory += inv_box - inv_box = new /atom/movable/screen/inventory() + inv_box = new /atom/movable/screen/inventory(null, src) inv_box.name = "back" inv_box.icon = ui_style inv_box.icon_state = "back" @@ -334,25 +345,25 @@ inv_box.slot_id = ITEM_SLOT_BACK static_inventory += inv_box - inv_box = new /atom/movable/screen/inventory() + inv_box = new /atom/movable/screen/inventory(null, src) inv_box.name = "left pocket" inv_box.icon = ui_style inv_box.icon_state = "pocket" - inv_box.icon_full = "template" + inv_box.icon_full = "template_small" inv_box.screen_loc = ui_storage1 inv_box.slot_id = ITEM_SLOT_LPOCKET static_inventory += inv_box - inv_box = new /atom/movable/screen/inventory() + inv_box = new /atom/movable/screen/inventory(null, src) inv_box.name = "right pocket" inv_box.icon = ui_style inv_box.icon_state = "pocket" - inv_box.icon_full = "template" + inv_box.icon_full = "template_small" inv_box.screen_loc = ui_storage2 inv_box.slot_id = ITEM_SLOT_RPOCKET static_inventory += inv_box - inv_box = new /atom/movable/screen/inventory() + inv_box = new /atom/movable/screen/inventory(null, src) inv_box.name = "suit storage" inv_box.icon = ui_style inv_box.icon_state = "suit_storage" @@ -361,32 +372,28 @@ inv_box.slot_id = ITEM_SLOT_SUITSTORE static_inventory += inv_box - using = new /atom/movable/screen/resist() + using = new /atom/movable/screen/resist(null, src) using.icon = ui_style using.screen_loc = ui_overridden_resist // CIT CHANGE - changes this to overridden resist - using.hud = src hotkeybuttons += using - rest_icon = new /atom/movable/screen/rest() + rest_icon = new /atom/movable/screen/rest(null, src) 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() + using = new /atom/movable/screen/human/toggle(null, src) using.icon = ui_style using.screen_loc = ui_inventory - using.hud = src static_inventory += using - using = new /atom/movable/screen/human/equip() + using = new /atom/movable/screen/human/equip(null, src) using.icon = ui_style using.screen_loc = ui_equip_position(mymob) - using.hud = src static_inventory += using - inv_box = new /atom/movable/screen/inventory() + inv_box = new /atom/movable/screen/inventory(null, src) inv_box.name = "gloves" inv_box.icon = ui_style inv_box.icon_state = "gloves" @@ -395,7 +402,7 @@ inv_box.slot_id = ITEM_SLOT_GLOVES toggleable_inventory += inv_box - inv_box = new /atom/movable/screen/inventory() + inv_box = new /atom/movable/screen/inventory(null, src) inv_box.name = "eyes" inv_box.icon = ui_style inv_box.icon_state = "glasses" @@ -404,7 +411,7 @@ inv_box.slot_id = ITEM_SLOT_EYES toggleable_inventory += inv_box - inv_box = new /atom/movable/screen/inventory() + inv_box = new /atom/movable/screen/inventory(null, src) inv_box.name = "left ear" // Sandstorm edit inv_box.icon = ui_style inv_box.icon_state = "ears" @@ -413,7 +420,7 @@ inv_box.slot_id = ITEM_SLOT_EARS_LEFT // Sandstorm Edit toggleable_inventory += inv_box - inv_box = new /atom/movable/screen/inventory() + inv_box = new /atom/movable/screen/inventory(null, src) inv_box.name = "head" inv_box.icon = ui_style inv_box.icon_state = "head" @@ -422,7 +429,7 @@ inv_box.slot_id = ITEM_SLOT_HEAD toggleable_inventory += inv_box - inv_box = new /atom/movable/screen/inventory() + inv_box = new /atom/movable/screen/inventory(null, src) inv_box.name = "shoes" inv_box.icon = ui_style inv_box.icon_state = "shoes" @@ -432,13 +439,12 @@ toggleable_inventory += inv_box // Sandstorm edit - using = new /atom/movable/screen/human/toggle/extra() + using = new /atom/movable/screen/human/toggle/extra(null, src) using.icon = ui_style_modular(ui_style) using.screen_loc = ui_inventory_extra - using.hud = src toggleable_inventory += using - inv_box = new /atom/movable/screen/inventory() + inv_box = new /atom/movable/screen/inventory(null, src) inv_box.name = "underwear" inv_box.icon = ui_style_modular(ui_style) inv_box.icon_state = "underwear" @@ -447,7 +453,7 @@ inv_box.slot_id = ITEM_SLOT_UNDERWEAR // Sandstorm edit extra_inventory += inv_box - inv_box = new /atom/movable/screen/inventory() + inv_box = new /atom/movable/screen/inventory(null, src) inv_box.name = "socks" inv_box.icon = ui_style_modular(ui_style) inv_box.icon_state = "socks" @@ -456,7 +462,7 @@ inv_box.slot_id = ITEM_SLOT_SOCKS // Sandstorm edit extra_inventory += inv_box - inv_box = new /atom/movable/screen/inventory() + inv_box = new /atom/movable/screen/inventory(null, src) inv_box.name = "shirt" inv_box.icon = ui_style_modular(ui_style) inv_box.icon_state = "shirt" @@ -465,7 +471,7 @@ inv_box.slot_id = ITEM_SLOT_SHIRT // Sandstorm edit extra_inventory += inv_box - inv_box = new /atom/movable/screen/inventory() + inv_box = new /atom/movable/screen/inventory(null, src) inv_box.name = "right ear" inv_box.icon = ui_style_modular(ui_style) inv_box.icon_state = "ears_extra" @@ -474,7 +480,7 @@ inv_box.slot_id = ITEM_SLOT_EARS_RIGHT // Sandstorm edit extra_inventory += inv_box - inv_box = new /atom/movable/screen/inventory() + inv_box = new /atom/movable/screen/inventory(null, src) inv_box.name = "wrists" inv_box.icon = ui_style_modular(ui_style) inv_box.icon_state = "wrists" @@ -484,7 +490,7 @@ extra_inventory += inv_box // - inv_box = new /atom/movable/screen/inventory() + inv_box = new /atom/movable/screen/inventory(null, src) inv_box.name = "belt" inv_box.icon = ui_style inv_box.icon_state = "belt" @@ -493,89 +499,73 @@ inv_box.slot_id = ITEM_SLOT_BELT static_inventory += inv_box - throw_icon = new /atom/movable/screen/throw_catch() + throw_icon = new /atom/movable/screen/throw_catch(null, src) throw_icon.icon = ui_style throw_icon.screen_loc = ui_drop_throw - throw_icon.hud = src hotkeybuttons += throw_icon - hunger = new /atom/movable/screen/hunger() - hunger.hud = src + hunger = new /atom/movable/screen/hunger(null, src) infodisplay += hunger - thirst = new /atom/movable/screen/thirst() - thirst.hud = src + thirst = new /atom/movable/screen/thirst(null, src) infodisplay += thirst - internals = new /atom/movable/screen/internals() - internals.hud = src - infodisplay += internals - - healths = new /atom/movable/screen/healths() - healths.hud = src + healths = new /atom/movable/screen/healths(null, src) + healths.icon = ui_style_modular(ui_style, "health") infodisplay += healths - staminas = new /atom/movable/screen/staminas() - staminas.hud = src + staminas = new /atom/movable/screen/staminas(null, src) + staminas.icon = ui_style_modular(ui_style, "stamina") infodisplay += staminas if(!CONFIG_GET(flag/disable_stambuffer)) - staminabuffer = new /atom/movable/screen/staminabuffer() - staminabuffer.hud = src + staminabuffer = new /atom/movable/screen/staminabuffer(null, src) + staminabuffer.icon = ui_style_modular(ui_style, "stamina") infodisplay += staminabuffer //END OF CIT CHANGES - healthdoll = new /atom/movable/screen/healthdoll() - healthdoll.hud = src + healthdoll = new /atom/movable/screen/healthdoll(null, src) + healthdoll.icon = ui_style_modular(ui_style, "health") infodisplay += healthdoll - pull_icon = new /atom/movable/screen/pull() + pull_icon = new /atom/movable/screen/pull(null, src) pull_icon.icon = ui_style - pull_icon.hud = src pull_icon.update_icon() pull_icon.screen_loc = ui_pull_resist static_inventory += pull_icon - lingchemdisplay = new /atom/movable/screen/ling/chems() - lingchemdisplay.hud = src + lingchemdisplay = new /atom/movable/screen/ling/chems(null, src) infodisplay += lingchemdisplay - lingstingdisplay = new /atom/movable/screen/ling/sting() - lingstingdisplay.hud = src + lingstingdisplay = new /atom/movable/screen/ling/sting(null, src) infodisplay += lingstingdisplay - devilsouldisplay = new /atom/movable/screen/devil/soul_counter - devilsouldisplay.hud = src + devilsouldisplay = new /atom/movable/screen/devil/soul_counter(null, src) infodisplay += devilsouldisplay - blood_display = new /atom/movable/screen/bloodsucker/blood_counter // Blood Volume - blood_display.hud = src + blood_display = new /atom/movable/screen/bloodsucker/blood_counter(null, src) // Blood Volume infodisplay += blood_display - vamprank_display = new /atom/movable/screen/bloodsucker/rank_counter // Bloodsucker Rank - vamprank_display.hud = src + vamprank_display = new /atom/movable/screen/bloodsucker/rank_counter(null, src) // Bloodsucker Rank infodisplay += vamprank_display - sunlight_display = new /atom/movable/screen/bloodsucker/sunlight_counter // Sunlight - sunlight_display.hud = src + sunlight_display = new /atom/movable/screen/bloodsucker/sunlight_counter(null, src) // Sunlight infodisplay += sunlight_display - coolant_display = new /atom/movable/screen/synth/coolant_counter //Coolant & cooling efficiency readouts for Synths. - coolant_display.hud = src + coolant_display = new /atom/movable/screen/synth/coolant_counter(null, src) //Coolant & cooling efficiency readouts for Synths. infodisplay += coolant_display - zone_select = new /atom/movable/screen/zone_sel() + zone_select = new /atom/movable/screen/zone_sel(null, src) zone_select.icon = ui_style - zone_select.hud = src + zone_select.overlay_icon = ui_style_modular(ui_style, "zone") zone_select.update_icon() static_inventory += zone_select - combo_display = new /atom/movable/screen/combo() + combo_display = new /atom/movable/screen/combo(null, src) infodisplay += combo_display for(var/atom/movable/screen/inventory/inv in (static_inventory + toggleable_inventory + extra_inventory)) // Sandstorm edit if(inv.slot_id) - inv.hud = src inv_slots[TOBITSHIFT(inv.slot_id) + 1] = inv inv.update_icon() @@ -596,10 +586,9 @@ // make new ones // walk/run - using = new /atom/movable/screen/mov_intent + using = new /atom/movable/screen/mov_intent(null, src) using.icon = tg_ui_icon_to_cit_ui(ui_style) // CIT CHANGE - overrides mov intent icon using.screen_loc = ui_movi - using.hud = src using.update_icon() static_inventory += using if(!on_new) @@ -609,19 +598,17 @@ return // sprint button - using = new /atom/movable/screen/sprintbutton + using = new /atom/movable/screen/sprintbutton(null, src) using.icon = tg_ui_icon_to_cit_ui(ui_style) using.icon_state = ((owner.combat_flags & COMBAT_FLAG_SPRINT_ACTIVE) ? "act_sprint_on" : "act_sprint") using.screen_loc = ui_movi - using.hud = src static_inventory += using if(!on_new) owner?.client?.screen += using // same as above but buffer. - sprint_buffer = new /atom/movable/screen/sprint_buffer + sprint_buffer = new /atom/movable/screen/sprint_buffer(null, src) sprint_buffer.screen_loc = ui_sprintbufferloc - sprint_buffer.hud = src static_inventory += sprint_buffer if(!on_new) owner?.client?.screen += using diff --git a/code/_onclick/hud/lavaland_elite.dm b/code/_onclick/hud/lavaland_elite.dm index f3ca5fec32..6df374cd10 100644 --- a/code/_onclick/hud/lavaland_elite.dm +++ b/code/_onclick/hud/lavaland_elite.dm @@ -4,13 +4,11 @@ /datum/hud/lavaland_elite/New(mob/living/simple_animal/hostile/asteroid/elite) ..() - pull_icon = new /atom/movable/screen/pull() + pull_icon = new /atom/movable/screen/pull(null, src) pull_icon.icon = ui_style - pull_icon.hud = src pull_icon.update_icon() pull_icon.screen_loc = ui_living_pull static_inventory += pull_icon - healths = new /atom/movable/screen/healths/lavaland_elite() - healths.hud = src + healths = new /atom/movable/screen/healths/lavaland_elite(null, src) infodisplay += healths diff --git a/code/_onclick/hud/monkey.dm b/code/_onclick/hud/monkey.dm index b63f8241cb..ddb5662889 100644 --- a/code/_onclick/hud/monkey.dm +++ b/code/_onclick/hud/monkey.dm @@ -3,48 +3,42 @@ var/atom/movable/screen/using var/atom/movable/screen/inventory/inv_box - action_intent = new /atom/movable/screen/act_intent() + action_intent = new /atom/movable/screen/act_intent(null, src) action_intent.icon = ui_style action_intent.icon_state = mymob.a_intent action_intent.screen_loc = ui_acti - action_intent.hud = src static_inventory += action_intent - using = new /atom/movable/screen/mov_intent() + using = new /atom/movable/screen/mov_intent(null, src) using.icon = ui_style using.icon_state = (mymob.m_intent == MOVE_INTENT_RUN ? "running" : "walking") using.screen_loc = ui_movi - using.hud = src static_inventory += using - using = new/atom/movable/screen/language_menu + using = new/atom/movable/screen/language_menu(null, src) using.icon = ui_style - using.hud = src static_inventory += using - using = new /atom/movable/screen/drop() + using = new /atom/movable/screen/drop(null, src) using.icon = ui_style using.screen_loc = ui_drop_throw - using.hud = src static_inventory += using build_hand_slots() - using = new /atom/movable/screen/swap_hand() + using = new /atom/movable/screen/swap_hand(null, src) using.icon = ui_style using.icon_state = "swap_1_m" //extra wide! using.screen_loc = ui_swaphand_position(owner,1) - using.hud = src static_inventory += using - using = new /atom/movable/screen/swap_hand() + using = new /atom/movable/screen/swap_hand(null, src) using.icon = ui_style using.icon_state = "swap_2" using.screen_loc = ui_swaphand_position(owner,2) - using.hud = src static_inventory += using - inv_box = new /atom/movable/screen/inventory() + inv_box = new /atom/movable/screen/inventory(null, src) inv_box.name = "mask" inv_box.icon = ui_style inv_box.icon_state = "mask" @@ -53,7 +47,7 @@ inv_box.slot_id = ITEM_SLOT_MASK static_inventory += inv_box - inv_box = new /atom/movable/screen/inventory() + inv_box = new /atom/movable/screen/inventory(null, src) inv_box.name = "neck" inv_box.icon = ui_style inv_box.icon_state = "neck" @@ -62,7 +56,7 @@ inv_box.slot_id = ITEM_SLOT_NECK static_inventory += inv_box - inv_box = new /atom/movable/screen/inventory() + inv_box = new /atom/movable/screen/inventory(null, src) inv_box.name = "head" inv_box.icon = ui_style inv_box.icon_state = "head" @@ -71,7 +65,7 @@ inv_box.slot_id = ITEM_SLOT_HEAD static_inventory += inv_box - inv_box = new /atom/movable/screen/inventory() + inv_box = new /atom/movable/screen/inventory(null, src) inv_box.name = "back" inv_box.icon = ui_style inv_box.icon_state = "back" @@ -79,53 +73,41 @@ inv_box.slot_id = ITEM_SLOT_BACK static_inventory += inv_box - throw_icon = new /atom/movable/screen/throw_catch() + throw_icon = new /atom/movable/screen/throw_catch(null, src) throw_icon.icon = ui_style throw_icon.screen_loc = ui_drop_throw - throw_icon.hud = src hotkeybuttons += throw_icon - internals = new /atom/movable/screen/internals() - internals.hud = src - infodisplay += internals - - healths = new /atom/movable/screen/healths() - healths.hud = src + healths = new /atom/movable/screen/healths(null, src) infodisplay += healths - pull_icon = new /atom/movable/screen/pull() + pull_icon = new /atom/movable/screen/pull(null, src) pull_icon.icon = ui_style pull_icon.screen_loc = ui_pull_resist - pull_icon.hud = src pull_icon.update_icon() static_inventory += pull_icon - lingchemdisplay = new /atom/movable/screen/ling/chems() - lingchemdisplay.hud = src + lingchemdisplay = new /atom/movable/screen/ling/chems(null, src) infodisplay += lingchemdisplay - lingstingdisplay = new /atom/movable/screen/ling/sting() - lingstingdisplay.hud = src + lingstingdisplay = new /atom/movable/screen/ling/sting(null, src) infodisplay += lingstingdisplay - zone_select = new /atom/movable/screen/zone_sel() + zone_select = new /atom/movable/screen/zone_sel(null, src) zone_select.icon = ui_style - zone_select.hud = src zone_select.update_icon() static_inventory += zone_select mymob.client.screen = list() - using = new /atom/movable/screen/resist() + using = new /atom/movable/screen/resist(null, src) using.icon = ui_style using.screen_loc = ui_pull_resist - using.hud = src hotkeybuttons += using for(var/atom/movable/screen/inventory/inv in (static_inventory + toggleable_inventory)) if(inv.slot_id) - inv.hud = src inv_slots[TOBITSHIFT(inv.slot_id) + 1] = inv inv.update_icon() diff --git a/code/_onclick/hud/new_player.dm b/code/_onclick/hud/new_player.dm index 539b842375..f1e12bccdd 100644 --- a/code/_onclick/hud/new_player.dm +++ b/code/_onclick/hud/new_player.dm @@ -1,9 +1,12 @@ #define SHUTTER_MOVEMENT_DURATION 0.4 SECONDS #define SHUTTER_WAIT_DURATION 0.2 SECONDS +/// Maximum number of station trait buttons we will display, please think hard before creating scenarios where there are more than this +#define MAX_STATION_TRAIT_BUTTONS_VERTICAL 3 /datum/hud/new_player ///Whether the menu is currently on the client's screen or not var/menu_hud_status = TRUE + var/list/shown_station_trait_buttons /datum/hud/new_player/New(mob/dead/new_player/owner) . = ..() @@ -13,29 +16,89 @@ /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) - var/atom/movable/screen/lobby/lobbyscreen = new button_type(our_hud = src) + for (var/atom/movable/screen/lobby/lobbyscreen as anything in buttons) + if (!initial(lobbyscreen.always_available)) + continue + lobbyscreen = new lobbyscreen(our_hud = src) lobbyscreen.SlowInit() - lobbyscreen.hud = src static_inventory += lobbyscreen if(!lobbyscreen.always_shown) lobbyscreen.RegisterSignal(src, COMSIG_HUD_LOBBY_COLLAPSED, TYPE_PROC_REF(/atom/movable/screen/lobby, collapse_button)) lobbyscreen.RegisterSignal(src, COMSIG_HUD_LOBBY_EXPANDED, TYPE_PROC_REF(/atom/movable/screen/lobby, expand_button)) - if(istype(lobbyscreen, /atom/movable/screen/lobby/button)) - var/atom/movable/screen/lobby/button/lobby_button = lobbyscreen - lobby_button.owner = REF(owner) + + if(owner.client.is_localhost()) + var/atom/movable/screen/lobby/button/start_now/start_button = new(our_hud = src) + start_button.SlowInit() + static_inventory += start_button + start_button.RegisterSignal(src, COMSIG_HUD_LOBBY_COLLAPSED, TYPE_PROC_REF(/atom/movable/screen/lobby, collapse_button)) + start_button.RegisterSignal(src, COMSIG_HUD_LOBBY_EXPANDED, TYPE_PROC_REF(/atom/movable/screen/lobby, expand_button)) + show_hud(hud_version) +/// Load and then display the buttons for relevant station traits +/datum/hud/new_player/proc/show_station_trait_buttons() + var/mob/dead/new_player/user = mymob + if (!user.age_verify()) + return + for (var/datum/station_trait/trait as anything in GLOB.lobby_station_traits) + if (QDELETED(trait) || !trait.can_display_lobby_button(mymob.client)) + remove_station_trait_button(trait) + continue + if(LAZYACCESS(shown_station_trait_buttons, trait)) + continue + var/atom/movable/screen/lobby/button/sign_up/sign_up_button = new(our_hud = src) + trait.setup_lobby_button(sign_up_button) + static_inventory |= sign_up_button + LAZYSET(shown_station_trait_buttons, trait, sign_up_button) + RegisterSignal(trait, COMSIG_PARENT_QDELETING, PROC_REF(remove_station_trait_button)) + + place_station_trait_buttons() + +/// Display the buttosn for relevant station traits. +/datum/hud/new_player/proc/place_station_trait_buttons() + if(hud_version != HUD_STYLE_STANDARD || !mymob?.client) + return + + var/y_offset = 397 + var/x_offset = 233 + var/y_button_offset = 27 + var/x_button_offset = -27 + var/iteration = 0 + for(var/trait in shown_station_trait_buttons) + var/atom/movable/screen/lobby/button/sign_up/sign_up_button = shown_station_trait_buttons[trait] + iteration++ + sign_up_button.screen_loc = offset_to_screen_loc(x_offset, y_offset, mymob.client.view) + mymob.client.screen |= sign_up_button + if (iteration >= MAX_STATION_TRAIT_BUTTONS_VERTICAL) + iteration = 0 + y_offset = 397 + x_offset += x_button_offset + else + y_offset += y_button_offset + +/// Remove a station trait button, then re-order the rest. +/datum/hud/new_player/proc/remove_station_trait_button(datum/station_trait/trait) + SIGNAL_HANDLER + var/atom/movable/screen/lobby/button/sign_up/button = LAZYACCESS(shown_station_trait_buttons, trait) + if(!button) + return + LAZYREMOVE(shown_station_trait_buttons, trait) + UnregisterSignal(trait, COMSIG_PARENT_QDELETING) + static_inventory -= button + qdel(button) + place_station_trait_buttons() + /atom/movable/screen/lobby plane = SPLASHSCREEN_PLANE layer = LOBBY_MENU_LAYER screen_loc = "TOP,CENTER" ///Whether this HUD element can be hidden from the client's "screen" (moved off-screen) or not var/always_shown = FALSE + /// If true we will create this button every time the HUD is generated + var/always_available = TRUE /atom/movable/screen/lobby/New(loc, datum/hud/our_hud, ...) - if(our_hud) - hud = our_hud + set_new_hud(our_hud) return ..() /// Run sleeping actions after initialize @@ -62,15 +125,20 @@ screen_loc = "TOP,CENTER:-61" /atom/movable/screen/lobby/button + mouse_over_pointer = MOUSE_HAND_POINTER ///Is the button currently enabled? - var/enabled = TRUE + VAR_PROTECTED/enabled = TRUE ///Is the button currently being hovered over with the mouse? var/highlighted = FALSE - /// The ref of the mob that owns this button. Only the owner can click on it. - var/owner + ///Should this button play the select sound? + var/select_sound_play = TRUE /atom/movable/screen/lobby/button/Click(location, control, params) - if(owner != REF(usr)) + if(usr != get_mob()) + return + + var/mob/dead/new_player/user = usr + if(!user.age_verify()) return . = ..() @@ -78,11 +146,19 @@ if(!enabled) return flick("[base_icon_state]_pressed", src) + if(select_sound_play) + var/sound/ui_select_sound = sound('sound/misc/menu/ui_select1.ogg') + ui_select_sound.frequency = get_rand_frequency_low_range() + SEND_SOUND(hud.mymob, ui_select_sound) update_appearance(UPDATE_ICON) return TRUE /atom/movable/screen/lobby/button/MouseEntered(location,control,params) - if(owner != REF(usr)) + if(usr != get_mob()) + return + + var/mob/dead/new_player/user = usr + if(!user.age_verify()) return . = ..() @@ -90,7 +166,11 @@ update_appearance(UPDATE_ICON) /atom/movable/screen/lobby/button/MouseExited() - if(owner != REF(usr)) + if(usr != get_mob()) + return + + var/mob/dead/new_player/user = usr + if(!user.age_verify()) return . = ..() @@ -113,6 +193,7 @@ return FALSE enabled = status update_appearance(UPDATE_ICON) + mouse_over_pointer = enabled ? MOUSE_HAND_POINTER : MOUSE_INACTIVE_POINTER return TRUE ///Prefs menu @@ -140,7 +221,7 @@ ///Whether we are readied up for the round or not var/ready = FALSE -/atom/movable/screen/lobby/button/ready/Initialize(mapload) +/atom/movable/screen/lobby/button/ready/Initialize(mapload, datum/hud/hud_owner) . = ..() switch(SSticker.current_state) if(GAME_STATE_PREGAME, GAME_STATE_STARTUP) @@ -176,6 +257,7 @@ new_player.ready = PLAYER_NOT_READY base_icon_state = "not_ready" update_appearance(UPDATE_ICON) + SEND_SIGNAL(hud, COMSIG_HUD_PLAYER_READY_TOGGLE) ///Shown when the game has started /atom/movable/screen/lobby/button/join @@ -184,12 +266,13 @@ icon = 'icons/hud/lobby/join.dmi' icon_state = "" //Default to not visible base_icon_state = "join_game" - enabled = FALSE + enabled = null // set in init -/atom/movable/screen/lobby/button/join/Initialize(mapload) +/atom/movable/screen/lobby/button/join/Initialize(mapload, datum/hud/hud_owner) . = ..() switch(SSticker.current_state) if(GAME_STATE_PREGAME, GAME_STATE_STARTUP) + set_button_status(FALSE) RegisterSignal(SSticker, COMSIG_TICKER_ENTER_SETTING_UP, PROC_REF(show_join_button)) if(GAME_STATE_SETTING_UP) set_button_status(TRUE) @@ -248,13 +331,14 @@ icon = 'icons/hud/lobby/observe.dmi' icon_state = "observe_disabled" base_icon_state = "observe" - enabled = FALSE + enabled = null // set in init -/atom/movable/screen/lobby/button/observe/Initialize(mapload) +/atom/movable/screen/lobby/button/observe/Initialize(mapload, datum/hud/hud_owner) . = ..() if(SSticker.current_state > GAME_STATE_STARTUP) set_button_status(TRUE) else + set_button_status(FALSE) RegisterSignal(SSticker, COMSIG_TICKER_ENTER_PREGAME, PROC_REF(enable_observing)) /atom/movable/screen/lobby/button/observe/Click(location, control, params) @@ -376,6 +460,23 @@ var/mob/dead/new_player/new_player = hud.mymob new_player.handle_player_polling() +/// A generic "sign up" button used by station traits +/atom/movable/screen/lobby/button/sign_up + icon = 'icons/hud/lobby/signup_button.dmi' + icon_state = "signup" + base_icon_state = "signup" + always_available = FALSE + +/atom/movable/screen/lobby/button/sign_up/MouseEntered(location, control, params) + . = ..() + if(QDELETED(src) || !desc) + return + openToolTip(usr, tip_src = src, params = params, title = name, content = desc,) + +/atom/movable/screen/lobby/button/sign_up/MouseExited() + . = ..() + closeToolTip(usr) + /atom/movable/screen/lobby/button/collapse name = "Collapse Lobby Menu" icon = 'icons/hud/lobby/collapse_expand.dmi' @@ -385,6 +486,27 @@ screen_loc = "TOP:-82,CENTER:-54" always_shown = TRUE + var/blip_enabled = TRUE + +/atom/movable/screen/lobby/button/collapse/Initialize(mapload, datum/hud/hud_owner) + . = ..() + switch(SSticker.current_state) + if(GAME_STATE_PREGAME, GAME_STATE_STARTUP) + RegisterSignal(SSticker, COMSIG_TICKER_ENTER_SETTING_UP, PROC_REF(disable_blip)) + RegisterSignal(hud, COMSIG_HUD_PLAYER_READY_TOGGLE, PROC_REF(on_player_ready_toggle)) + if(GAME_STATE_SETTING_UP) + blip_enabled = FALSE + RegisterSignal(SSticker, COMSIG_TICKER_ERROR_SETTING_UP, PROC_REF(enable_blip)) + else + blip_enabled = FALSE + + add_overlay(get_blip_overlay()) + update_icon(UPDATE_OVERLAYS) + +/atom/movable/screen/lobby/button/collapse/update_overlays() + . = ..() + . += get_blip_overlay() + /atom/movable/screen/lobby/button/collapse/Click(location, control, params) . = ..() if(!.) @@ -414,6 +536,38 @@ sleep(2 * SHUTTER_MOVEMENT_DURATION + SHUTTER_WAIT_DURATION) set_button_status(TRUE) +///Proc to update the ready blip state upon new player's ready status change +/atom/movable/screen/lobby/button/collapse/proc/on_player_ready_toggle() + SIGNAL_HANDLER + update_appearance(UPDATE_ICON) + +///Returns a ready blip overlay depending on the player's ready state +/atom/movable/screen/lobby/button/collapse/proc/get_blip_overlay() + var/blip_icon_state = "ready_blip" + if(blip_enabled && hud) + var/mob/dead/new_player/new_player = hud.mymob + blip_icon_state += "_[new_player.ready ? "" : "not_"]ready" + else + blip_icon_state += "_disabled" + var/mutable_appearance/ready_blip = mutable_appearance(icon, blip_icon_state) + return ready_blip + +///Disables the ready blip; makes us listen for the setup error to re-enable the blip +/atom/movable/screen/lobby/button/collapse/proc/disable_blip() + SIGNAL_HANDLER + blip_enabled = FALSE + UnregisterSignal(SSticker, COMSIG_TICKER_ENTER_SETTING_UP) + RegisterSignal(SSticker, COMSIG_TICKER_ERROR_SETTING_UP, PROC_REF(enable_blip)) + update_appearance(UPDATE_ICON) + +///Enables the ready blip; makes us listen for the setup completion and game start to disable the blip +/atom/movable/screen/lobby/button/collapse/proc/enable_blip() + SIGNAL_HANDLER + blip_enabled = TRUE + UnregisterSignal(SSticker, COMSIG_TICKER_ERROR_SETTING_UP) + RegisterSignal(SSticker, COMSIG_TICKER_ENTER_SETTING_UP, PROC_REF(disable_blip)) + update_appearance(UPDATE_ICON) + ///Moves the button to the top of the screen, leaving only the screen part in view ///Sends a signal on the hud for the menu hud elements to listen to /atom/movable/screen/lobby/button/collapse/proc/collapse_menu() @@ -422,12 +576,14 @@ animate(src, transform = transform, time = SHUTTER_MOVEMENT_DURATION + SHUTTER_WAIT_DURATION) //then pull the button up with the shutter and leave it on the edge of the screen animate(transform = transform.Translate(x = 0, y = 134), time = SHUTTER_MOVEMENT_DURATION, easing = CUBIC_EASING|EASE_IN) + SEND_SOUND(hud.mymob, sound('sound/misc/menu/menu_rollup1.ogg')) ///Extends the button back to its usual spot ///Sends a signal on the hud for the menu hud elements to listen to /atom/movable/screen/lobby/button/collapse/proc/expand_menu() SEND_SIGNAL(hud, COMSIG_HUD_LOBBY_EXPANDED) animate(src, transform = matrix(), time = SHUTTER_MOVEMENT_DURATION, easing = CUBIC_EASING|EASE_OUT) + SEND_SOUND(hud.mymob, sound('sound/misc/menu/menu_rolldown1.ogg')) /atom/movable/screen/lobby/shutter icon = 'icons/hud/lobby/shutter.dmi' @@ -448,5 +604,22 @@ //pull the shutter back off-screen animate(transform = matrix(), time = SHUTTER_MOVEMENT_DURATION, easing = CUBIC_EASING|EASE_IN) +/// LOCALHOST ONLY - Start Now button +/atom/movable/screen/lobby/button/start_now + name = "Start Now (LOCALHOST ONLY)" + screen_loc = "TOP:-146,CENTER:-54" + icon = 'icons/hud/lobby/start_now.dmi' + icon_state = "start_now" + base_icon_state = "start_now" + always_available = FALSE + select_sound_play = FALSE + +/atom/movable/screen/lobby/button/start_now/Click(location, control, params) + . = ..() + if(!. || !usr.client.is_localhost() || !check_rights_for(usr.client, R_SERVER)) + return + SEND_SOUND(hud.mymob, sound('sound/effects/splat.ogg', volume = 50)) + SSticker.start_immediately = TRUE + #undef SHUTTER_MOVEMENT_DURATION #undef SHUTTER_WAIT_DURATION diff --git a/code/_onclick/hud/picture_in_picture.dm b/code/_onclick/hud/picture_in_picture.dm index 354a6ed546..2a23a63c50 100644 --- a/code/_onclick/hud/picture_in_picture.dm +++ b/code/_onclick/hud/picture_in_picture.dm @@ -14,7 +14,7 @@ var/mutable_appearance/standard_background var/const/max_dimensions = 10 -/atom/movable/screen/movable/pic_in_pic/Initialize(mapload) +/atom/movable/screen/movable/pic_in_pic/Initialize(mapload, datum/hud/hud_owner) . = ..() make_backgrounds() @@ -55,7 +55,7 @@ add_overlay(move_tab) if(!button_x) - button_x = new /atom/movable/screen/component_button(null, src) + button_x = new /atom/movable/screen/component_button(null, hud, src) var/mutable_appearance/MA = new /mutable_appearance() MA.name = "close" MA.icon = 'icons/misc/pic_in_pic.dmi' @@ -68,7 +68,7 @@ vis_contents += button_x if(!button_expand) - button_expand = new /atom/movable/screen/component_button(null, src) + button_expand = new /atom/movable/screen/component_button(null, hud, src) var/mutable_appearance/MA = new /mutable_appearance() MA.name = "expand" MA.icon = 'icons/misc/pic_in_pic.dmi' @@ -81,7 +81,7 @@ vis_contents += button_expand if(!button_shrink) - button_shrink = new /atom/movable/screen/component_button(null, src) + button_shrink = new /atom/movable/screen/component_button(null, hud, src) var/mutable_appearance/MA = new /mutable_appearance() MA.name = "shrink" MA.icon = 'icons/misc/pic_in_pic.dmi' diff --git a/code/_onclick/hud/plane_master.dm b/code/_onclick/hud/plane_master.dm index a32209eba3..366fa2fa95 100644 --- a/code/_onclick/hud/plane_master.dm +++ b/code/_onclick/hud/plane_master.dm @@ -24,7 +24,7 @@ blend_mode = BLEND_MULTIPLY alpha = 255 -/atom/movable/screen/plane_master/openspace/Initialize(mapload) +/atom/movable/screen/plane_master/openspace/Initialize(mapload, datum/hud/hud_owner) . = ..() filters += filter(type="alpha", render_source=FIELD_OF_VISION_RENDER_TARGET, flags=MASK_INVERSE) filters += filter(type="alpha", render_source = LIGHTING_RENDER_TARGET, flags = MASK_INVERSE) @@ -61,7 +61,7 @@ plane = ABOVE_WALL_PLANE appearance_flags = PLANE_MASTER -/atom/movable/screen/plane_master/above_wall/Initialize(mapload) +/atom/movable/screen/plane_master/above_wall/Initialize(mapload, datum/hud/hud_owner) . = ..() add_filter("vision_cone", 100, list(type="alpha", render_source=FIELD_OF_VISION_RENDER_TARGET, flags=MASK_INVERSE)) @@ -78,7 +78,7 @@ appearance_flags = PLANE_MASTER //should use client color blend_mode = BLEND_OVERLAY -/atom/movable/screen/plane_master/game_world/Initialize(mapload) +/atom/movable/screen/plane_master/game_world/Initialize(mapload, datum/hud/hud_owner) . = ..() add_filter("vision_cone", 100, list(type="alpha", render_source=FIELD_OF_VISION_RENDER_TARGET, flags=MASK_INVERSE)) @@ -95,7 +95,7 @@ render_target = FIELD_OF_VISION_RENDER_TARGET mouse_opacity = MOUSE_OPACITY_TRANSPARENT -/atom/movable/screen/plane_master/field_of_vision/Initialize(mapload) +/atom/movable/screen/plane_master/field_of_vision/Initialize(mapload, datum/hud/hud_owner) . = ..() filters += filter(type="alpha", render_source=FIELD_OF_VISION_BLOCKER_RENDER_TARGET, flags=MASK_INVERSE) @@ -112,7 +112,7 @@ plane = FIELD_OF_VISION_VISUAL_PLANE mouse_opacity = MOUSE_OPACITY_TRANSPARENT -/atom/movable/screen/plane_master/field_of_vision_visual/Initialize(mapload) +/atom/movable/screen/plane_master/field_of_vision_visual/Initialize(mapload, datum/hud/hud_owner) . = ..() filters += filter(type="alpha", render_source=FIELD_OF_VISION_BLOCKER_RENDER_TARGET, flags=MASK_INVERSE) @@ -138,7 +138,7 @@ * This is then used to alpha mask the lighting plane. */ -/atom/movable/screen/plane_master/lighting/Initialize(mapload) +/atom/movable/screen/plane_master/lighting/Initialize(mapload, datum/hud/hud_owner) . = ..() add_filter("emissives", 1, alpha_mask_filter(render_source = EMISSIVE_RENDER_TARGET, flags = MASK_INVERSE)) add_filter("object_lighting", 2, alpha_mask_filter(render_source = O_LIGHTING_VISUAL_RENDER_TARGET, flags = MASK_INVERSE)) @@ -152,7 +152,7 @@ mouse_opacity = MOUSE_OPACITY_TRANSPARENT render_target = EMISSIVE_RENDER_TARGET -/atom/movable/screen/plane_master/emissive/Initialize(mapload) +/atom/movable/screen/plane_master/emissive/Initialize(mapload, datum/hud/hud_owner) . = ..() add_filter("em_block_masking", 1, color_matrix_filter(GLOB.em_mask_matrix)) diff --git a/code/_onclick/hud/plane_master_controller.dm b/code/_onclick/hud/plane_master_controller.dm index e27bd3bc55..c2ec1417b2 100644 --- a/code/_onclick/hud/plane_master_controller.dm +++ b/code/_onclick/hud/plane_master_controller.dm @@ -5,8 +5,11 @@ ///hud that owns this controller var/datum/hud/owner_hud + +INITIALIZE_IMMEDIATE(/atom/movable/plane_master_controller) + ///Ensures that all the planes are correctly in the controlled_planes list. -/atom/movable/plane_master_controller/New(hud) +/atom/movable/plane_master_controller/Initialize(mapload, datum/hud/hud) . = ..() owner_hud = hud var/assoc_controlled_planes = list() diff --git a/code/_onclick/hud/radial_persistent.dm b/code/_onclick/hud/radial_persistent.dm index e7f7c664ad..b5fa494c94 100644 --- a/code/_onclick/hud/radial_persistent.dm +++ b/code/_onclick/hud/radial_persistent.dm @@ -7,8 +7,8 @@ icon_state = "radial_center" /atom/movable/screen/radial/persistent/center/Click(location, control, params) - if(usr.client == parent.current_user) - parent.element_chosen(null,usr) + if(usr == get_mob()) + parent.element_chosen(null, usr) /atom/movable/screen/radial/persistent/center/MouseEntered(location, control, params) . = ..() diff --git a/code/_onclick/hud/revenanthud.dm b/code/_onclick/hud/revenanthud.dm index 708b1d4915..a98ef60a1a 100644 --- a/code/_onclick/hud/revenanthud.dm +++ b/code/_onclick/hud/revenanthud.dm @@ -2,6 +2,5 @@ /datum/hud/revenant/New(mob/owner) ..() - healths = new /atom/movable/screen/healths/revenant() - healths.hud = src + healths = new /atom/movable/screen/healths/revenant(null, src) infodisplay += healths diff --git a/code/_onclick/hud/robot.dm b/code/_onclick/hud/robot.dm index 899ad72f2f..839ae4b9fa 100644 --- a/code/_onclick/hud/robot.dm +++ b/code/_onclick/hud/robot.dm @@ -1,5 +1,6 @@ /atom/movable/screen/robot icon = 'icons/mob/screen_cyborg.dmi' + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/robot/module name = "cyborg module" @@ -77,64 +78,56 @@ var/mob/living/silicon/robot/robit = mymob var/atom/movable/screen/using - using = new/atom/movable/screen/language_menu + using = new/atom/movable/screen/language_menu(null, src) using.screen_loc = ui_borg_language_menu static_inventory += using //Radio - using = new /atom/movable/screen/robot/radio() + using = new /atom/movable/screen/robot/radio(null, src) using.screen_loc = ui_borg_radio - using.hud = src static_inventory += using //Module select if(!robit.inv1) - robit.inv1 = new /atom/movable/screen/robot/module1() + robit.inv1 = new /atom/movable/screen/robot/module1(null, src) robit.inv1.screen_loc = ui_inv1 - robit.inv1.hud = src static_inventory += robit.inv1 if(!robit.inv2) - robit.inv2 = new /atom/movable/screen/robot/module2() + robit.inv2 = new /atom/movable/screen/robot/module2(null, src) robit.inv2.screen_loc = ui_inv2 - robit.inv2.hud = src static_inventory += robit.inv2 if(!robit.inv3) - robit.inv3 = new /atom/movable/screen/robot/module3() + robit.inv3 = new /atom/movable/screen/robot/module3(null, src) robit.inv3.screen_loc = ui_inv3 - robit.inv3.hud = src static_inventory += robit.inv3 //End of module select - using = new /atom/movable/screen/robot/lamp() + using = new /atom/movable/screen/robot/lamp(null, src) using.screen_loc = ui_borg_lamp - using.hud = src static_inventory += using robit.lampButton = using var/atom/movable/screen/robot/lamp/lampscreen = using lampscreen.robot = robit //Photography stuff - using = new /atom/movable/screen/ai/image_take() + using = new /atom/movable/screen/ai/image_take(null, src) using.screen_loc = ui_borg_camera - using.hud = src static_inventory += using //Sec/Med HUDs - using = new /atom/movable/screen/robot/sensors() + using = new /atom/movable/screen/robot/sensors(null, src) using.screen_loc = ui_borg_sensor - using.hud = src static_inventory += using //Borg Integrated Tablet - using = new /atom/movable/screen/robot/modPC() + using = new /atom/movable/screen/robot/modPC(null, src) using.screen_loc = ui_borg_tablet - using.hud = src static_inventory += using robit.interfaceButton = using if(robit.modularInterface) @@ -143,64 +136,54 @@ tabletbutton.robot = robit //Alerts - using = new /atom/movable/screen/robot/alerts() + using = new /atom/movable/screen/robot/alerts(null, src) using.screen_loc = ui_borg_alerts - using.hud = src static_inventory += using //Thrusters - using = new /atom/movable/screen/robot/thrusters() + using = new /atom/movable/screen/robot/thrusters(null, src) using.screen_loc = ui_borg_thrusters - using.hud = src static_inventory += using robit.thruster_button = using //PDA message - using = new /atom/movable/screen/robot/pda_msg_send + using = new /atom/movable/screen/robot/pda_msg_send(null, src) using.screen_loc = ui_borg_pda_send - using.hud = src static_inventory += using //PDA log - using = new /atom/movable/screen/robot/pda_msg_show + using = new /atom/movable/screen/robot/pda_msg_show(null, src) using.screen_loc = ui_borg_pda_log - using.hud = src static_inventory += using //Intent - action_intent = new /atom/movable/screen/act_intent/robot() + action_intent = new /atom/movable/screen/act_intent/robot(null, src) action_intent.icon_state = mymob.a_intent - action_intent.hud = src static_inventory += action_intent assert_move_intent_ui(owner, TRUE) //Health - healths = new /atom/movable/screen/healths/robot() - healths.hud = src + healths = new /atom/movable/screen/healths/robot(null, src) infodisplay += healths //Installed Module - robit.hands = new /atom/movable/screen/robot/module() + robit.hands = new /atom/movable/screen/robot/module(null, src) robit.hands.screen_loc = ui_borg_module - robit.hands.hud = src static_inventory += robit.hands //Store - module_store_icon = new /atom/movable/screen/robot/store() + module_store_icon = new /atom/movable/screen/robot/store(null, src) module_store_icon.screen_loc = ui_borg_store - module_store_icon.hud = src - pull_icon = new /atom/movable/screen/pull() + pull_icon = new /atom/movable/screen/pull(null, src) pull_icon.icon = 'icons/mob/screen_cyborg.dmi' pull_icon.screen_loc = ui_borg_pull - pull_icon.hud = src pull_icon.update_icon() hotkeybuttons += pull_icon - zone_select = new /atom/movable/screen/zone_sel/robot() - zone_select.hud = src + zone_select = new /atom/movable/screen/zone_sel/robot(null, src) zone_select.update_icon() static_inventory += zone_select @@ -221,7 +204,6 @@ using = new /atom/movable/screen/mov_intent using.icon = 'modular_citadel/icons/ui/screen_cyborg.dmi' using.screen_loc = ui_borg_movi - using.hud = src using.update_icon() static_inventory += using if(!on_new) @@ -235,7 +217,6 @@ using.icon = 'modular_citadel/icons/ui/screen_cyborg.dmi' using.icon_state = owner.cansprint ? ((owner.combat_flags & COMBAT_FLAG_SPRINT_ACTIVE) ? "act_sprint_on" : "act_sprint") : "act_sprint_locked" using.screen_loc = ui_borg_movi - using.hud = src static_inventory += using if(!on_new) owner?.client?.screen += using diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index c0d500511f..d964d418ae 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -17,7 +17,7 @@ /// A reference to the object in the slot. Grabs or items, generally. var/obj/master = null /// A reference to the owner HUD, if any. - var/datum/hud/hud = null + VAR_PRIVATE/datum/hud/hud = null /** * Map name assigned to this object. * Automatically set by /client/proc/add_obj_to_map. @@ -31,12 +31,36 @@ * But for now, this works. */ var/del_on_map_removal = TRUE + /// If FALSE, this will not be cleared when calling /client/clear_screen() + // var/clear_with_screen = TRUE // Unimplemented + /// If TRUE, clicking the screen element will fall through and perform a default "Click" call + /// Obviously this requires your Click override, if any, to call parent on their own. + /// This is set to FALSE to default to dissade you from doing this. + /// Generally we don't want default Click stuff, which results in bugs like using Telekinesis on a screen element + /// or trying to point your gun at your screen. + var/default_click = FALSE + +/atom/movable/screen/Initialize(mapload, datum/hud/hud_owner) + . = ..() + if(isnull(hud_owner)) //some screens set their hud owners on /new, this prevents overriding them with null post atoms init + return + set_new_hud(hud_owner) /atom/movable/screen/Destroy() master = null hud = null return ..() +/atom/movable/screen/Click(location, control, params) + if(flags_1 & INITIALIZED_1) + SEND_SIGNAL(src, COMSIG_SCREEN_ELEMENT_CLICK, location, control, params, usr) + if(default_click) + return ..() + +///Screen elements are always on top of the players screen and don't move so yes they are adjacent +/atom/movable/screen/Adjacent(atom/neighbor, atom/target, atom/movable/mover) + return TRUE + /atom/movable/screen/examine(mob/user) return list() @@ -46,6 +70,26 @@ /atom/movable/screen/proc/component_click(atom/movable/screen/component_button/component, params) return +///setter used to set our new hud +/atom/movable/screen/proc/set_new_hud(datum/hud/hud_owner) + if(hud) + UnregisterSignal(hud, COMSIG_PARENT_QDELETING) + if(isnull(hud_owner)) + hud = null + return + hud = hud_owner + RegisterSignal(hud, COMSIG_PARENT_QDELETING, PROC_REF(on_hud_delete)) + +/// Returns the mob this is being displayed to, if any +/atom/movable/screen/proc/get_mob() + RETURN_TYPE(/mob) + return hud?.mymob + +/atom/movable/screen/proc/on_hud_delete(datum/source) + SIGNAL_HANDLER + + set_new_hud(hud_owner = null) + /atom/movable/screen/text icon = null icon_state = null @@ -57,6 +101,7 @@ /atom/movable/screen/swap_hand plane = HUD_PLANE name = "swap hand" + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/swap_hand/Click() // At this point in client Click() code we have passed the 1/10 sec check and little else @@ -85,12 +130,14 @@ icon = 'icons/mob/screen_midnight.dmi' icon_state = "craft" screen_loc = ui_crafting + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/area_creator name = "create new area" icon = 'icons/mob/screen_midnight.dmi' icon_state = "area_edit" screen_loc = ui_building + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/area_creator/Click() if(usr.incapacitated() || (isobserver(usr) && !IsAdminGhost(usr))) @@ -106,11 +153,10 @@ icon = 'icons/mob/screen_midnight.dmi' icon_state = "talk_wheel" screen_loc = ui_language_menu + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/language_menu/Click() - var/mob/M = usr - var/datum/language_holder/H = M.get_language_holder() - H.open_language_menu(usr) + hud.mymob.get_language_holder().open_language_menu(hud.mymob) /atom/movable/screen/inventory /// The identifier for the slot. It has nothing to do with ID cards. @@ -172,7 +218,7 @@ var/image/item_overlay = image(holding) item_overlay.alpha = 92 - if(!user.can_equip(holding, slot_id, disable_warning = TRUE, bypass_equip_delay_self = TRUE)) + if(!holding.mob_can_equip(user, user, slot_id, disable_warning = TRUE, bypass_equip_delay_self = TRUE)) item_overlay.color = "#FF0000" else item_overlay.color = "#00ff00" @@ -233,7 +279,7 @@ // plane = ABOVE_HUD_PLANE // icon_state = "backpack_close" -// /atom/movable/screen/close/Initialize(mapload, new_master) +// /atom/movable/screen/close/Initialize(mapload, datum/hud/hud_owner, new_master) // . = ..() // master = new_master @@ -247,6 +293,7 @@ icon = 'icons/mob/screen_midnight.dmi' icon_state = "act_drop" plane = HUD_PLANE + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/drop/Click() if(usr.stat == CONSCIOUS) @@ -256,28 +303,39 @@ name = "intent" icon_state = "help" screen_loc = ui_acti + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/act_intent/Click(location, control, params) - usr.a_intent_change(INTENT_HOTKEY_RIGHT) + hud.mymob.a_intent_change(INTENT_HOTKEY_RIGHT) + +/atom/movable/screen/act_intent/update_icon_state() + icon_state = hud.mymob.a_intent || initial(icon_state) + +/atom/movable/screen/act_intent/segmented + base_icon_state = "intent" /atom/movable/screen/act_intent/segmented/Click(location, control, params) - if(usr.client.prefs.toggles & INTENT_STYLE) - var/_x = text2num(params2list(params)["icon-x"]) - var/_y = text2num(params2list(params)["icon-y"]) - - if(_x<=16 && _y<=16) - usr.a_intent_change(INTENT_HARM) - - else if(_x<=16 && _y>=17) - usr.a_intent_change(INTENT_HELP) - - else if(_x>=17 && _y<=16) - usr.a_intent_change(INTENT_GRAB) - - else if(_x>=17 && _y>=17) - usr.a_intent_change(INTENT_DISARM) - else + if(!(hud.mymob?.client.prefs.toggles & INTENT_STYLE)) return ..() + var/_x = text2num(params2list(params)["icon-x"]) + var/_y = text2num(params2list(params)["icon-y"]) + + if(_x<=16 && _y<=16) + usr.a_intent_change(INTENT_HARM) + + else if(_x<=16 && _y>=17) + usr.a_intent_change(INTENT_HELP) + + else if(_x>=17 && _y<=16) + usr.a_intent_change(INTENT_GRAB) + + else if(_x>=17 && _y>=17) + usr.a_intent_change(INTENT_DISARM) + + update_icon() + +/atom/movable/screen/act_intent/segmented/update_icon_state() + icon_state = "[base_icon_state]_[hud.mymob.a_intent]" /atom/movable/screen/act_intent/alien icon = 'icons/mob/screen_alien.dmi' @@ -287,78 +345,13 @@ icon = 'icons/mob/screen_cyborg.dmi' screen_loc = ui_borg_intents -/atom/movable/screen/internals - name = "toggle internals" - icon_state = "internal0" - screen_loc = ui_internal - -/atom/movable/screen/internals/Click() - if(!iscarbon(usr)) - return - var/mob/living/carbon/C = usr - if(C.incapacitated()) - return - - if(C.internal) - C.internal = null - to_chat(C, span_notice("You are no longer running on internals.")) - icon_state = "internal0" - else - if(!C.getorganslot(ORGAN_SLOT_BREATHING_TUBE)) - if(HAS_TRAIT(C, TRAIT_NO_INTERNALS)) - to_chat(C, span_warning("Due to cumbersome equipment or anatomy, you are currently unable to use internals!")) - return - var/obj/item/clothing/check - var/internals = FALSE - - for(check in GET_INTERNAL_SLOTS(C)) - if(istype(check, /obj/item/clothing/mask)) - var/obj/item/clothing/mask/M = check - if(M.mask_adjusted) - M.adjustmask(C) - if((check.clothing_flags & ALLOWINTERNALS)) - internals = TRUE - if(!internals) - to_chat(C, span_warning("You are not wearing an internals mask!")) - return - - var/obj/item/I = C.is_holding_item_of_type(/obj/item/tank) - if(I) - to_chat(C, span_notice("You are now running on internals from [I] in your [C.get_held_index_name(C.get_held_index_of_item(I))].")) - C.internal = I - else if(ishuman(C)) - var/mob/living/carbon/human/H = C - if(istype(H.s_store, /obj/item/tank)) - to_chat(H, span_notice("You are now running on internals from [H.s_store] on your [H.wear_suit.name].")) - H.internal = H.s_store - else if(istype(H.belt, /obj/item/tank)) - to_chat(H, span_notice("You are now running on internals from [H.belt] on your belt.")) - H.internal = H.belt - else if(istype(H.l_store, /obj/item/tank)) - to_chat(H, span_notice("You are now running on internals from [H.l_store] in your left pocket.")) - H.internal = H.l_store - else if(istype(H.r_store, /obj/item/tank)) - to_chat(H, span_notice("You are now running on internals from [H.r_store] in your right pocket.")) - H.internal = H.r_store - - //Separate so CO2 jetpacks are a little less cumbersome. - if(!C.internal && istype(C.back, /obj/item/tank)) - to_chat(C, span_notice("You are now running on internals from [C.back] on your back.")) - C.internal = C.back - - if(C.internal) - icon_state = "internal1" - else - to_chat(C, span_warning("You don't have an oxygen tank!")) - return - C.update_action_buttons_icon() - /atom/movable/screen/mov_intent name = "run/walk toggle" icon = 'icons/mob/screen_midnight.dmi' icon_state = "running" + mouse_over_pointer = MOUSE_HAND_POINTER -/atom/movable/screen/mov_intent/Initialize(mapload) +/atom/movable/screen/mov_intent/Initialize(mapload, datum/hud/hud_owner) . = ..() update_icon() @@ -366,7 +359,10 @@ toggle(usr) /atom/movable/screen/mov_intent/update_icon_state() - switch(hud?.mymob?.m_intent) + if(!hud || !hud.mymob || !isliving(hud.mymob)) + return + var/mob/living/living_hud_owner = hud.mymob + switch(living_hud_owner.m_intent) if(MOVE_INTENT_WALK) icon_state = CONFIG_GET(flag/sprint_enabled)? "walking" : "walking_nosprint" if(MOVE_INTENT_RUN) @@ -382,6 +378,8 @@ name = "stop pulling" icon = 'icons/mob/screen_midnight.dmi' icon_state = "pull" + base_icon_state = "pull" + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/pull/Click() if(isobserver(usr)) @@ -389,17 +387,14 @@ usr.stop_pulling() /atom/movable/screen/pull/update_icon_state() - if(hud?.mymob?.pulling) - icon_state = "pull" - else - icon_state = "pull0" + icon_state = "[base_icon_state][hud?.mymob?.pulling ? null : 0]" return ..() /atom/movable/screen/resist name = "resist" icon = 'icons/mob/screen_midnight.dmi' icon_state = "act_resist" - plane = HUD_PLANE + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/resist/Click() if(isliving(usr)) @@ -411,7 +406,7 @@ icon = 'icons/mob/screen_midnight.dmi' icon_state = "act_rest" base_icon_state = "act_rest" - plane = HUD_PLANE + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/rest/Click() if(isliving(usr)) @@ -429,6 +424,7 @@ name = "throw/catch" icon = 'icons/mob/screen_midnight.dmi' icon_state = "act_throw_off" + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/throw_catch/Click() if(iscarbon(usr)) @@ -439,10 +435,15 @@ name = "damage zone" icon_state = "zone_sel" screen_loc = ui_zonesel + mouse_over_pointer = MOUSE_HAND_POINTER var/overlay_icon = 'icons/mob/screen_gen.dmi' - var/static/list/hover_overlays_cache = list() + var/list/hover_overlays_cache = list() var/hovering +/atom/movable/screen/zone_sel/Destroy() + QDEL_LIST_ASSOC_VAL(hover_overlays_cache) + return ..() + /atom/movable/screen/zone_sel/Click(location, control,params) if(isobserver(usr)) return @@ -641,6 +642,7 @@ /atom/movable/screen/healthdoll name = "health doll" screen_loc = ui_healthdoll + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/healthdoll/Click() if (iscarbon(usr)) @@ -656,6 +658,7 @@ name = "mood" icon_state = "mood5" screen_loc = ui_mood + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/mood/attack_tk() return @@ -668,7 +671,9 @@ plane = SPLASHSCREEN_PLANE var/client/holder -/atom/movable/screen/splash/New(client/C, visible, use_previous_title) //TODO: Make this use INITIALIZE_IMMEDIATE, except its not easy +INITIALIZE_IMMEDIATE(/atom/movable/screen/splash) + +/atom/movable/screen/splash/Initialize(mapload, datum/hud/hud_owner, client/C, visible, use_previous_title) . = ..() if(!istype(C)) return @@ -683,8 +688,7 @@ icon = SStitle.icon else if(!SStitle.previous_icon) - qdel(src) - return + return INITIALIZE_HINT_QDEL icon = SStitle.previous_icon holder.screen += src @@ -708,9 +712,10 @@ /atom/movable/screen/component_button + mouse_over_pointer = MOUSE_HAND_POINTER var/atom/movable/screen/parent -/atom/movable/screen/component_button/Initialize(mapload, atom/movable/screen/parent) +/atom/movable/screen/component_button/Initialize(mapload, datum/hud/hud_owner, atom/movable/screen/parent) . = ..() src.parent = parent diff --git a/code/_onclick/hud/screen_objects/clickdelay.dm b/code/_onclick/hud/screen_objects/clickdelay.dm index b8258c7598..dc6c3e0da7 100644 --- a/code/_onclick/hud/screen_objects/clickdelay.dm +++ b/code/_onclick/hud/screen_objects/clickdelay.dm @@ -25,7 +25,7 @@ icon_state = "prog_bar_100" layer = 20 // under hand buttons -/atom/movable/screen/action_bar/clickdelay/Initialize(mapload) +/atom/movable/screen/action_bar/clickdelay/Initialize(mapload, datum/hud/hud_owner) . = ..() var/matrix/M = new M.Scale(2, 1) diff --git a/code/_onclick/hud/screen_objects/sprint.dm b/code/_onclick/hud/screen_objects/sprint.dm index b32973f2dd..1a655a4db6 100644 --- a/code/_onclick/hud/screen_objects/sprint.dm +++ b/code/_onclick/hud/screen_objects/sprint.dm @@ -5,7 +5,7 @@ name = "toggle sprint" icon = 'modular_citadel/icons/ui/screen_midnight.dmi' icon_state = "act_sprint" - layer = ABOVE_HUD_LAYER - 0.1 + mouse_over_pointer = MOUSE_HAND_POINTER var/mutable_appearance/flashy /atom/movable/screen/sprintbutton/Click() @@ -44,6 +44,7 @@ name = "sprint buffer" icon = 'icons/effects/progessbar.dmi' icon_state = "prog_bar_100" + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/sprint_buffer/Click() if(isliving(usr)) diff --git a/code/_onclick/hud/screen_objects/stamina.dm b/code/_onclick/hud/screen_objects/stamina.dm index b4c4807ec8..b711e22084 100644 --- a/code/_onclick/hud/screen_objects/stamina.dm +++ b/code/_onclick/hud/screen_objects/stamina.dm @@ -1,19 +1,20 @@ -/datum/hud/var/atom/movable/screen/staminas/staminas -/datum/hud/var/atom/movable/screen/staminabuffer/staminabuffer +/datum/hud + var/atom/movable/screen/staminas/staminas + var/atom/movable/screen/staminabuffer/staminabuffer /atom/movable/screen/staminas icon = 'modular_citadel/icons/ui/screen_gen.dmi' name = "stamina" icon_state = "stamina0" screen_loc = ui_stamina - mouse_opacity = 1 + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/staminas/Click(location,control,params) if(isliving(usr)) var/mob/living/L = usr CONFIG_CACHE_ENTRY_AND_FETCH_VALUE(number/stamina_combat/buffer_max, buffer_max) - to_chat(L, "You have [L.getStaminaLoss()] stamina loss.
\ -
Your stamina buffer is [round((L.stamina_buffer / buffer_max) * 100, 0.1)]% full.
") + to_chat(L, examine_block(span_notice("You have [L.getStaminaLoss()] stamina loss.
\ +
Your stamina buffer is [round((L.stamina_buffer / buffer_max) * 100, 0.1)]% full."))) /atom/movable/screen/staminas/update_icon_state() var/mob/living/carbon/user = hud?.mymob diff --git a/code/_onclick/hud/screen_objects/storage.dm b/code/_onclick/hud/screen_objects/storage.dm index d77e4e03ed..a3657a50d3 100644 --- a/code/_onclick/hud/screen_objects/storage.dm +++ b/code/_onclick/hud/screen_objects/storage.dm @@ -2,14 +2,14 @@ name = "storage" var/insertion_click = FALSE -/atom/movable/screen/storage/Initialize(mapload, new_master) +/atom/movable/screen/storage/Initialize(mapload, datum/hud/hud_owner, new_master) . = ..() master = new_master /atom/movable/screen/storage/Click(location, control, params) if(!insertion_click) return ..() - if(hud?.mymob && (hud.mymob != usr)) + if(get_mob() != usr) return // just redirect clicks if(master) @@ -55,7 +55,7 @@ plane = VOLUMETRIC_STORAGE_BOX_PLANE var/obj/item/our_item -/atom/movable/screen/storage/volumetric_box/Initialize(mapload, new_master, obj/item/our_item) +/atom/movable/screen/storage/volumetric_box/Initialize(mapload, datum/hud/hud_owner, new_master, obj/item/our_item) src.our_item = our_item RegisterSignal(our_item, COMSIG_ITEM_MOUSE_ENTER, PROC_REF(on_item_mouse_enter)) RegisterSignal(our_item, COMSIG_ITEM_MOUSE_EXIT, PROC_REF(on_item_mouse_exit)) @@ -97,9 +97,9 @@ var/atom/movable/screen/storage/item_holder/holder var/pixel_size -/atom/movable/screen/storage/volumetric_box/center/Initialize(mapload, new_master, our_item) - left = new(null, src, our_item) - right = new(null, src, our_item) +/atom/movable/screen/storage/volumetric_box/center/Initialize(mapload, datum/hud/hud_owner, new_master, our_item) + left = new(null, hud_owner, src, our_item) + right = new(null, hud_owner, src, our_item) return ..() /atom/movable/screen/storage/volumetric_box/center/Destroy() @@ -116,7 +116,7 @@ /** * Sets the size of this box screen object and regenerates its left/right borders. This includes the actual border's size! */ -/atom/movable/screen/storage/volumetric_box/center/proc/set_pixel_size(pixels) +/atom/movable/screen/storage/volumetric_box/center/proc/set_pixel_size(pixels, datum/hud/hud) if(pixel_size == pixels) return pixel_size = pixels @@ -128,7 +128,7 @@ if(our_item) if(holder) qdel(holder) - holder = new(null, src, our_item) + holder = new(null, hud, src, our_item) holder.transform = matrix(1 / multiplier, 0, 0, 0, 1, 0) holder.mouse_opacity = MOUSE_OPACITY_TRANSPARENT holder.appearance_flags &= ~RESET_TRANSFORM @@ -155,7 +155,7 @@ layer = VOLUMETRIC_STORAGE_BOX_LAYER plane = VOLUMETRIC_STORAGE_BOX_PLANE -/atom/movable/screen/storage/volumetric_edge/Initialize(mapload, master, our_item) +/atom/movable/screen/storage/volumetric_edge/Initialize(mapload, datum/hud/hud_owner, master, our_item) src.master = master return ..() @@ -183,7 +183,7 @@ var/obj/item/our_item vis_flags = NONE -/atom/movable/screen/storage/item_holder/Initialize(mapload, new_master, obj/item/I) +/atom/movable/screen/storage/item_holder/Initialize(mapload, datum/hud/hud_owner, new_master, obj/item/I) . = ..() our_item = I vis_contents += I diff --git a/code/_onclick/hud/screen_objects/vore.dm b/code/_onclick/hud/screen_objects/vore.dm index 91aa8f318c..1eea40f565 100644 --- a/code/_onclick/hud/screen_objects/vore.dm +++ b/code/_onclick/hud/screen_objects/vore.dm @@ -2,6 +2,7 @@ name = "toggle vore mode" icon = 'modular_citadel/icons/ui/screen_midnight.dmi' icon_state = "nom_off" + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/voretoggle/Click() if(usr != hud.mymob) diff --git a/code/_onclick/hud/screentip.dm b/code/_onclick/hud/screentip.dm index b9b27072b3..beb705133b 100644 --- a/code/_onclick/hud/screentip.dm +++ b/code/_onclick/hud/screentip.dm @@ -8,9 +8,8 @@ maptext = "" layer = SCREENTIP_LAYER -/atom/movable/screen/screentip/Initialize(mapload, _hud) +/atom/movable/screen/screentip/Initialize(mapload, datum/hud/hud_owner) . = ..() - hud = _hud update_view() /atom/movable/screen/screentip/proc/update_view(datum/source) diff --git a/code/_onclick/hud/simple_animal.dm b/code/_onclick/hud/simple_animal.dm index 2f7902c965..3549bc38fb 100644 --- a/code/_onclick/hud/simple_animal.dm +++ b/code/_onclick/hud/simple_animal.dm @@ -1,15 +1,14 @@ /datum/hud/living/simple_animal ui_style = 'icons/mob/screen_gen.dmi' + /datum/hud/living/simple_animal/New(mob/living/owner) ..() - pull_icon = new /atom/movable/screen/pull() + pull_icon = new /atom/movable/screen/pull(null, src) pull_icon.icon = ui_style pull_icon.update_icon() pull_icon.screen_loc = ui_living_pull - pull_icon.hud = src static_inventory += pull_icon //mob health doll! assumes whatever sprite the mob is - healthdoll = new /atom/movable/screen/healthdoll/living() - healthdoll.hud = src + healthdoll = new /atom/movable/screen/healthdoll/living(null, src) infodisplay += healthdoll diff --git a/code/_onclick/hud/swarmer.dm b/code/_onclick/hud/swarmer.dm index 6aba23fab5..ca0cbc458a 100644 --- a/code/_onclick/hud/swarmer.dm +++ b/code/_onclick/hud/swarmer.dm @@ -67,32 +67,26 @@ ..() var/atom/movable/screen/using - using = new /atom/movable/screen/swarmer/FabricateTrap() + using = new /atom/movable/screen/swarmer/FabricateTrap(null, src) using.screen_loc = ui_hand_position(2) - using.hud = src static_inventory += using - using = new /atom/movable/screen/swarmer/Barricade() + using = new /atom/movable/screen/swarmer/Barricade(null, src) using.screen_loc = ui_hand_position(1) - using.hud = src static_inventory += using - using = new /atom/movable/screen/swarmer/Replicate() + using = new /atom/movable/screen/swarmer/Replicate(null, src) using.screen_loc = ui_zonesel - using.hud = src static_inventory += using - using = new /atom/movable/screen/swarmer/RepairSelf() + using = new /atom/movable/screen/swarmer/RepairSelf(null, src) using.screen_loc = ui_storage1 - using.hud = src static_inventory += using - using = new /atom/movable/screen/swarmer/ToggleLight() + using = new /atom/movable/screen/swarmer/ToggleLight(null, src) using.screen_loc = ui_back - using.hud = src static_inventory += using - using = new /atom/movable/screen/swarmer/ContactSwarmers() + using = new /atom/movable/screen/swarmer/ContactSwarmers(null, src) using.screen_loc = ui_inventory - using.hud = src static_inventory += using diff --git a/code/controllers/subsystem/processing/station.dm b/code/controllers/subsystem/processing/station.dm index f812ea8c4a..c4cdfb11b4 100644 --- a/code/controllers/subsystem/processing/station.dm +++ b/code/controllers/subsystem/processing/station.dm @@ -77,8 +77,17 @@ PROCESSING_SUBSYSTEM_DEF(station) var/datum/station_trait/trait_instance = new trait_type() can_fire = can_fire || trait_instance.trait_processes station_traits += trait_instance + log_game("Station Trait: [trait_instance.name] chosen for this round.") if(!trait_instance.blacklist) return for(var/i in trait_instance.blacklist) var/datum/station_trait/trait_to_remove = i selectable_traits_by_types[initial(trait_to_remove.trait_type)] -= trait_to_remove + +/// Update station trait lobby buttons for clients who joined before we initialised this subsystem +/datum/controller/subsystem/processing/station/proc/display_lobby_traits() + for (var/mob/dead/new_player/player as anything in GLOB.new_player_list) + var/datum/hud/new_player/observer_hud = player.hud_used + if (!istype(observer_hud)) + continue + observer_hud.show_station_trait_buttons() diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index a871f152f6..5149ebaa2e 100644 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -169,7 +169,7 @@ SUBSYSTEM_DEF(ticker) start_at = world.time + (CONFIG_GET(number/lobby_countdown) * 10) for(var/client/C in GLOB.clients) window_flash(C, ignorepref = TRUE) //let them know lobby has opened up. - to_chat(world, "Welcome to [station_name()]!") + to_chat(world, span_boldnotice("Welcome to [station_name()]!")) send2chat(new /datum/tgs_message_content("New round starting on [SSmapping.config.map_name]!"), CONFIG_GET(string/chat_announce_new_game)) current_state = GAME_STATE_PREGAME //SPLURT EDIT - Bring back old panel @@ -445,7 +445,7 @@ SUBSYSTEM_DEF(ticker) if (living.client.prefs && living.client.prefs.auto_ooc) if (living.client.prefs.chat_toggles & CHAT_OOC) living.client.prefs.chat_toggles ^= CHAT_OOC - var/atom/movable/screen/splash/S = new(living.client, TRUE) + var/atom/movable/screen/splash/S = new(null, living.client, TRUE) S.Fade(TRUE) living.client.init_verbs() livings += living diff --git a/code/controllers/subsystem/title.dm b/code/controllers/subsystem/title.dm index 85948fc66c..8ba1f86e99 100644 --- a/code/controllers/subsystem/title.dm +++ b/code/controllers/subsystem/title.dm @@ -76,7 +76,7 @@ SUBSYSTEM_DEF(title) for(var/thing in GLOB.clients) if(!thing) continue - var/atom/movable/screen/splash/S = new(thing, FALSE) + var/atom/movable/screen/splash/S = new(null, thing, FALSE) S.Fade(FALSE,FALSE) // Save the sound path diff --git a/code/datums/action.dm b/code/datums/action.dm index 04ef6e8974..835e1d4d89 100644 --- a/code/datums/action.dm +++ b/code/datums/action.dm @@ -39,6 +39,7 @@ var/icon_icon = 'icons/mob/actions.dmi' /// This is the icon state for the icon that appears on the button var/button_icon_state = "default" + var/button_overlay_state /datum/action/New(Target) link_to(Target) @@ -92,7 +93,7 @@ if(!hud.mymob) continue HideFrom(hud.mymob) - LAZYREMOVE(remove_from.actions, src) // We aren't always properly inserted into the viewers list, gotta make sure that action's cleared + LAZYREMOVE(remove_from?.actions, src) // We aren't always properly inserted into the viewers list, gotta make sure that action's cleared viewers = list() if(isnull(owner)) @@ -177,6 +178,11 @@ ApplyIcon(button, force) + if(button_overlay_state) + button.cut_overlay(button.button_overlay) + button.button_overlay = mutable_appearance(icon = 'icons/mob/actions.dmi', icon_state = button_overlay_state) + button.add_overlay(button.button_overlay) + if(!IsAvailable(TRUE)) button.color = transparent_when_unavailable ? rgb(128,0,0,128) : rgb(128,0,0) else @@ -362,6 +368,8 @@ /datum/action/item_action/set_internals name = "Set Internals" + default_button_position = SCRN_OBJ_INSERT_FIRST + button_overlay_state = "ab_goldborder" /datum/action/item_action/set_internals/UpdateButton(atom/movable/screen/movable/action_button/button, status_only = FALSE, force) if(!..()) // no button available @@ -941,20 +949,6 @@ icon_icon = 'icons/mob/actions/actions_items.dmi' button_icon_state = "jetboot" -/datum/action/language_menu - name = "Language Menu" - desc = "Open the language menu to review your languages, their keys, and select your default language." - button_icon_state = "language_menu" - check_flags = 0 - -/datum/action/language_menu/Trigger() - if(!..()) - return FALSE - if(ismob(owner)) - var/mob/M = owner - var/datum/language_holder/H = M.get_language_holder() - H.open_language_menu(usr) - /datum/action/item_action/wheelys name = "Toggle Wheely-Heel's Wheels" desc = "Pops out or in your wheely-heel's wheels." diff --git a/code/datums/brain_damage/severe.dm b/code/datums/brain_damage/severe.dm index 182bcce97e..bc447280be 100644 --- a/code/datums/brain_damage/severe.dm +++ b/code/datums/brain_damage/severe.dm @@ -28,13 +28,13 @@ lose_text = "You suddenly remember how languages work." /datum/brain_trauma/severe/aphasia/on_gain() - owner.add_blocked_language(subtypesof(/datum/language/) - /datum/language/aphasia, LANGUAGE_APHASIA) - owner.grant_language(/datum/language/aphasia, TRUE, TRUE, LANGUAGE_APHASIA) + owner.add_blocked_language(subtypesof(/datum/language) - /datum/language/aphasia, LANGUAGE_APHASIA) + owner.grant_language(/datum/language/aphasia, source = LANGUAGE_APHASIA) ..() /datum/brain_trauma/severe/aphasia/on_lose() - owner.remove_blocked_language(subtypesof(/datum/language/), LANGUAGE_APHASIA) - owner.remove_language(/datum/language/aphasia, TRUE, TRUE, LANGUAGE_APHASIA) + owner.remove_blocked_language(subtypesof(/datum/language), LANGUAGE_APHASIA) + owner.remove_language(/datum/language/aphasia, LANGUAGE_APHASIA) ..() /datum/brain_trauma/severe/blindness diff --git a/code/datums/components/combat_mode.dm b/code/datums/components/combat_mode.dm index 17c67e9662..b90bb571a1 100644 --- a/code/datums/components/combat_mode.dm +++ b/code/datums/components/combat_mode.dm @@ -40,8 +40,7 @@ /// Creates the hud screen object. /datum/component/combat_mode/proc/on_mob_hud_created(mob/source) - hud_icon = new - hud_icon.hud = source.hud_used + hud_icon = new(null, source.hud_used) hud_icon.icon = tg_ui_icon_to_cit_ui(source.hud_used.ui_style) hud_icon.screen_loc = hud_loc source.hud_used.static_inventory += hud_icon @@ -187,6 +186,7 @@ name = "toggle combat mode" icon = 'modular_citadel/icons/ui/screen_midnight.dmi' icon_state = "combat_off" + mouse_over_pointer = MOUSE_HAND_POINTER var/mutable_appearance/flashy var/combat_on = FALSE ///Wheter combat mode is enabled or not, so we don't have to store a reference. diff --git a/code/datums/components/crafting/crafting.dm b/code/datums/components/crafting/crafting.dm index 257e6cc4ca..19ec295a41 100644 --- a/code/datums/components/crafting/crafting.dm +++ b/code/datums/components/crafting/crafting.dm @@ -4,11 +4,11 @@ /datum/component/personal_crafting/proc/create_mob_button(mob/user) var/datum/hud/H = user.hud_used - var/atom/movable/screen/craft/C = new() + var/atom/movable/screen/craft/C = new(null, H) C.icon = H.ui_style H.static_inventory += C user.client.screen += C - RegisterSignal(C, COMSIG_CLICK, PROC_REF(component_ui_interact)) + RegisterSignal(C, COMSIG_SCREEN_ELEMENT_CLICK, PROC_REF(component_ui_interact)) /datum/component/personal_crafting var/busy diff --git a/code/datums/components/mood.dm b/code/datums/components/mood.dm index a5c316310b..5b0455b0aa 100644 --- a/code/datums/components/mood.dm +++ b/code/datums/components/mood.dm @@ -300,12 +300,12 @@ /datum/component/mood/proc/modify_hud(datum/source) var/mob/living/owner = parent var/datum/hud/hud = owner.hud_used - screen_obj = new - screen_obj_sanity = new // Sandstorm sanity + screen_obj = new(null, hud) + screen_obj_sanity = new(null, hud) hud.infodisplay += screen_obj hud.infodisplay += screen_obj_sanity // Sandstorm sanity RegisterSignal(hud, COMSIG_PARENT_QDELETING, PROC_REF(unmodify_hud)) - RegisterSignal(screen_obj, COMSIG_CLICK, PROC_REF(hud_click)) + RegisterSignal(screen_obj, COMSIG_SCREEN_ELEMENT_CLICK, PROC_REF(hud_click)) /datum/component/mood/proc/unmodify_hud(datum/source) if(!screen_obj || !parent) diff --git a/code/datums/components/rotation.dm b/code/datums/components/rotation.dm index 8eb37eabdf..043e2f8f18 100644 --- a/code/datums/components/rotation.dm +++ b/code/datums/components/rotation.dm @@ -13,7 +13,7 @@ var/rotation_flags = NONE var/default_rotation_direction = ROTATION_CLOCKWISE -/datum/component/simple_rotation/Initialize(rotation_flags = NONE ,can_user_rotate,can_be_rotated,after_rotation) +/datum/component/simple_rotation/Initialize(rotation_flags = NONE, can_user_rotate, can_be_rotated, after_rotation) if(!ismovable(parent)) return COMPONENT_INCOMPATIBLE diff --git a/code/datums/components/storage/ui.dm b/code/datums/components/storage/ui.dm index c0cc03965c..841525ba79 100644 --- a/code/datums/components/storage/ui.dm +++ b/code/datums/components/storage/ui.dm @@ -33,11 +33,11 @@ var/rows = clamp(CEILING(adjusted_contents / columns, 1), 1, screen_max_rows) // First, boxes. - ui_boxes = get_ui_boxes() + ui_boxes = get_ui_boxes(user.hud_used) ui_boxes.screen_loc = "[screen_start_x]:[screen_pixel_x],[screen_start_y]:[screen_pixel_y] to [screen_start_x+columns-1]:[screen_pixel_x],[screen_start_y+rows-1]:[screen_pixel_y]" . += ui_boxes // Then, closer. - ui_close = get_ui_close() + ui_close = get_ui_close(user.hud_used) ui_close.screen_loc = "[screen_start_x + columns]:[screen_pixel_x],[screen_start_y]:[screen_pixel_y]" . += ui_close // Then orient the actual items. @@ -62,7 +62,7 @@ for(var/obj/O in accessible_items()) if(QDELETED(O)) continue - var/atom/movable/screen/storage/item_holder/D = new(null, src, O) + var/atom/movable/screen/storage/item_holder/D = new(null, user.hud_used, src, O) // SNOWFLAKE: make O opaque too, pending storage rewrite O.mouse_opacity = MOUSE_OPACITY_OPAQUE D.mouse_opacity = MOUSE_OPACITY_OPAQUE //This is here so storage items that spawn with contents correctly have the "click around item to equip" @@ -139,7 +139,7 @@ for(var/i in percentage_by_item) I = i var/percent = percentage_by_item[I] - var/atom/movable/screen/storage/volumetric_box/center/B = new /atom/movable/screen/storage/volumetric_box/center(null, src, I) + var/atom/movable/screen/storage/volumetric_box/center/B = new /atom/movable/screen/storage/volumetric_box/center(null, user.hud_used, src, I) // SNOWFLAKE: force it to icon until we unfuck storage/click passing I.mouse_opacity = MOUSE_OPACITY_ICON var/pixels_to_use = overrun? MINIMUM_PIXELS_PER_ITEM : max(using_horizontal_pixels * percent, MINIMUM_PIXELS_PER_ITEM) @@ -168,15 +168,15 @@ current_pixel = VOLUMETRIC_STORAGE_EDGE_PADDING // Then, continuous section. - ui_continuous = get_ui_continuous() + ui_continuous = get_ui_continuous(user.hud_used) ui_continuous.screen_loc = "[screen_start_x]:[screen_pixel_x],[screen_start_y]:[screen_pixel_y] to [screen_start_x+maxcolumns-1]:[screen_pixel_x],[screen_start_y+rows-1]:[screen_pixel_y]" . += ui_continuous // Then, left. - ui_left = get_ui_left() + ui_left = get_ui_left(user.hud_used) ui_left.screen_loc = "[screen_start_x]:[screen_pixel_x - 2],[screen_start_y]:[screen_pixel_y] to [screen_start_x]:[screen_pixel_x - 2],[screen_start_y+rows-1]:[screen_pixel_y]" . += ui_left // Then, closer, which is also our right element. - ui_close = get_ui_close() + ui_close = get_ui_close(user.hud_used) ui_close.screen_loc = "[screen_start_x + maxcolumns]:[screen_pixel_x],[screen_start_y]:[screen_pixel_y] to [screen_start_x + maxcolumns]:[screen_pixel_x],[screen_start_y+rows-1]:[screen_pixel_y]" . += ui_close @@ -258,23 +258,23 @@ /** * Gets our ui_boxes, making it if it doesn't exist. */ -/datum/component/storage/proc/get_ui_boxes() - return new /atom/movable/screen/storage/boxes(null, src) +/datum/component/storage/proc/get_ui_boxes(datum/hud/hud) + return new /atom/movable/screen/storage/boxes(null, hud, src) /** * Gets our ui_left, making it if it doesn't exist. */ -/datum/component/storage/proc/get_ui_left() - return new /atom/movable/screen/storage/left(null, src) +/datum/component/storage/proc/get_ui_left(datum/hud/hud) + return new /atom/movable/screen/storage/left(null, hud, src) /** * Gets our ui_close, making it if it doesn't exist. */ -/datum/component/storage/proc/get_ui_close() - return new /atom/movable/screen/storage/close(null, src) +/datum/component/storage/proc/get_ui_close(datum/hud/hud) + return new /atom/movable/screen/storage/close(null, hud, src) /** * Gets our ui_continuous, making it if it doesn't exist. */ -/datum/component/storage/proc/get_ui_continuous() - return new /atom/movable/screen/storage/continuous(null, src) +/datum/component/storage/proc/get_ui_continuous(datum/hud/hud) + return new /atom/movable/screen/storage/continuous(null, hud, src) diff --git a/code/datums/diseases/advance/symptoms/voice_change.dm b/code/datums/diseases/advance/symptoms/voice_change.dm index 9fa6ed5cc8..6cf3847ddc 100644 --- a/code/datums/diseases/advance/symptoms/voice_change.dm +++ b/code/datums/diseases/advance/symptoms/voice_change.dm @@ -63,7 +63,7 @@ Bonus if(scramble_language && !current_language) // Last part prevents rerolling language with small amounts of cure. current_language = pick(subtypesof(/datum/language) - /datum/language/common) H.add_blocked_language(subtypesof(/datum/language) - current_language, LANGUAGE_VOICECHANGE) - H.grant_language(current_language, TRUE, TRUE, LANGUAGE_VOICECHANGE) + H.grant_language(current_language, source = LANGUAGE_VOICECHANGE) /datum/symptom/voice_change/End(datum/disease/advance/A) ..() diff --git a/code/datums/dna.dm b/code/datums/dna.dm index 2974222665..849bd66c8f 100644 --- a/code/datums/dna.dm +++ b/code/datums/dna.dm @@ -407,7 +407,6 @@ qdel(language_holder) var/species_holder = initial(mrace.species_language_holder) language_holder = new species_holder(src) - update_atom_languages() /mob/living/carbon/human/set_species(datum/species/mrace, icon_update = TRUE, pref_load = FALSE) ..() diff --git a/code/datums/elements/decal.dm b/code/datums/elements/decal.dm index c3f9f1bd17..e3baf9aafa 100644 --- a/code/datums/elements/decal.dm +++ b/code/datums/elements/decal.dm @@ -4,75 +4,90 @@ var/cleanable var/description var/mutable_appearance/pic - var/list/num_decals_per_atom + /** + * A short lecture on decal element collision on rotation + * If a given decal's rotated version is identical to one of existing (at a same target), pre-rotation decals, + * then the rotated decal won't stay after when the colliding pre-rotation decal gets rotated, + * resulting in some decal elements colliding into nonexistence. This internal tick-tock prevents + * such collision by forcing a non-collision. + */ + var/rotated - var/first_dir // This stores the direction of the decal compared to the parent facing NORTH - -/datum/element/decal/Attach(datum/target, _icon, _icon_state, _dir, _cleanable=CLEAN_GOD, _color, _layer=TURF_LAYER, _description, _alpha=255) +/datum/element/decal/Attach(atom/target, _icon, _icon_state, _dir, _cleanable=CLEAN_GOD, _color, _layer=TURF_LAYER, _description, _alpha=255, _rotated=FALSE) . = ..() - if(. == ELEMENT_INCOMPATIBLE || !_icon || !_icon_state || !isatom(target)) + if(!isatom(target) || (pic ? FALSE : !generate_appearance(_icon, _icon_state, _dir, _layer, _color, _alpha, target))) return ELEMENT_INCOMPATIBLE - var/atom/A = target - if(!pic) - // It has to be made from an image or dir breaks because of a byond bug - var/temp_image = image(_icon, null, _icon_state, _layer, _dir) - pic = new(temp_image) - pic.color = _color - pic.alpha = _alpha - first_dir = _dir description = _description cleanable = _cleanable + rotated = _rotated - LAZYINITLIST(num_decals_per_atom) - - if(!num_decals_per_atom[A]) - if(first_dir) - RegisterSignal(A, COMSIG_ATOM_DIR_CHANGE, PROC_REF(rotate_react)) - if(cleanable) - RegisterSignal(A, COMSIG_COMPONENT_CLEAN_ACT, PROC_REF(clean_react)) - if(description) - RegisterSignal(A, COMSIG_PARENT_EXAMINE, PROC_REF(examine)) - RegisterSignal(A, COMSIG_ATOM_UPDATE_OVERLAYS, PROC_REF(apply_overlay), TRUE) - - num_decals_per_atom[A]++ - apply(A) - -/datum/element/decal/Detach(datum/target) - var/atom/A = target - num_decals_per_atom[A]-- - if(!num_decals_per_atom[A]) - UnregisterSignal(A, list(COMSIG_ATOM_DIR_CHANGE, COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZE, - COMSIG_COMPONENT_CLEAN_ACT, COMSIG_PARENT_EXAMINE, COMSIG_ATOM_UPDATE_OVERLAYS)) - LAZYREMOVE(num_decals_per_atom, A) - apply(A) - return ..() - -/datum/element/decal/proc/apply(atom/target) + RegisterSignal(target,COMSIG_ATOM_UPDATE_OVERLAYS, PROC_REF(apply_overlay), TRUE) + if(isturf(target)) + RegisterSignal(target,COMSIG_TURF_AFTER_SHUTTLE_MOVE, PROC_REF(shuttlemove_react), TRUE) if(target.flags_1 & INITIALIZED_1) target.update_icon() //could use some queuing here now maybe. - else if(!QDELETED(target) && num_decals_per_atom[target] == 1) - RegisterSignal(target, COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZE, PROC_REF(late_update_icon)) + else + RegisterSignal(target,COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZE,PROC_REF(late_update_icon), TRUE) if(isitem(target)) - addtimer(CALLBACK(target, TYPE_PROC_REF(/obj/item, update_slot_icon)), 0, TIMER_UNIQUE) + INVOKE_ASYNC(target, TYPE_PROC_REF(/obj/item, update_slot_icon), TRUE) + if(_dir) + RegisterSignal(target, COMSIG_ATOM_DIR_CHANGE, PROC_REF(rotate_react),TRUE) + if(_cleanable) + RegisterSignal(target, COMSIG_COMPONENT_CLEAN_ACT, PROC_REF(clean_react),TRUE) + if(_description) + RegisterSignal(target, COMSIG_PARENT_EXAMINE, PROC_REF(examine),TRUE) + +/datum/element/decal/proc/generate_appearance(_icon, _icon_state, _dir, _layer, _color, _alpha, source) + if(!_icon || !_icon_state) + return FALSE + var/temp_image = image(_icon, null, _icon_state, _layer, _dir) + pic = new(temp_image) + pic.color = _color + pic.alpha = _alpha + return TRUE + +/datum/element/decal/Detach(atom/source, force) + UnregisterSignal(source, list(COMSIG_ATOM_DIR_CHANGE, COMSIG_COMPONENT_CLEAN_ACT, COMSIG_PARENT_EXAMINE, COMSIG_ATOM_UPDATE_OVERLAYS,COMSIG_TURF_AFTER_SHUTTLE_MOVE)) + source.update_icon() + if(isitem(source)) + INVOKE_ASYNC(source, TYPE_PROC_REF(/obj/item, update_slot_icon)) + return ..() /datum/element/decal/proc/late_update_icon(atom/source) - source.update_icon() - UnregisterSignal(source,COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZE) + SIGNAL_HANDLER + + if(source && istype(source)) + source.update_icon() + UnregisterSignal(source,COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZE) + /datum/element/decal/proc/apply_overlay(atom/source, list/overlay_list) - if(first_dir) - pic.dir = first_dir == SOUTH ? source.dir : turn(first_dir, dir2angle(source.dir)-180) //Never turn a dir by 0. - for(var/i in 1 to num_decals_per_atom[source]) - overlay_list += pic + SIGNAL_HANDLER + + overlay_list += pic + +/datum/element/decal/proc/shuttlemove_react(datum/source, turf/newT) + SIGNAL_HANDLER + Detach(source) + newT.AddElement(/datum/element/decal, pic.icon, pic.icon_state, pic.dir, cleanable, pic.color, pic.layer, description, pic.alpha, rotated) + +/datum/element/decal/proc/rotate_react(datum/source, old_dir, new_dir) + SIGNAL_HANDLER -/datum/element/decal/proc/rotate_react(atom/source, old_dir, new_dir) if(old_dir == new_dir) return - source.update_icon() + Detach(source) + source.AddElement(/datum/element/decal, pic.icon, pic.icon_state, angle2dir(dir2angle(pic.dir)+dir2angle(new_dir)-dir2angle(old_dir)), cleanable, pic.color, pic.layer, description, pic.alpha, !rotated) /datum/element/decal/proc/clean_react(datum/source, strength) + SIGNAL_HANDLER + if(strength >= cleanable) Detach(source) + return TRUE + return NONE /datum/element/decal/proc/examine(datum/source, mob/user, list/examine_list) + SIGNAL_HANDLER + examine_list += description diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 243edd9472..b4fd86abf4 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -64,7 +64,6 @@ var/isholy = FALSE //is this person a chaplain or admin role allowed to use bibles var/mob/living/enslaved_to //If this mind's master is another mob (i.e. adamantine golems) - var/datum/language_holder/language_holder var/unconvertable = FALSE var/late_joiner = FALSE ///has this mind ever been an AI @@ -97,7 +96,6 @@ /datum/mind/Destroy() SSticker.minds -= src QDEL_LIST(antag_datums) - QDEL_NULL(language_holder) QDEL_NULL(skill_holder) set_current(null) soulOwner = null @@ -119,12 +117,6 @@ /datum/mind/proc/set_original_character(new_original_character) original_character = WEAKREF(new_original_character) -/datum/mind/proc/get_language_holder() - if(!language_holder) - language_holder = new (src) - - return language_holder - /datum/mind/proc/transfer_to(mob/new_character, var/force_key_move = 0) var/old_character = current var/signals = SEND_SIGNAL(new_character, COMSIG_MOB_PRE_PLAYER_CHANGE, new_character, old_character) | SEND_SIGNAL(src, COMSIG_PRE_MIND_TRANSFER, new_character, old_character) @@ -146,7 +138,19 @@ var/datum/atom_hud/antag/hud_to_transfer = antag_hud//we need this because leave_hud() will clear this list var/mob/living/old_current = current if(current) - current.transfer_observers_to(new_character) //transfer anyone observing the old character to the new one + //transfer anyone observing the old character to the new one + current.transfer_observers_to(new_character) + + // Offload all mind languages from the old holder to a temp one + var/datum/language_holder/empty/temp_holder = new() + var/datum/language_holder/old_holder = old_current.get_language_holder() + var/datum/language_holder/new_holder = new_character.get_language_holder() + // Off load mind languages to the temp holder momentarily + new_holder.transfer_mind_languages(temp_holder) + // Transfer the old holder's mind languages to the new holder + old_holder.transfer_mind_languages(new_holder) + // And finally transfer the temp holder's mind languages back to the old holder + temp_holder.transfer_mind_languages(old_holder) set_current(new_character) //associate ourself with our new body new_character.mind = src //and associate our new body with ourself for(var/a in antag_datums) //Makes sure all antag datums effects are applied in the new body @@ -163,7 +167,6 @@ if(new_character.client) LAZYCLEARLIST(new_character.client.recent_examines) new_character.client.init_verbs() // re-initialize character specific verbs - current.update_atom_languages() //CIT CHANGE - makes arousal update when transfering bodies if(isliving(new_character)) //New humans and such are by default enabled arousal. Let's always use the new mind's prefs. diff --git a/code/datums/mutations/speech.dm b/code/datums/mutations/speech.dm index 0eeb387a77..4559f39b00 100644 --- a/code/datums/mutations/speech.dm +++ b/code/datums/mutations/speech.dm @@ -277,10 +277,10 @@ /datum/mutation/human/stoner/on_acquiring(mob/living/carbon/human/owner) ..() - owner.grant_language(/datum/language/beachbum, TRUE, TRUE, LANGUAGE_STONER) + owner.grant_language(/datum/language/beachbum, source = LANGUAGE_STONER) owner.add_blocked_language(subtypesof(/datum/language) - /datum/language/beachbum, LANGUAGE_STONER) /datum/mutation/human/stoner/on_losing(mob/living/carbon/human/owner) ..() - owner.remove_language(/datum/language/beachbum, TRUE, TRUE, LANGUAGE_STONER) + owner.remove_language(/datum/language/beachbum, source = LANGUAGE_STONER) owner.remove_blocked_language(subtypesof(/datum/language) - /datum/language/beachbum, LANGUAGE_STONER) diff --git a/code/datums/numbered_display.dm b/code/datums/numbered_display.dm index b714be23fb..15e147463d 100644 --- a/code/datums/numbered_display.dm +++ b/code/datums/numbered_display.dm @@ -6,5 +6,5 @@ /datum/numbered_display/New(obj/item/sample, _number = 1, datum/component/storage/parent) if(!istype(sample)) qdel(src) - sample_object = new /atom/movable/screen/storage/item_holder(null, parent, sample) + sample_object = new /atom/movable/screen/storage/item_holder(null, null, parent, sample) number = _number diff --git a/code/datums/station_traits/_station_trait.dm b/code/datums/station_traits/_station_trait.dm index cb0de6afd4..6c7abcd7bf 100644 --- a/code/datums/station_traits/_station_trait.dm +++ b/code/datums/station_traits/_station_trait.dm @@ -1,3 +1,6 @@ +/// Station traits displayed in the lobby +GLOBAL_LIST_EMPTY(lobby_station_traits) + ///Base class of station traits. These are used to influence rounds in one way or the other by influencing the levers of the station. /datum/station_trait ///Name of the trait @@ -22,26 +25,30 @@ var/trait_flags /// Whether or not this trait can be reverted by an admin var/can_revert = TRUE + /// If set to true we'll show a button on the lobby to notify people about this trait + var/sign_up_button = FALSE + /// Lobby buttons controlled by this trait + var/list/lobby_buttons = list() /datum/station_trait/New() . = ..() RegisterSignal(SSticker, COMSIG_TICKER_ROUND_STARTING, PROC_REF(on_round_start)) + if(sign_up_button) + GLOB.lobby_station_traits += src + if(SSstation.initialized) + SSstation.display_lobby_traits() if(trait_processes) START_PROCESSING(SSstation, src) if(trait_to_give) ADD_TRAIT(SSstation, trait_to_give, STATION_TRAIT) /datum/station_trait/Destroy() + destroy_lobby_buttons() SSstation.station_traits -= src return ..() -/// Proc ran when round starts. Use this for roundstart effects. -/datum/station_trait/proc/on_round_start() - SIGNAL_HANDLER - return - ///type of info the centcom report has on this trait, if any. /datum/station_trait/proc/get_report() return "[name] - [report_message]" @@ -55,3 +62,50 @@ REMOVE_TRAIT(SSstation, trait_to_give, STATION_TRAIT) qdel(src) + +/// Return TRUE if we want to show a lobby button, by default we assume we don't want it after the round begins +/datum/station_trait/proc/can_display_lobby_button(client/player) + return sign_up_button && !SSticker.HasRoundStarted() + +/// Apply any additional handling we need to our lobby button +/datum/station_trait/proc/setup_lobby_button(atom/movable/screen/lobby/button/sign_up/lobby_button) + SHOULD_CALL_PARENT(TRUE) + lobby_button.name = name + lobby_buttons |= lobby_button + RegisterSignal(lobby_button, COMSIG_ATOM_UPDATE_ICON, PROC_REF(on_lobby_button_update_icon)) + RegisterSignal(lobby_button, COMSIG_SCREEN_ELEMENT_CLICK, PROC_REF(on_lobby_button_click)) + RegisterSignal(lobby_button, COMSIG_PARENT_QDELETING, PROC_REF(on_lobby_button_destroyed)) + lobby_button.update_appearance(UPDATE_ICON) + +/// Called when our lobby button is clicked on +/datum/station_trait/proc/on_lobby_button_click(atom/movable/screen/lobby/button/sign_up/lobby_button, location, control, params, mob/dead/new_player/user) + SIGNAL_HANDLER + return + +/// Called when our lobby button tries to update its appearance +/datum/station_trait/proc/on_lobby_button_update_icon(atom/movable/screen/lobby/button/sign_up/lobby_button, updates) + SIGNAL_HANDLER + return + +/// Don't hold references to deleted buttons +/datum/station_trait/proc/on_lobby_button_destroyed(atom/movable/screen/lobby/button/sign_up/lobby_button) + SIGNAL_HANDLER + lobby_buttons -= lobby_button + +/// Proc ran when round starts. Use this for roundstart effects. By default we clean up our buttons here. +/datum/station_trait/proc/on_round_start() + SIGNAL_HANDLER + destroy_lobby_buttons() + +/// Remove all of our active lobby buttons +/datum/station_trait/proc/destroy_lobby_buttons() + for (var/atom/movable/screen/button as anything in lobby_buttons) + var/mob/dead/new_player/hud_owner = button.get_mob() + if (QDELETED(hud_owner)) + qdel(button) + continue + var/datum/hud/new_player/using_hud = hud_owner.hud_used + if(!using_hud) + qdel(button) + continue + using_hud.remove_station_trait_button(src) diff --git a/code/datums/station_traits/negative_traits.dm b/code/datums/station_traits/negative_traits.dm index 91043d3942..bc879830b1 100644 --- a/code/datums/station_traits/negative_traits.dm +++ b/code/datums/station_traits/negative_traits.dm @@ -152,9 +152,7 @@ . = ..() //All bots that exist round start have their set language randomized. for(var/mob/living/simple_animal/bot/found_bot in GLOB.alive_mob_list) - /// The bot's language holder - so we can randomize and change their language - var/datum/language_holder/bot_languages = found_bot.get_language_holder() - bot_languages.selected_language = bot_languages.get_random_spoken_language() + found_bot.set_active_language(found_bot.get_random_spoken_language()) /datum/station_trait/revenge_of_pun_pun name = "Revenge of Pun Pun" diff --git a/code/datums/status_effects/debuffs.dm b/code/datums/status_effects/debuffs.dm index 486b0d764b..ab2945ace4 100644 --- a/code/datums/status_effects/debuffs.dm +++ b/code/datums/status_effects/debuffs.dm @@ -988,17 +988,20 @@ desc = "A magical strand of Durathread is wrapped around your neck, preventing you from breathing! Click this icon to remove the strand." icon_state = "his_grace" alerttooltipstyle = "hisgrace" + clickable_glow = TRUE /atom/movable/screen/alert/status_effect/strandling/Click(location, control, params) . = ..() - if(usr != owner) + if(!.) return to_chat(owner, "You attempt to remove the durathread strand from around your neck.") - if(do_after(owner, 3.5 SECONDS, owner)) - if(isliving(owner)) - var/mob/living/L = owner - to_chat(owner, "You successfully remove the durathread strand.") - L.remove_status_effect(STATUS_EFFECT_CHOKINGSTRAND) + if(!do_after(owner, 3.5 SECONDS, owner)) + return + if(!isliving(owner)) + return + var/mob/living/L = owner + to_chat(owner, "You successfully remove the durathread strand.") + L.remove_status_effect(STATUS_EFFECT_CHOKINGSTRAND) /datum/status_effect/pacify diff --git a/code/datums/status_effects/wound_effects.dm b/code/datums/status_effects/wound_effects.dm index f5903bbc28..12bc58d70f 100644 --- a/code/datums/status_effects/wound_effects.dm +++ b/code/datums/status_effects/wound_effects.dm @@ -102,8 +102,12 @@ /atom/movable/screen/alert/status_effect/wound name = "Wounded" desc = "Your body has sustained serious damage, click here to inspect yourself." + clickable_glow = TRUE /atom/movable/screen/alert/status_effect/wound/Click() + . = ..() + if(!.) + return var/mob/living/carbon/C = usr C.check_self_for_injuries() diff --git a/code/datums/weather/weather_types/ash_storm.dm b/code/datums/weather/weather_types/ash_storm.dm index e41cb93c54..b9fac4b299 100644 --- a/code/datums/weather/weather_types/ash_storm.dm +++ b/code/datums/weather/weather_types/ash_storm.dm @@ -58,10 +58,6 @@ GLOBAL_LIST_EMPTY(ash_storm_sounds) GLOB.ash_storm_sounds += weak_sounds return ..() -/datum/weather/ash_storm/end() - GLOB.ash_storm_sounds -= weak_sounds - return ..() - /datum/weather/ash_storm/proc/is_ash_immune(atom/L) while (L && !isturf(L)) if(ismecha(L)) //Mechs are immune @@ -88,6 +84,14 @@ GLOBAL_LIST_EMPTY(ash_storm_sounds) return L.adjustFireLoss(4) +/datum/weather/ash_storm/end() + GLOB.ash_storm_sounds -= weak_sounds + for(var/turf/open/floor/plating/asteroid/basalt/basalt as anything in GLOB.dug_up_basalt) + if(!(basalt.loc in impacted_areas) || !(basalt.z in impacted_z_levels)) + continue + basalt.refill_dug() + return ..() + //Emberfalls are the result of an ash storm passing by close to the playable area of lavaland. They have a 10% chance to trigger in place of an ash storm. /datum/weather/ash_storm/emberfall name = "emberfall" diff --git a/code/datums/world_topic.dm b/code/datums/world_topic.dm index 45046e3070..576dd288d4 100644 --- a/code/datums/world_topic.dm +++ b/code/datums/world_topic.dm @@ -124,7 +124,7 @@ for(var/mob/dead/observer/O in GLOB.player_list) if(O.key == expected_key) if(O.client?.address == addr) - new /atom/movable/screen/splash(O.client, TRUE) + new /atom/movable/screen/splash(null, O.client, TRUE) break /datum/world_topic/adminmsg diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 0a659bc48f..ab58e49f9c 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -709,7 +709,8 @@ /atom/proc/hitby(atom/movable/hitting_atom, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) SEND_SIGNAL(src, COMSIG_ATOM_HITBY, hitting_atom, skipcatch, hitpush, blocked, throwingdatum) if(density && !has_gravity(hitting_atom)) //thrown stuff bounces off dense stuff in no grav, unless the thrown stuff ends up inside what it hit(embedding, bola, etc...). - addtimer(CALLBACK(src, PROC_REF(hitby_react), hitting_atom), 2) + addtimer(CALLBACK(src, PROC_REF(hitby_react), hitting_atom), 0.2 SECONDS) + return FALSE /** * We have have actually hit the passed in atom diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 764e61d4c8..edf954bb78 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -12,8 +12,11 @@ var/throw_speed = 2 //How many tiles to move per ds when being thrown. Float values are fully supported var/throw_range = 7 var/mob/pulledby = null + /// What language holder type to init as var/initial_language_holder = /datum/language_holder - var/datum/language_holder/language_holder // Mindless mobs and objects need language too, some times. Mind holder takes prescedence. + /// Holds all languages this mob can speak and understand + VAR_PRIVATE/datum/language_holder/language_holder + var/verb_say = "says" var/verb_ask = "asks" var/verb_exclaim = "exclaims" @@ -388,7 +391,7 @@ /atom/movable/hitby(atom/movable/hitting_atom, skipcatch, hitpush = TRUE, blocked, datum/thrownthing/throwingdatum) if(!anchored && hitpush && (!throwingdatum || (throwingdatum.force >= (move_resist * MOVE_FORCE_PUSH_RATIO)))) step(src, hitting_atom.dir) - ..() + return ..() /atom/movable/proc/safe_throw_at(atom/target, range, speed, mob/thrower, spin = TRUE, diagonals_first = FALSE, datum/callback/callback, force = MOVE_FORCE_STRONG, gentle = FALSE) if((force < (move_resist * MOVE_FORCE_THROW_RATIO)) || (move_resist == INFINITY)) @@ -649,49 +652,46 @@ /// Gets or creates the relevant language holder. For mindless atoms, gets the local one. For atom with mind, gets the mind one. /atom/movable/proc/get_language_holder(get_minds = TRUE) + RETURN_TYPE(/datum/language_holder) + if(QDELING(src)) + CRASH("get_language_holder() called on a QDELing atom, \ + this will try to re-instantiate the language holder that's about to be deleted, which is bad.") + if(!language_holder) language_holder = new initial_language_holder(src) return language_holder /// Grants the supplied language and sets omnitongue true. -/atom/movable/proc/grant_language(language, understood = TRUE, spoken = TRUE, source = LANGUAGE_ATOM) - var/datum/language_holder/LH = get_language_holder() - return LH.grant_language(language, understood, spoken, source) +/atom/movable/proc/grant_language(language, language_flags = ALL, source = LANGUAGE_ATOM) + return get_language_holder().grant_language(language, language_flags, source) /// Grants every language. -/atom/movable/proc/grant_all_languages(understood = TRUE, spoken = TRUE, grant_omnitongue = TRUE, source = LANGUAGE_MIND) - var/datum/language_holder/LH = get_language_holder() - return LH.grant_all_languages(understood, spoken, grant_omnitongue, source) +/atom/movable/proc/grant_all_languages(language_flags = ALL, grant_omnitongue = TRUE, source = LANGUAGE_MIND) + return get_language_holder().grant_all_languages(language_flags, grant_omnitongue, source) /// Removes a single language. -/atom/movable/proc/remove_language(language, understood = TRUE, spoken = TRUE, source = LANGUAGE_ALL) - var/datum/language_holder/LH = get_language_holder() - return LH.remove_language(language, understood, spoken, source) +/atom/movable/proc/remove_language(language, language_flags = ALL, source = LANGUAGE_ALL) + return get_language_holder().remove_language(language, language_flags, source) /// Removes every language and sets omnitongue false. /atom/movable/proc/remove_all_languages(source = LANGUAGE_ALL, remove_omnitongue = FALSE) - var/datum/language_holder/LH = get_language_holder() - return LH.remove_all_languages(source, remove_omnitongue) + return get_language_holder().remove_all_languages(source, remove_omnitongue) /// Adds a language to the blocked language list. Use this over remove_language in cases where you will give languages back later. /atom/movable/proc/add_blocked_language(language, source = LANGUAGE_ATOM) - var/datum/language_holder/LH = get_language_holder() - return LH.add_blocked_language(language, source) + return get_language_holder().add_blocked_language(language, source) /// Removes a language from the blocked language list. /atom/movable/proc/remove_blocked_language(language, source = LANGUAGE_ATOM) - var/datum/language_holder/LH = get_language_holder() - return LH.remove_blocked_language(language, source) + return get_language_holder().remove_blocked_language(language, source) /// Checks if atom has the language. If spoken is true, only checks if atom can speak the language. -/atom/movable/proc/has_language(language, spoken = FALSE) - var/datum/language_holder/LH = get_language_holder() - return LH.has_language(language, spoken) +/atom/movable/proc/has_language(language, flags_to_check) + return get_language_holder().has_language(language, flags_to_check) /// Checks if atom can speak the language. /atom/movable/proc/can_speak_language(language) - var/datum/language_holder/LH = get_language_holder() - return LH.can_speak_language(language) + return get_language_holder().can_speak_language(language) /// Returns the result of tongue specific limitations on spoken languages. /atom/movable/proc/could_speak_language(language) @@ -699,33 +699,32 @@ /// Returns selected language, if it can be spoken, or finds, sets and returns a new selected language if possible. /atom/movable/proc/get_selected_language() - var/datum/language_holder/LH = get_language_holder() - return LH.get_selected_language() + return get_language_holder().get_selected_language() /// Gets a random understood language, useful for hallucinations and such. /atom/movable/proc/get_random_understood_language() - var/datum/language_holder/LH = get_language_holder() - return LH.get_random_understood_language() + return get_language_holder().get_random_understood_language() /// Gets a random spoken language, useful for forced speech and such. /atom/movable/proc/get_random_spoken_language() - var/datum/language_holder/LH = get_language_holder() - return LH.get_random_spoken_language() + return get_language_holder().get_random_spoken_language() /// Copies all languages into the supplied atom/language holder. Source should be overridden when you /// do not want the language overwritten by later atom updates or want to avoid blocked languages. -/atom/movable/proc/copy_languages(from_holder, source_override) - if(isatom(from_holder)) +/atom/movable/proc/copy_languages(datum/language_holder/from_holder, source_override) + if(ismovable(from_holder)) var/atom/movable/thing = from_holder from_holder = thing.get_language_holder() - var/datum/language_holder/LH = get_language_holder() - return LH.copy_languages(from_holder, source_override) -/// Empties out the atom specific languages and updates them according to the current atoms language holder. -/// As a side effect, it also creates missing language holders in the process. -/atom/movable/proc/update_atom_languages() - var/datum/language_holder/LH = get_language_holder() - return LH.update_atom_languages(src) + return get_language_holder().copy_languages(from_holder, source_override) + +/// Sets the passed path as the active language +/// Returns the currently selected language if successful, if the language was not valid, returns null +/atom/movable/proc/set_active_language(language_path) + var/datum/language_holder/our_holder = get_language_holder() + our_holder.selected_language = language_path + + return our_holder.get_selected_language() // verifies its validity, returns it if successful. /// Sets the vocal bark for the atom, using the bark's ID /atom/movable/proc/set_bark(id) diff --git a/code/game/gamemodes/clock_cult/clock_cult.dm b/code/game/gamemodes/clock_cult/clock_cult.dm index d852ce9850..8b7f265b11 100644 --- a/code/game/gamemodes/clock_cult/clock_cult.dm +++ b/code/game/gamemodes/clock_cult/clock_cult.dm @@ -291,7 +291,6 @@ Credit where due: W.update_label() if(plasmaman && !visualsOnly) //If we need to breathe from the plasma tank, we should probably start doing that H.internal = H.get_item_for_held_index(2) - H.update_internals_hud_icon(1) PDA.owner = H.real_name PDA.ownjob = "Assistant" PDA.update_label() diff --git a/code/game/gamemodes/sandbox/h_sandbox.dm b/code/game/gamemodes/sandbox/h_sandbox.dm index f91a8acc60..fdcb47b275 100644 --- a/code/game/gamemodes/sandbox/h_sandbox.dm +++ b/code/game/gamemodes/sandbox/h_sandbox.dm @@ -176,7 +176,6 @@ GLOBAL_VAR_INIT(hsboxspawn, TRUE) P.back.plane = ABOVE_HUD_PLANE P.update_inv_back() P.internal = P.back - P.update_internals_hud_icon(1) if("hsbscrubber") // This is beyond its normal capability but this is sandbox and you spawned one, I assume you need it var/obj/hsb = new/obj/machinery/portable_atmospherics/scrubber{volume_rate=50*ONE_ATMOSPHERE;on=1}(usr.loc) diff --git a/code/game/machinery/buttons.dm b/code/game/machinery/buttons.dm index eabc4e2c26..25c68b02c1 100644 --- a/code/game/machinery/buttons.dm +++ b/code/game/machinery/buttons.dm @@ -14,6 +14,7 @@ use_power = IDLE_POWER_USE idle_power_usage = 2 resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF + mouse_over_pointer = MOUSE_HAND_POINTER /obj/machinery/button/Initialize(mapload, ndir = 0, built = 0) if(istext(id) && mapload && id[1] == "!") diff --git a/code/game/machinery/embedded_controller/access_controller.dm b/code/game/machinery/embedded_controller/access_controller.dm index dcfdeca502..e197c64f62 100644 --- a/code/game/machinery/embedded_controller/access_controller.dm +++ b/code/game/machinery/embedded_controller/access_controller.dm @@ -10,6 +10,7 @@ idle_power_usage = 2 active_power_usage = 4 resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF + mouse_over_pointer = MOUSE_HAND_POINTER var/idSelf /obj/machinery/doorButtons/attackby(obj/O, mob/user) diff --git a/code/game/machinery/firealarm.dm b/code/game/machinery/firealarm.dm index decbb3a53f..118f0e866c 100644 --- a/code/game/machinery/firealarm.dm +++ b/code/game/machinery/firealarm.dm @@ -21,6 +21,7 @@ max_integrity = 250 integrity_failure = 0.4 armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 100, RAD = 100, FIRE = 90, ACID = 30) + mouse_over_pointer = MOUSE_HAND_POINTER use_power = IDLE_POWER_USE idle_power_usage = 2 active_power_usage = 6 diff --git a/code/game/machinery/lightswitch.dm b/code/game/machinery/lightswitch.dm index 1b7781abb8..9cc4da11b1 100644 --- a/code/game/machinery/lightswitch.dm +++ b/code/game/machinery/lightswitch.dm @@ -5,6 +5,7 @@ icon_state = "light1" base_icon_state = "light" desc = "Make dark." + mouse_over_pointer = MOUSE_HAND_POINTER var/area/area = null var/otherarea = null diff --git a/code/game/objects/buckling.dm b/code/game/objects/buckling.dm index b7eab38d6b..69c81a64df 100644 --- a/code/game/objects/buckling.dm +++ b/code/game/objects/buckling.dm @@ -97,7 +97,7 @@ M.setDir(dir) buckled_mobs |= M M.update_mobility() - M.throw_alert("buckled", /atom/movable/screen/alert/restrained/buckled) + M.throw_alert("buckled", /atom/movable/screen/alert/buckled) post_buckle_mob(M) SEND_SIGNAL(src, COMSIG_MOVABLE_BUCKLE, M, force) diff --git a/code/game/objects/effects/decals/decal.dm b/code/game/objects/effects/decals/decal.dm index 31919e7649..3c1f47eedf 100644 --- a/code/game/objects/effects/decals/decal.dm +++ b/code/game/objects/effects/decals/decal.dm @@ -54,8 +54,7 @@ if(!istype(T)) //you know this will happen somehow CRASH("Turf decal initialized in an object/nullspace") var/turn_dir = 180 - dir2angle(T.dir) //Turning a dir by 0 results in a roulette of random dirs. - T.AddElement(/datum/element/decal, icon, icon_state, turn_dir ? turn(dir, turn_dir) : dir, CLEAN_GOD, color, null, null, alpha) - return INITIALIZE_HINT_QDEL + T.AddElement(/datum/element/decal, icon, icon_state, turn_dir ? turn(dir, turn_dir) : dir, CLEAN_GOD, color, null, null, alpha, FALSE) /obj/effect/turf_decal/Destroy(force) SHOULD_CALL_PARENT(FALSE) diff --git a/code/game/objects/effects/landmarks.dm b/code/game/objects/effects/landmarks.dm index 4f5ed2e643..4f2e51782f 100644 --- a/code/game/objects/effects/landmarks.dm +++ b/code/game/objects/effects/landmarks.dm @@ -222,8 +222,8 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark) name = "department_sec" icon_state = "Security Officer" -/obj/effect/landmark/start/depsec/New() - ..() +/obj/effect/landmark/start/depsec/Initialize(mapload) + . = ..() GLOB.department_security_spawns += src /obj/effect/landmark/start/depsec/Destroy() @@ -248,7 +248,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark) icon_state = "wiznerd_spawn" /obj/effect/landmark/start/wizard/Initialize(mapload) - ..() + . = ..() GLOB.wizardstart += get_turf(src) return INITIALIZE_HINT_QDEL @@ -258,7 +258,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark) icon_state = "snukeop_spawn" /obj/effect/landmark/start/nukeop/Initialize(mapload) - ..() + . = ..() GLOB.nukeop_start += get_turf(src) return INITIALIZE_HINT_QDEL @@ -268,7 +268,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark) icon_state = "snukeop_leader_spawn" /obj/effect/landmark/start/nukeop_leader/Initialize(mapload) - ..() + . = ..() GLOB.nukeop_leader_start += get_turf(src) return INITIALIZE_HINT_QDEL @@ -280,7 +280,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player) name = "New Player" /obj/effect/landmark/start/new_player/Initialize(mapload) - ..() + . = ..() GLOB.newplayer_start += get_turf(src) return INITIALIZE_HINT_QDEL @@ -310,7 +310,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player) name = "JoinLate" /obj/effect/landmark/latejoin/Initialize(mapload) - ..() + . = ..() SSjob.latejoin_trackers += get_turf(src) return INITIALIZE_HINT_QDEL @@ -335,7 +335,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player) icon_state = "xeno_spawn" /obj/effect/landmark/xeno_spawn/Initialize(mapload) - ..() + . = ..() GLOB.xeno_spawn += get_turf(src) return INITIALIZE_HINT_QDEL @@ -345,7 +345,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player) icon_state = "blob_start" /obj/effect/landmark/blobstart/Initialize(mapload) - ..() + . = ..() GLOB.blobstart += get_turf(src) return INITIALIZE_HINT_QDEL @@ -354,7 +354,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player) icon_state = "secequipment" /obj/effect/landmark/secequipment/Initialize(mapload) - ..() + . = ..() GLOB.secequipment += get_turf(src) return INITIALIZE_HINT_QDEL @@ -363,7 +363,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player) icon_state = "prisonwarp" /obj/effect/landmark/prisonwarp/Initialize(mapload) - ..() + . = ..() GLOB.prisonwarp += get_turf(src) return INITIALIZE_HINT_QDEL @@ -372,7 +372,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player) icon_state = "ert_spawn" /obj/effect/landmark/ert_spawn/Initialize(mapload) - ..() + . = ..() GLOB.emergencyresponseteamspawn += get_turf(src) return INITIALIZE_HINT_QDEL @@ -381,7 +381,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player) icon_state = "holding_facility" /obj/effect/landmark/holding_facility/Initialize(mapload) - ..() + . = ..() GLOB.holdingfacility += get_turf(src) return INITIALIZE_HINT_QDEL @@ -390,7 +390,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player) icon_state = "tdome_observer" /obj/effect/landmark/thunderdome/observe/Initialize(mapload) - ..() + . = ..() GLOB.tdomeobserve += get_turf(src) return INITIALIZE_HINT_QDEL @@ -399,7 +399,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player) icon_state = "tdome_t1" /obj/effect/landmark/thunderdome/one/Initialize(mapload) - ..() + . = ..() GLOB.tdome1 += get_turf(src) return INITIALIZE_HINT_QDEL @@ -408,7 +408,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player) icon_state = "tdome_t2" /obj/effect/landmark/thunderdome/two/Initialize(mapload) - ..() + . = ..() GLOB.tdome2 += get_turf(src) return INITIALIZE_HINT_QDEL @@ -417,7 +417,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player) icon_state = "tdome_admin" /obj/effect/landmark/thunderdome/admin/Initialize(mapload) - ..() + . = ..() GLOB.tdomeadmin += get_turf(src) return INITIALIZE_HINT_QDEL @@ -428,7 +428,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player) layer = MOB_LAYER /obj/effect/landmark/servant_of_ratvar/Initialize(mapload) - ..() + . = ..() GLOB.servant_spawns += get_turf(src) return INITIALIZE_HINT_QDEL @@ -438,7 +438,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player) icon_state = "city_of_cogs" /obj/effect/landmark/city_of_cogs/Initialize(mapload) - ..() + . = ..() GLOB.city_of_cogs_spawns += get_turf(src) return INITIALIZE_HINT_QDEL @@ -450,7 +450,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player) /obj/effect/landmark/event_spawn/New() - ..() + . = ..() GLOB.generic_event_spawns += src /obj/effect/landmark/event_spawn/Destroy() @@ -460,9 +460,9 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player) /obj/effect/landmark/ruin var/datum/map_template/ruin/ruin_template -/obj/effect/landmark/ruin/New(loc, my_ruin_template) +/obj/effect/landmark/ruin/Initialize(mapload, my_ruin_template) + . = ..() name = "ruin_[GLOB.ruin_landmarks.len + 1]" - ..(loc) ruin_template = my_ruin_template GLOB.ruin_landmarks |= src @@ -479,8 +479,8 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player) layer = BULLET_HOLE_LAYER plane = ABOVE_WALL_PLANE -/obj/effect/landmark/stationroom/New() - ..() +/obj/effect/landmark/stationroom/Initialize(mapload) + . = ..() GLOB.stationroom_landmarks += src /obj/effect/landmark/stationroom/Destroy() @@ -532,7 +532,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player) template_names = list("Engine SM" = 3, "Engine Singulo" = 3, "Engine Tesla" = 3) icon = 'icons/rooms/box/engine.dmi' -/obj/effect/landmark/stationroom/box/engine/New() +/obj/effect/landmark/stationroom/box/engine/Initialize(mapload) . = ..() template_names = CONFIG_GET(keyed_list/box_random_engine) diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index f6856437f8..f66f1c04fb 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -964,6 +964,8 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb outline_color = COLOR_THEME_DETECTIVE if("liteweb") outline_color = COLOR_THEME_LITEWEB + if("corru") + outline_color = COLOR_THEME_CORRU else //this should never happen, hopefully outline_color = COLOR_WHITE if(color) diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm index 3f64be4729..5db6aead98 100644 --- a/code/game/objects/items/devices/flashlight.dm +++ b/code/game/objects/items/devices/flashlight.dm @@ -399,8 +399,8 @@ var/emp_cur_charges = 4 var/charge_tick = 0 -/obj/item/flashlight/emp/New() - ..() +/obj/item/flashlight/emp/Initialize(mapload) + . = ..() START_PROCESSING(SSobj, src) /obj/item/flashlight/emp/Destroy() diff --git a/code/game/objects/items/documents.dm b/code/game/objects/items/documents.dm index 1172b50377..9976848bdf 100644 --- a/code/game/objects/items/documents.dm +++ b/code/game/objects/items/documents.dm @@ -37,8 +37,8 @@ var/forgedseal = 0 var/copy_type = null -/obj/item/documents/photocopy/New(loc, obj/item/documents/copy=null) - ..() +/obj/item/documents/photocopy/Initialize(mapload, obj/item/documents/copy=null) + . = ..() if(copy) copy_type = copy.type if(istype(copy, /obj/item/documents/photocopy)) // Copy Of A Copy Of A Copy diff --git a/code/game/objects/items/holy_weapons.dm b/code/game/objects/items/holy_weapons.dm index f2ef6380ee..12ad38911a 100644 --- a/code/game/objects/items/holy_weapons.dm +++ b/code/game/objects/items/holy_weapons.dm @@ -513,7 +513,6 @@ S.ckey = C.ckey S.status_flags |= GODMODE S.copy_languages(user, LANGUAGE_MASTER) //Make sure the sword can understand and communicate with the user. - S.update_atom_languages() grant_all_languages(FALSE, FALSE, TRUE) //Grants omnitongue S.AddElement(/datum/element/ghost_role_eligibility,penalize_on_ghost = TRUE) START_PROCESSING(SSprocessing,src) diff --git a/code/game/objects/items/tanks/tanks.dm b/code/game/objects/items/tanks/tanks.dm index ad18d1049e..0380c2d5ac 100644 --- a/code/game/objects/items/tanks/tanks.dm +++ b/code/game/objects/items/tanks/tanks.dm @@ -34,7 +34,6 @@ if(H.internal == src) to_chat(H, "You close [src] valve.") H.internal = null - H.update_internals_hud_icon(0) else if(!H.getorganslot(ORGAN_SLOT_BREATHING_TUBE)) if(HAS_TRAIT(H, TRAIT_NO_INTERNALS)) @@ -60,7 +59,6 @@ else to_chat(H, "You open [src] valve.") H.internal = src - H.update_internals_hud_icon(1) H.update_action_buttons_icon() diff --git a/code/game/objects/obj_defense.dm b/code/game/objects/obj_defense.dm index 831041db91..a14d207423 100644 --- a/code/game/objects/obj_defense.dm +++ b/code/game/objects/obj_defense.dm @@ -47,14 +47,14 @@ if(BURN) playsound(src.loc, 'sound/items/welder.ogg', 100, 1) -/obj/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) +/obj/hitby(atom/movable/hit_by, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) ..() - var/throwdamage = AM.throwforce - if(isobj(AM)) - var/obj/O = AM - if(O.damtype == STAMINA) + var/throwdamage = hit_by.throwforce + if(isobj(hit_by)) + var/obj/as_obj = hit_by + if(as_obj.damtype == STAMINA) throwdamage = 0 - take_damage(throwdamage, BRUTE, MELEE, 1, get_dir(src, AM)) + take_damage(throwdamage, BRUTE, MELEE, 1, get_dir(src, hit_by)) /obj/ex_act(severity, target, origin) if(resistance_flags & INDESTRUCTIBLE) diff --git a/code/game/objects/structures/beds_chairs/chair.dm b/code/game/objects/structures/beds_chairs/chair.dm index 9f115af180..bda46b4afb 100644 --- a/code/game/objects/structures/beds_chairs/chair.dm +++ b/code/game/objects/structures/beds_chairs/chair.dm @@ -17,9 +17,9 @@ /obj/structure/chair/examine(mob/user) . = ..() - . += "It's held together by a couple of bolts." + . += span_notice("It's held together by a couple of bolts.") if(!has_buckled_mobs()) - . += "Drag your sprite to sit in it." + . += span_notice("Drag your sprite to sit in it.") /obj/structure/chair/Initialize(mapload) . = ..() @@ -28,7 +28,7 @@ /obj/structure/chair/ComponentInitialize() . = ..() - AddComponent(/datum/component/simple_rotation,ROTATION_ALTCLICK | ROTATION_CLOCKWISE, CALLBACK(src, PROC_REF(can_user_rotate)),CALLBACK(src, PROC_REF(can_be_rotated)),null) + AddComponent(/datum/component/simple_rotation, ROTATION_ALTCLICK | ROTATION_CLOCKWISE, CALLBACK(src, PROC_REF(can_user_rotate)), CALLBACK(src, PROC_REF(can_be_rotated)), null) /obj/structure/chair/proc/can_be_rotated(mob/user) return TRUE diff --git a/code/game/objects/structures/fireplace.dm b/code/game/objects/structures/fireplace.dm index ec7db22cf0..280922364d 100644 --- a/code/game/objects/structures/fireplace.dm +++ b/code/game/objects/structures/fireplace.dm @@ -17,8 +17,8 @@ var/fuel_added = 0 var/flame_expiry_timer -/obj/structure/fireplace/New() - ..() +/obj/structure/fireplace/Initialize(mapload) + . = ..() START_PROCESSING(SSobj, src) /obj/structure/fireplace/Destroy() diff --git a/code/game/objects/structures/ghost_role_spawners.dm b/code/game/objects/structures/ghost_role_spawners.dm index 913cbc673c..adbad19bdf 100644 --- a/code/game/objects/structures/ghost_role_spawners.dm +++ b/code/game/objects/structures/ghost_role_spawners.dm @@ -32,7 +32,7 @@ new_spawn.undershirt = "Nude" //changing underwear/shirt/socks doesn't seem to function correctly right now because of some bug elsewhere? new_spawn.socks = "Nude" new_spawn.update_body(TRUE) - new_spawn.language_holder.selected_language = /datum/language/sylvan + new_spawn.set_active_language(/datum/language/sylvan) //Ash walker eggs: Spawns in ash walker dens in lavaland. Ghosts become unbreathing lizards that worship the Necropolis and are advised to retrieve corpses to create more ash walkers. @@ -896,7 +896,6 @@ /datum/outfit/ghostcafe/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE, client/preference_source) H.internal = H.get_item_for_held_index(1) - H.update_internals_hud_icon(1) /obj/item/storage/box/syndie_kit/chameleon/ghostcafe name = "ghost cafe costuming kit" diff --git a/code/game/objects/structures/industrial_lift.dm b/code/game/objects/structures/industrial_lift.dm index 9f04d1b710..cff9e8e2a1 100644 --- a/code/game/objects/structures/industrial_lift.dm +++ b/code/game/objects/structures/industrial_lift.dm @@ -154,12 +154,9 @@ GLOBAL_LIST_EMPTY(lifts) var/list/atom/movable/lift_load //things to move var/datum/lift_master/lift_master_datum //control from -/obj/structure/industrial_lift/New() - GLOB.lifts.Add(src) - ..() - /obj/structure/industrial_lift/Initialize(mapload) . = ..() + GLOB.lifts.Add(src) RegisterSignal(src, COMSIG_MOVABLE_CROSSED, PROC_REF(AddItemOnLift)) RegisterSignal(loc, COMSIG_ATOM_CREATED, PROC_REF(AddItemOnLift))//For atoms created on platform RegisterSignal(src, COMSIG_MOVABLE_UNCROSSED, PROC_REF(RemoveItemFromLift)) diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm index d1af57bd28..2278787583 100644 --- a/code/game/objects/structures/mirror.dm +++ b/code/game/objects/structures/mirror.dm @@ -118,23 +118,23 @@ var/list/races_blacklist = list("skeleton", "agent", "military_synth", "memezombies", "clockwork golem servant", "android", "synth", "mush", "zombie", "memezombie") var/list/choosable_races = list() -/obj/structure/mirror/magic/New() +/obj/structure/mirror/magic/Initialize(mapload) + . = ..() if(!choosable_races.len) for(var/speciestype in subtypesof(/datum/species)) var/datum/species/S = new speciestype() if(!(S.id in races_blacklist)) choosable_races += S.id - ..() -/obj/structure/mirror/magic/lesser/New() +/obj/structure/mirror/magic/lesser/Initialize(mapload) choosable_races = GLOB.roundstart_races.Copy() - ..() + return ..() -/obj/structure/mirror/magic/badmin/New() +/obj/structure/mirror/magic/badmin/Initialize(mapload) for(var/speciestype in subtypesof(/datum/species)) var/datum/species/S = new speciestype() choosable_races += S.id - ..() + return ..() /obj/structure/mirror/magic/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) if(!ishuman(user)) diff --git a/code/game/objects/structures/transit_tubes/transit_tube.dm b/code/game/objects/structures/transit_tubes/transit_tube.dm index be87c97759..0e7515b273 100644 --- a/code/game/objects/structures/transit_tubes/transit_tube.dm +++ b/code/game/objects/structures/transit_tubes/transit_tube.dm @@ -15,8 +15,8 @@ var/enter_delay = 0 var/const/time_to_unwrench = 2 SECONDS -/obj/structure/transit_tube/New(loc, newdirection) - ..(loc) +/obj/structure/transit_tube/Initialize(mapload, newdirection) + . = ..() if(newdirection) setDir(newdirection) init_tube_dirs() diff --git a/code/game/sound.dm b/code/game/sound.dm index 02c2936f8d..6ad3f3ece1 100644 --- a/code/game/sound.dm +++ b/code/game/sound.dm @@ -232,6 +232,10 @@ distance_multiplier - Can be used to multiply the distance at which the sound is /proc/get_rand_frequency() return rand(32000, 55000) //Frequency stuff only works with 45kbps oggs. +///get_rand_frequency but lower range. +/proc/get_rand_frequency_low_range() + return rand(38000, 45000) + /proc/get_sfx(soundin) if(istext(soundin)) switch(soundin) diff --git a/code/game/turfs/open/floor/catwalk_plating.dm b/code/game/turfs/open/floor/catwalk_plating.dm index ac0f3b63de..833bcdf60b 100644 --- a/code/game/turfs/open/floor/catwalk_plating.dm +++ b/code/game/turfs/open/floor/catwalk_plating.dm @@ -13,9 +13,6 @@ desc = "Flooring that shows its contents underneath. Engineers love it!" baseturfs = /turf/open/floor/plating footstep = FOOTSTEP_CATWALK - barefootstep = FOOTSTEP_CATWALK - clawfootstep = FOOTSTEP_CATWALK - heavyfootstep = FOOTSTEP_CATWALK intact = FALSE var/covered = TRUE diff --git a/code/game/turfs/simulated/floor/plating/asteroid.dm b/code/game/turfs/simulated/floor/plating/asteroid.dm index 32c1f0d42b..9e61489de5 100644 --- a/code/game/turfs/simulated/floor/plating/asteroid.dm +++ b/code/game/turfs/simulated/floor/plating/asteroid.dm @@ -20,9 +20,9 @@ var/floor_variance = 20 attachment_holes = FALSE /// Itemstack to drop when dug by a shovel - var/obj/item/stack/digResult = /obj/item/stack/ore/glass/basalt + var/obj/item/stack/dig_result = /obj/item/stack/ore/glass/basalt /// Whether the turf has been dug or not - var/dug + var/dug = FALSE /// Whether to change the turf's icon_state to "[base_icon_state]_dug" when its dugged up postdig_icon_change = TRUE @@ -38,18 +38,31 @@ /// Drops itemstack when dug and changes icon /turf/open/floor/plating/asteroid/proc/getDug() + if(dug || broken) + return dug = TRUE - new digResult(src, 5) + broken = TRUE + new dig_result(src, 5) + /* if(prob(worm_chance)) + new /obj/item/food/bait/worm(src) */ if(postdig_icon_change) icon_plating = "[environment_type]_dug" icon_state = "[environment_type]_dug" /// If the user can dig the turf /turf/open/floor/plating/asteroid/proc/can_dig(mob/user) - if(!dug) + if(!dug && !broken) return TRUE if(user) - to_chat(user, "Looks like someone has dug here already!") + balloon_alert(user, "already excavated!") + +///Refills the previously dug tile +/turf/open/floor/plating/asteroid/proc/refill_dug() + dug = FALSE + broken = FALSE + icon_state = "[environment_type]" + if(prob(floor_variance)) + icon_state = "[environment_type][rand(0,12)]" /turf/open/floor/plating/asteroid/try_replace_tile(obj/item/stack/tile/T, mob/user, params) return @@ -66,10 +79,10 @@ // /turf/open/floor/plating/asteroid/crush() // return -/turf/open/floor/plating/asteroid/attackby(obj/item/W, mob/user, params) +/turf/open/floor/plating/asteroid/attackby(obj/item/attack_item, mob/user, params) . = ..() if(!.) - if(W.tool_behaviour == TOOL_SHOVEL || W.tool_behaviour == TOOL_MINING) + if(attack_item.tool_behaviour == TOOL_SHOVEL || attack_item.tool_behaviour == TOOL_MINING) if(!can_dig(user)) return TRUE @@ -78,16 +91,16 @@ to_chat(user, "You start digging...") - if(W.use_tool(src, user, 40, volume=50)) + if(attack_item.use_tool(src, user, 4 SECONDS, volume = 50)) if(!can_dig(user)) return TRUE to_chat(user, "You dig a hole.") getDug() - SSblackbox.record_feedback("tally", "pick_used_mining", 1, W.type) + SSblackbox.record_feedback("tally", "pick_used_mining", 1, attack_item.type) return TRUE - else if(istype(W, /obj/item/storage/bag/ore)) - for(var/obj/item/stack/ore/O in src) - SEND_SIGNAL(W, COMSIG_PARENT_ATTACKBY, O) + else if(istype(attack_item, /obj/item/storage/bag/ore)) + for(var/obj/item/stack/ore/dropped_ore in src) + SEND_SIGNAL(attack_item, COMSIG_PARENT_ATTACKBY, dropped_ore) /turf/open/floor/plating/asteroid/ex_act(severity, target, origin) . = SEND_SIGNAL(src, COMSIG_ATOM_EX_ACT, severity, target) @@ -96,6 +109,9 @@ /turf/open/floor/plating/lavaland_baseturf baseturfs = /turf/open/floor/plating/asteroid/basalt/lava_land_surface +/// Used by ashstorms to replenish basalt tiles that have been dug up without going through all of them. +GLOBAL_LIST_EMPTY(dug_up_basalt) + /turf/open/floor/plating/asteroid/basalt name = "volcanic floor" baseturfs = /turf/open/floor/plating/asteroid/basalt @@ -104,10 +120,21 @@ icon_plating = "basalt" environment_type = "basalt" floor_variance = 15 - digResult = /obj/item/stack/ore/glass/basalt + dig_result = /obj/item/stack/ore/glass/basalt -// /turf/open/floor/plating/asteroid/basalt/setup_broken_states() -// return list("basalt_dug") +/turf/open/floor/plating/asteroid/basalt/getDug() + set_light(0) + GLOB.dug_up_basalt |= src + return ..() + +/turf/open/floor/plating/asteroid/basalt/Destroy() + GLOB.dug_up_basalt -= src + return ..() + +/turf/open/floor/plating/asteroid/basalt/refill_dug() + . = ..() + GLOB.dug_up_basalt -= src + set_basalt_light(src) /turf/open/floor/plating/asteroid/basalt/lava //lava underneath baseturfs = /turf/open/lava/smooth @@ -120,10 +147,6 @@ . = ..() set_basalt_light(src) -/turf/open/floor/plating/asteroid/getDug() - set_light(0) - return ..() - /proc/set_basalt_light(turf/open/floor/B) switch(B.icon_state) if("basalt1", "basalt2", "basalt3") @@ -164,7 +187,7 @@ burnt_states = list("snow_dug") bullet_sizzle = TRUE bullet_bounce_sound = null - digResult = /obj/item/stack/sheet/mineral/snow + dig_result = /obj/item/stack/sheet/mineral/snow // /turf/open/floor/plating/asteroid/snow/setup_broken_states() // return list("snow_dug") diff --git a/code/modules/admin/admin_ranks.dm b/code/modules/admin/admin_ranks.dm index 79ba4abae7..08cfbe3218 100644 --- a/code/modules/admin/admin_ranks.dm +++ b/code/modules/admin/admin_ranks.dm @@ -13,9 +13,7 @@ GLOBAL_PROTECT(protected_ranks) /datum/admin_rank/New(init_name, init_rights, init_exclude_rights, init_edit_rights) if(IsAdminAdvancedProcCall()) - var/msg = " has tried to elevate permissions!" - message_admins("[key_name_admin(usr)][msg]") - log_admin("[key_name(usr)][msg]") + alert_to_permissions_elevation_attempt(usr) if (name == "NoRank") //only del if this is a true creation (and not just a New() proc call), other wise trialmins/coders could abuse this to deadmin other admins QDEL_IN(src, 0) CRASH("Admin proc call creation of admin datum") @@ -35,9 +33,7 @@ GLOBAL_PROTECT(protected_ranks) /datum/admin_rank/Destroy() if(IsAdminAdvancedProcCall()) - var/msg = " has tried to elevate permissions!" - message_admins("[key_name_admin(usr)][msg]") - log_admin("[key_name(usr)][msg]") + alert_to_permissions_elevation_attempt(usr) return QDEL_HINT_LETMELIVE . = ..() @@ -93,9 +89,7 @@ GLOBAL_PROTECT(protected_ranks) // Adds/removes rights to this admin_rank /datum/admin_rank/proc/process_keyword(word, previous_rights=0) if(IsAdminAdvancedProcCall()) - var/msg = " has tried to elevate permissions!" - message_admins("[key_name_admin(usr)][msg]") - log_admin("[key_name(usr)][msg]") + alert_to_permissions_elevation_attempt(usr) return var/flag = admin_keyword_to_flag(word, previous_rights) if(flag) diff --git a/code/modules/admin/holder2.dm b/code/modules/admin/holder2.dm index ea16283070..2bd6dc9236 100644 --- a/code/modules/admin/holder2.dm +++ b/code/modules/admin/holder2.dm @@ -40,9 +40,7 @@ GLOBAL_PROTECT(href_token) /datum/admins/New(datum/admin_rank/R, ckey, force_active = FALSE, protected) if(IsAdminAdvancedProcCall()) - var/msg = " has tried to elevate permissions!" - message_admins("[key_name_admin(usr)][msg]") - log_admin("[key_name(usr)][msg]") + alert_to_permissions_elevation_attempt(usr) if (!target) //only del if this is a true creation (and not just a New() proc call), other wise trialmins/coders could abuse this to deadmin other admins QDEL_IN(src, 0) CRASH("Admin proc call creation of admin datum") @@ -70,17 +68,13 @@ GLOBAL_PROTECT(href_token) /datum/admins/Destroy() if(IsAdminAdvancedProcCall()) - var/msg = " has tried to elevate permissions!" - message_admins("[key_name_admin(usr)][msg]") - log_admin("[key_name(usr)][msg]") + alert_to_permissions_elevation_attempt(usr) return QDEL_HINT_LETMELIVE . = ..() /datum/admins/proc/activate() if(IsAdminAdvancedProcCall()) - var/msg = " has tried to elevate permissions!" - message_admins("[key_name_admin(usr)][msg]") - log_admin("[key_name(usr)][msg]") + alert_to_permissions_elevation_attempt(usr) return GLOB.deadmins -= target GLOB.admin_datums[target] = src @@ -91,9 +85,7 @@ GLOBAL_PROTECT(href_token) /datum/admins/proc/deactivate() if(IsAdminAdvancedProcCall()) - var/msg = " has tried to elevate permissions!" - message_admins("[key_name_admin(usr)][msg]") - log_admin("[key_name(usr)][msg]") + alert_to_permissions_elevation_attempt(usr) return GLOB.deadmins[target] = src GLOB.admin_datums -= target @@ -105,9 +97,7 @@ GLOBAL_PROTECT(href_token) /datum/admins/proc/associate(client/C) if(IsAdminAdvancedProcCall()) - var/msg = " has tried to elevate permissions!" - message_admins("[key_name_admin(usr)][msg]") - log_admin("[key_name(usr)][msg]") + alert_to_permissions_elevation_attempt(usr) return if(istype(C)) @@ -127,9 +117,7 @@ GLOBAL_PROTECT(href_token) /datum/admins/proc/disassociate() if(IsAdminAdvancedProcCall()) - var/msg = " has tried to elevate permissions!" - message_admins("[key_name_admin(usr)][msg]") - log_admin("[key_name(usr)][msg]") + alert_to_permissions_elevation_attempt(usr) return if(owner) GLOB.admins -= owner diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index eb42828744..d14b6c29f7 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -2118,8 +2118,7 @@ if(!ismob(M)) to_chat(usr, "This can only be used on instances of type /mob.") return - var/datum/language_holder/H = M.get_language_holder() - H.open_language_menu(usr) + M.get_language_holder().open_language_menu(usr) else if(href_list["traitor"]) if(!check_rights(R_ADMIN)) diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm index 284cdcf5b3..e95c2f73b6 100644 --- a/code/modules/admin/verbs/adminhelp.dm +++ b/code/modules/admin/verbs/adminhelp.dm @@ -142,9 +142,9 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new) /obj/effect/statclick/ticket_list var/current_state -/obj/effect/statclick/ticket_list/New(loc, name, state) +/obj/effect/statclick/ticket_list/Initialize(mapload, name, state) + . = ..() current_state = state - ..() /obj/effect/statclick/ticket_list/Click() GLOB.ahelp_tickets.BrowseTickets(current_state) diff --git a/code/modules/antagonists/abductor/equipment/glands/slime.dm b/code/modules/antagonists/abductor/equipment/glands/slime.dm index 36732d5fe0..f98bb403bc 100644 --- a/code/modules/antagonists/abductor/equipment/glands/slime.dm +++ b/code/modules/antagonists/abductor/equipment/glands/slime.dm @@ -10,12 +10,12 @@ /obj/item/organ/heart/gland/slime/Insert(mob/living/carbon/M, special = 0, drop_if_replaced = TRUE) ..() owner.faction |= "slime" - owner.grant_language(/datum/language/slime, TRUE, TRUE, LANGUAGE_GLAND) + owner.grant_language(/datum/language/slime, source = LANGUAGE_GLAND) /obj/item/organ/heart/gland/slime/Remove(mob/living/carbon/M, special = 0) ..() owner.faction -= "slime" - owner.remove_language(/datum/language/slime, TRUE, TRUE, LANGUAGE_GLAND) + owner.remove_language(/datum/language/slime, source = LANGUAGE_GLAND) /obj/item/organ/heart/gland/slime/activate() to_chat(owner, "You feel nauseated!") diff --git a/code/modules/antagonists/bloodsucker/datum_bloodsucker.dm b/code/modules/antagonists/bloodsucker/datum_bloodsucker.dm index 611f54e89c..6193339c5c 100644 --- a/code/modules/antagonists/bloodsucker/datum_bloodsucker.dm +++ b/code/modules/antagonists/bloodsucker/datum_bloodsucker.dm @@ -211,7 +211,7 @@ // Physiology CheckVampOrgans() // Heart, Eyes // Language - owner.current.grant_language(/datum/language/vampiric, TRUE, TRUE, LANGUAGE_BLOODSUCKER) + owner.current.grant_language(/datum/language/vampiric, source = LANGUAGE_BLOODSUCKER) owner.hasSoul = FALSE // If false, renders the character unable to sell their soul. owner.isholy = FALSE // is this person a chaplain or admin role allowed to use bibles // Disabilities diff --git a/code/modules/antagonists/bloodsucker/datum_vassal.dm b/code/modules/antagonists/bloodsucker/datum_vassal.dm index 9a2e3a1ae6..3275f251a5 100644 --- a/code/modules/antagonists/bloodsucker/datum_vassal.dm +++ b/code/modules/antagonists/bloodsucker/datum_vassal.dm @@ -48,7 +48,7 @@ objectives += vassal_objective objectives_given += vassal_objective give_thrall_eyes() - owner.current.grant_language(/datum/language/vampiric, TRUE, TRUE, LANGUAGE_VASSAL) + owner.current.grant_language(/datum/language/vampiric, source = LANGUAGE_VASSAL) // Add Antag HUD update_vassal_icons_added(owner.current, "vassal") . = ..() diff --git a/code/modules/antagonists/changeling/changeling.dm b/code/modules/antagonists/changeling/changeling.dm index 5a6a6af90b..0ed599c824 100644 --- a/code/modules/antagonists/changeling/changeling.dm +++ b/code/modules/antagonists/changeling/changeling.dm @@ -84,7 +84,7 @@ create_initial_profile() if(give_objectives) forge_objectives() - owner.current.grant_all_languages(FALSE, FALSE, TRUE) //Grants omnitongue. We are able to transform our body after all. + owner.current.get_language_holder().omnitongue = TRUE remove_clownmut() . = ..() diff --git a/code/modules/antagonists/clockcult/clockcult.dm b/code/modules/antagonists/clockcult/clockcult.dm index ed2982f861..f052afc4b4 100644 --- a/code/modules/antagonists/clockcult/clockcult.dm +++ b/code/modules/antagonists/clockcult/clockcult.dm @@ -96,7 +96,7 @@ current = mob_override GLOB.all_clockwork_mobs += current current.faction |= "ratvar" - current.grant_language(/datum/language/ratvar, TRUE, TRUE, LANGUAGE_CLOCKIE) + current.grant_language(/datum/language/ratvar, source = LANGUAGE_CLOCKIE) current.update_action_buttons_icon() //because a few clockcult things are action buttons and we may be wearing/holding them for whatever reason, we need to update buttons if(issilicon(current)) var/mob/living/silicon/S = current diff --git a/code/modules/antagonists/cult/cult.dm b/code/modules/antagonists/cult/cult.dm index 63b82f26ce..fe9f8cbe04 100644 --- a/code/modules/antagonists/cult/cult.dm +++ b/code/modules/antagonists/cult/cult.dm @@ -121,7 +121,7 @@ if(mob_override) current = mob_override current.faction |= "cult" - current.grant_language(/datum/language/narsie, TRUE, TRUE, LANGUAGE_CULTIST) + current.grant_language(/datum/language/narsie, source = LANGUAGE_CULTIST) if(!cult_team?.cult_master) vote.Grant(current) communion.Grant(current) @@ -139,7 +139,7 @@ if(mob_override) current = mob_override current.faction -= "cult" - current.remove_language(/datum/language/narsie, TRUE, TRUE, LANGUAGE_CULTIST) + current.remove_language(/datum/language/narsie, source = LANGUAGE_CULTIST) vote.Remove(current) communion.Remove(current) magic.Remove(current) diff --git a/code/modules/antagonists/ert/ert.dm b/code/modules/antagonists/ert/ert.dm index a8e57ee08b..7f45c5099c 100644 --- a/code/modules/antagonists/ert/ert.dm +++ b/code/modules/antagonists/ert/ert.dm @@ -182,9 +182,8 @@ add_antag_hud(antag_hud_type, antag_hud_name, M) if(M.hud_used) var/datum/hud/H = M.hud_used - var/atom/movable/screen/wanted/giving_wanted_lvl = new /atom/movable/screen/wanted() + var/atom/movable/screen/wanted/giving_wanted_lvl = new /atom/movable/screen/wanted(null, H) H.wanted_lvl = giving_wanted_lvl - giving_wanted_lvl.hud = H H.infodisplay += giving_wanted_lvl H.mymob.client.screen += giving_wanted_lvl diff --git a/code/modules/antagonists/gang/gang.dm b/code/modules/antagonists/gang/gang.dm index 85acfe138a..c9825501b6 100644 --- a/code/modules/antagonists/gang/gang.dm +++ b/code/modules/antagonists/gang/gang.dm @@ -113,9 +113,8 @@ add_antag_hud(antag_hud_type, antag_hud_name, M) if(M.hud_used) var/datum/hud/H = M.hud_used - var/atom/movable/screen/wanted/giving_wanted_lvl = new /atom/movable/screen/wanted() + var/atom/movable/screen/wanted/giving_wanted_lvl = new /atom/movable/screen/wanted(null, H) H.wanted_lvl = giving_wanted_lvl - giving_wanted_lvl.hud = H H.infodisplay += giving_wanted_lvl H.mymob.client.screen += giving_wanted_lvl diff --git a/code/modules/antagonists/traitor/classes/ai.dm b/code/modules/antagonists/traitor/classes/ai.dm index 0c1709ee53..8992c9ea17 100644 --- a/code/modules/antagonists/traitor/classes/ai.dm +++ b/code/modules/antagonists/traitor/classes/ai.dm @@ -65,5 +65,5 @@ /datum/traitor_class/ai/finalize_traitor(datum/antagonist/traitor/T) T.add_law_zero() T.owner.current.playsound_local(get_turf(T.owner.current), 'sound/ambience/antag/malf.ogg', 100, FALSE, pressure_affected = FALSE) - T.owner.current.grant_language(/datum/language/codespeak, TRUE, TRUE, LANGUAGE_MALF) + T.owner.current.grant_language(/datum/language/codespeak, source = LANGUAGE_MALF) return FALSE diff --git a/code/modules/antagonists/wizard/equipment/artefact.dm b/code/modules/antagonists/wizard/equipment/artefact.dm index 99e69e1fa1..4eab67ea34 100644 --- a/code/modules/antagonists/wizard/equipment/artefact.dm +++ b/code/modules/antagonists/wizard/equipment/artefact.dm @@ -41,13 +41,13 @@ var/spawn_amt_left = 20 var/spawn_fast = 0 -/obj/effect/rend/New(loc, var/spawn_type, var/spawn_amt, var/desc, var/spawn_fast) +/obj/effect/rend/Initialize(mapload, spawn_type, spawn_amt, desc, spawn_fast) + . = ..() src.spawn_path = spawn_type src.spawn_amt_left = spawn_amt src.desc = desc src.spawn_fast = spawn_fast START_PROCESSING(SSobj, src) - return /obj/effect/rend/process() if(!spawn_fast) diff --git a/code/modules/antagonists/wizard/equipment/soulstone.dm b/code/modules/antagonists/wizard/equipment/soulstone.dm index fe9770e64a..cff5260463 100644 --- a/code/modules/antagonists/wizard/equipment/soulstone.dm +++ b/code/modules/antagonists/wizard/equipment/soulstone.dm @@ -287,9 +287,7 @@ S.real_name = "Shade of [T.real_name]" T.transfer_ckey(S) S.original_mind = T.mind - S.copy_languages(T, LANGUAGE_MIND)//Copies the old mobs languages into the new mob holder. - S.update_atom_languages() - grant_all_languages(FALSE, FALSE, TRUE) //Grants omnitongue + S.get_language_holder().omnitongue = TRUE //Grants omnitongue if(user) S.faction |= "[REF(user)]" //Add the master as a faction, allowing inter-mob cooperation if(user && iscultist(user)) diff --git a/code/modules/assembly/mousetrap.dm b/code/modules/assembly/mousetrap.dm index 67bb59afd1..774c63e9fa 100644 --- a/code/modules/assembly/mousetrap.dm +++ b/code/modules/assembly/mousetrap.dm @@ -131,10 +131,10 @@ return FALSE -/obj/item/assembly/mousetrap/hitby(atom/hit_atom, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum) +/obj/item/assembly/mousetrap/hitby(atom/movable/hit_atom, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) if(!armed) return ..() - visible_message("[src] is triggered by [hit_atom].") + visible_message(span_warning("[src] is triggered by [hit_atom].")) triggered(null) diff --git a/code/modules/asset_cache/assets/font.dm b/code/modules/asset_cache/assets/font.dm new file mode 100644 index 0000000000..f665c02f91 --- /dev/null +++ b/code/modules/asset_cache/assets/font.dm @@ -0,0 +1,9 @@ +/datum/asset/simple/namespaced/fonts + parents = list("fonts.css" = 'interface/fonts/fonts.css') + +/datum/asset/simple/namespaced/fonts/New() + for(var/datum/font/font as anything in subtypesof(/datum/font)) + var/file = "[initial(font.font_family)]" + var/file_name = copytext(file, findlasttext(file, "/") + 1) + assets[file_name] = file(file) + return ..() diff --git a/code/modules/atmospherics/gasmixtures/auxgm.dm b/code/modules/atmospherics/gasmixtures/auxgm.dm index 0318e06abe..9c6a533646 100644 --- a/code/modules/atmospherics/gasmixtures/auxgm.dm +++ b/code/modules/atmospherics/gasmixtures/auxgm.dm @@ -186,6 +186,6 @@ GLOBAL_DATUM_INIT(gas_data, /datum/auxgm, new) appearance_flags = TILE_BOUND vis_flags = NONE -/obj/effect/overlay/gas/New(state) +/obj/effect/overlay/gas/Initialize(mapload, state) . = ..() icon_state = state diff --git a/code/modules/buildmode/buttons.dm b/code/modules/buildmode/buttons.dm index e29739f5ad..f3f1105a5c 100644 --- a/code/modules/buildmode/buttons.dm +++ b/code/modules/buildmode/buttons.dm @@ -1,5 +1,6 @@ /atom/movable/screen/buildmode icon = 'icons/misc/buildmode.dmi' + mouse_over_pointer = MOUSE_HAND_POINTER var/datum/buildmode/bd // If we don't do this, we get occluded by item action buttons layer = ABOVE_HUD_LAYER diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index 2d5cd2027b..60904df090 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -171,6 +171,15 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( to_chat(src, "Become a BYOND member to access member-perks and features, as well as support the engine that makes this game possible. Only 10 bucks for 3 months! Click Here to find out more.") return FALSE return TRUE + +/client/proc/is_localhost() + var/static/localhost_addresses = list( + "127.0.0.1", + "::1", + null, + ) + return address in localhost_addresses + /* * Call back proc that should be checked in all paths where a client can send messages * diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 0c910556df..0ed2627b47 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -483,11 +483,14 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "
" dat += "
" - var/savefile/client_file = new(user.client.Import()) + var/file = user.client.Import() + var/savefile/client_file var/savefile_name - if(istype(client_file, /savefile)) - if(!client_file["deleted"] || savefile_needs_update(client_file) != -2) - client_file["real_name"] >> savefile_name + if(file) + client_file = new(file) + if(istype(client_file, /savefile)) + if(!client_file["deleted"] || savefile_needs_update(client_file) != -2) + client_file["real_name"] >> savefile_name dat += "Local storage: [savefile_name ? savefile_name : "Empty"]" dat += "
" dat += "Export current slot" @@ -1462,11 +1465,11 @@ GLOBAL_LIST_EMPTY(preferences_datums) if(user.client) if(unlock_content) dat += "BYOND Membership Publicity: [(toggles & MEMBER_PUBLIC) ? "Public" : "Hidden"]
" - if(unlock_content || check_rights_for(user.client, R_ADMIN)) + if(unlock_content || is_admin(user.client)) dat += "OOC Color: [ooccolor ? ooccolor : GLOB.normal_ooc_colour] Change
" dat += "Antag OOC Color: [aooccolor ? aooccolor : GLOB.normal_aooc_colour] Change
" - if(user.client.holder) + if(is_admin(user.client)) dat += "

Admin Settings

" dat += "Adminhelp Sounds: [(toggles & SOUND_ADMINHELP)?"Enabled":"Disabled"]
" dat += "Announce Login: [(toggles & ANNOUNCE_LOGIN)?"Enabled":"Disabled"]
" diff --git a/code/modules/clothing/spacesuits/chronosuit.dm b/code/modules/clothing/spacesuits/chronosuit.dm index f5c2c44f58..9e387dab3f 100644 --- a/code/modules/clothing/spacesuits/chronosuit.dm +++ b/code/modules/clothing/spacesuits/chronosuit.dm @@ -11,7 +11,7 @@ /obj/item/clothing/head/helmet/space/chronos/dropped(mob/user) if(suit) suit.deactivate(1, 1) - ..() + return ..() /obj/item/clothing/suit/space/chronos name = "Chronosuit" @@ -23,23 +23,22 @@ resistance_flags = FIRE_PROOF | ACID_PROOF mutantrace_variation = STYLE_DIGITIGRADE var/list/chronosafe_items = list(/obj/item/chrono_eraser, /obj/item/gun/energy/chrono_gun) - var/obj/item/clothing/head/helmet/space/chronos/helmet = null - var/obj/effect/chronos_cam/camera = null - var/datum/action/innate/chrono_teleport/teleport_now = new + var/obj/item/clothing/head/helmet/space/chronos/helmet + var/obj/effect/chronos_cam/camera + var/datum/action/innate/chrono_teleport/teleport_now var/activating = 0 var/activated = 0 - var/cooldowntime = 50 //deciseconds + var/cooldowntime = 5 SECONDS var/teleporting = 0 var/phase_timer_id -/obj/item/clothing/suit/space/chronos/New() - ..() +/obj/item/clothing/suit/space/chronos/Initialize(mapload) + . = ..() + teleport_now = new(src) teleport_now.chronosuit = src - teleport_now.target = src /obj/item/clothing/suit/space/chronos/proc/new_camera(mob/user) - if(camera) - qdel(camera) + QDEL_NULL(camera) camera = new /obj/effect/chronos_cam(user) camera.holder = user camera.chronosuit = src @@ -55,7 +54,7 @@ /obj/item/clothing/suit/space/chronos/dropped(mob/user) if(activated) deactivate() - ..() + return ..() /obj/item/clothing/suit/space/chronos/emp_act(severity) . = ..() @@ -64,8 +63,8 @@ var/mob/living/carbon/human/user = src.loc if(severity >= 70) if(activated && user && ishuman(user) && (user.wear_suit == src)) - to_chat(user, "E:FATAL:RAM_READ_FAIL\nE:FATAL:STACK_EMPTY\nE:FATAL:READ_NULL_POINT\nE:FATAL:PWR_BUS_OVERLOAD") - to_chat(user, "An electromagnetic pulse disrupts your [name] and violently tears you out of time-bluespace!") + to_chat(user, span_danger("E:FATAL:RAM_READ_FAIL\nE:FATAL:STACK_EMPTY\nE:FATAL:READ_NULL_POINT\nE:FATAL:PWR_BUS_OVERLOAD")) + to_chat(user, span_userdanger("An electromagnetic pulse disrupts your [name] and violently tears you out of time-bluespace!")) user.emote("scream") deactivate(1, 1) @@ -75,23 +74,24 @@ if(phase_timer_id) deltimer(phase_timer_id) phase_timer_id = 0 - if(istype(user)) - if(to_turf) - user.forceMove(to_turf) - user.SetStun(0) - user.SetNextAction(0, considered_action = FALSE, immediate = FALSE) - user.alpha = 255 - user.update_atom_colour() - user.animate_movement = FORWARD_STEPS - user.mob_transforming = 0 - user.anchored = FALSE - teleporting = 0 - for(var/obj/item/I in user.held_items) - REMOVE_TRAIT(I, TRAIT_NODROP, CHRONOSUIT_TRAIT) - if(camera) - camera.remove_target_ui() - camera.forceMove(user) - teleport_now.UpdateButtons() + if(!istype(user)) + return + if(to_turf) + user.forceMove(to_turf) + user.SetStun(0) + user.SetNextAction(0, considered_action = FALSE, immediate = FALSE) + user.alpha = 255 + user.update_atom_colour() + user.animate_movement = FORWARD_STEPS + user.mob_transforming = 0 + user.anchored = FALSE + teleporting = 0 + for(var/obj/item/I in user.held_items) + REMOVE_TRAIT(I, TRAIT_NODROP, CHRONOSUIT_TRAIT) + if(camera) + camera.remove_target_ui() + camera.forceMove(user) + teleport_now.UpdateButtons() /obj/item/clothing/suit/space/chronos/proc/chronowalk(atom/location) var/mob/living/carbon/human/user = src.loc @@ -238,7 +238,7 @@ var/mob/holder = null var/phase_time = 0 var/phase_time_length = 3 - var/atom/movable/screen/chronos_target/target_ui = null + var/atom/movable/screen/chronos_target/target_ui var/obj/item/clothing/suit/space/chronos/chronosuit /obj/effect/chronos_cam/singularity_act() @@ -249,17 +249,14 @@ /obj/effect/chronos_cam/proc/create_target_ui() if(holder && holder.client && chronosuit) - if(target_ui) - remove_target_ui() - target_ui = new(null, holder) + remove_target_ui() + target_ui = new(null, holder.hud_used, holder) holder.client.screen += target_ui /obj/effect/chronos_cam/proc/remove_target_ui() - if(target_ui) - qdel(target_ui) - target_ui = null + QDEL_NULL(target_ui) -/obj/effect/chronos_cam/relaymove(var/mob/user, direction) +/obj/effect/chronos_cam/relaymove(mob/user, direction) if(!holder) qdel(src) return @@ -305,13 +302,13 @@ color = "#ff3311" blend_mode = BLEND_SUBTRACT -/atom/movable/screen/chronos_target/New(loc, var/mob/living/carbon/human/user) - if(user) - var/icon/user_icon = getFlatIcon(user) - icon = user_icon - transform = user.transform - else - qdel(src) +/atom/movable/screen/chronos_target/Initialize(mapload, datum/hud/hud_owner, mob/living/carbon/human/user) + . = ..() + if(!user) + return INITIALIZE_HINT_QDEL + var/icon/user_icon = getFlatIcon(user) + icon = user_icon + transform = user.transform /datum/action/innate/chrono_teleport name = "Teleport Now" @@ -324,6 +321,7 @@ return (chronosuit && chronosuit.activated && chronosuit.camera && !chronosuit.teleporting) /datum/action/innate/chrono_teleport/Activate() - if(IsAvailable()) - if(chronosuit.camera) - chronosuit.chronowalk(chronosuit.camera) + if(!IsAvailable()) + return + if(chronosuit.camera) + chronosuit.chronowalk(chronosuit.camera) diff --git a/code/modules/clothing/suits/_suits.dm b/code/modules/clothing/suits/_suits.dm index 6806f73c65..5e83ddacb1 100644 --- a/code/modules/clothing/suits/_suits.dm +++ b/code/modules/clothing/suits/_suits.dm @@ -27,10 +27,11 @@ if(ishuman(M) && M.w_uniform) var/obj/item/clothing/under/U = M.w_uniform //SANDSTORM EDIT - if(istype(U) && length(U.attached_accessories)) - for(var/obj/item/clothing/accessory/attached in U.attached_accessories) - if(attached.above_suit) - . += U.accessory_overlays + if(istype(U) && !CHECK_BITFIELD(U.flags_inv, HIDEACCESSORY)) + for(var/obj/item/clothing/accessory/attached as anything in U.attached_accessories) + if(CHECK_BITFIELD(attached.flags_inv, HIDEACCESSORY) || !attached.above_suit) + continue + . += attached.build_worn_icon() //SANDSTORM EDIT END /obj/item/clothing/suit/update_clothes_damaged_state() diff --git a/code/modules/clothing/under/_under.dm b/code/modules/clothing/under/_under.dm index 7914dc0e72..cd558d2978 100644 --- a/code/modules/clothing/under/_under.dm +++ b/code/modules/clothing/under/_under.dm @@ -24,8 +24,7 @@ var/dummy_thick = FALSE // is able to hold accessories on its item //SANDSTORM EDIT - Removed the old attached accessory system. We use a list of accessories instead. var/max_accessories = 3 - var/list/obj/item/clothing/accessory/attached_accessories = list() - var/list/mutable_appearance/accessory_overlays = list() + var/list/obj/item/clothing/accessory/attached_accessories //SANDSTORM EDIT END /obj/item/clothing/under/worn_overlays(isinhands = FALSE, icon_file, used_state, style_flags = NONE) @@ -36,8 +35,12 @@ . += mutable_appearance('icons/effects/item_damage.dmi', "damageduniform") if(blood_DNA) . += mutable_appearance('icons/effects/blood.dmi', "uniformblood", color = blood_DNA_to_color(), blend_mode = blood_DNA_to_blend()) - if(length(accessory_overlays)) - . += accessory_overlays + if(CHECK_BITFIELD(flags_inv, HIDEACCESSORY)) + return + for(var/obj/item/clothing/accessory/attached_accessory as anything in attached_accessories) + if(CHECK_BITFIELD(attached_accessory.flags_inv, HIDEACCESSORY)) + continue + . += attached_accessory.build_worn_icon() /obj/item/clothing/under/attackby(obj/item/I, mob/user, params) if((sensordamage || (has_sensor < HAS_SENSORS && has_sensor != NO_SENSORS)) && istype(I, /obj/item/stack/cable_coil)) @@ -125,68 +128,60 @@ body_parts_covered |= CHEST // Sandstorm edit - for(var/obj/item/clothing/accessory/attached_accessory in attached_accessories) - if(attached_accessory && slot != ITEM_SLOT_HANDS && ishuman(user)) - var/mob/living/carbon/human/H = user + var/must_update = FALSE + for(var/obj/item/clothing/accessory/attached_accessory as anything in attached_accessories) + if(attached_accessory && slot == ITEM_SLOT_ICLOTHING && ishuman(user)) attached_accessory.on_uniform_equip(src, user) - if(attached_accessory.above_suit) - H.update_inv_wear_suit() + if(attached_accessory.above_suit) + must_update = TRUE + if(must_update) + user.update_inv_wear_suit() // /obj/item/clothing/under/dropped(mob/user) // Sandstorm edit - for(var/obj/item/clothing/accessory/attached_accessory in attached_accessories) + var/must_update = FALSE + for(var/obj/item/clothing/accessory/attached_accessory as anything in attached_accessories) attached_accessory.on_uniform_dropped(src, user) - if(ishuman(user)) - var/mob/living/carbon/human/H = user - if(attached_accessory.above_suit) - H.update_inv_wear_suit() + if(attached_accessory.above_suit) + must_update = TRUE + if(must_update) + user.update_inv_wear_suit() // ..() -/obj/item/clothing/under/proc/attach_accessory(obj/item/I, mob/user, notifyAttach = 1) +/obj/item/clothing/under/proc/attach_accessory(obj/item/clothing/accessory/accessory, mob/user, notifyAttach = 1) . = FALSE - if(istype(I, /obj/item/clothing/accessory) && !istype(I, /obj/item/clothing/accessory/ring)) - var/obj/item/clothing/accessory/A = I - if(length(attached_accessories) >= max_accessories) - if(user) - to_chat(user, "[src] already has [length(attached_accessories)] accessories.") - return - if(dummy_thick) - if(user) - to_chat(user, "[src] is too bulky and cannot have accessories attached to it!") - return - else - if(user && !user.temporarilyRemoveItemFromInventory(I)) - return - if(!A.attach(src, user)) - return + if(!istype(accessory)) + return + if(istype(accessory, /obj/item/clothing/accessory/ring)) + return + if(length(attached_accessories) >= max_accessories) + if(user) + to_chat(user, span_warning("[src] already has [length(attached_accessories)] accessories.")) + return + if(dummy_thick) + if(user) + to_chat(user, span_warning("[src] is too bulky and cannot have accessories attached to it!")) + return + if(user && !user.temporarilyRemoveItemFromInventory(accessory)) + return + if(!accessory.attach(src, user)) + return - if(user && notifyAttach) - to_chat(user, "You attach [I] to [src].") + if(user && notifyAttach) + to_chat(user, span_notice("You attach [accessory] to [src].")) - if((flags_inv & HIDEACCESSORY) || (A.flags_inv & HIDEACCESSORY)) - return TRUE + if((flags_inv & HIDEACCESSORY) || (accessory.flags_inv & HIDEACCESSORY)) + return TRUE - //SANDSTORM EDIT - accessory_overlays = list(mutable_appearance('icons/mob/clothing/accessories.dmi', "blank")) - for(var/obj/item/clothing/accessory/attached_accessory in attached_accessories) - var/datum/element/polychromic/polychromic = LAZYACCESS(attached_accessory.comp_lookup, "item_worn_overlays") - if(!polychromic) - var/mutable_appearance/accessory_overlay = mutable_appearance(attached_accessory.mob_overlay_icon, attached_accessory.item_state || attached_accessory.icon_state, ABOVE_HUD_LAYER) - accessory_overlay.alpha = attached_accessory.alpha - accessory_overlay.color = attached_accessory.color - accessory_overlays += accessory_overlay - else - polychromic.apply_worn_overlays(attached_accessory, FALSE, attached_accessory.mob_overlay_icon, attached_accessory.item_state || attached_accessory.icon_state, NONE, accessory_overlays) - //SANDSTORM EDIT END + if(ishuman(loc)) + var/mob/living/carbon/human/H = loc + H.update_inv_w_uniform() + if(accessory.above_suit) + H.update_inv_wear_suit() - if(ishuman(loc)) - var/mob/living/carbon/human/H = loc - H.update_inv_w_uniform() - H.update_inv_wear_suit() - - return TRUE + return TRUE /obj/item/clothing/under/proc/remove_accessory(mob/user) if(!isliving(user)) @@ -194,22 +189,21 @@ if(!can_use(user)) return - //SKYRAT EDIT - if(length(attached_accessories)) - var/obj/item/clothing/accessory/A = attached_accessories[length(attached_accessories)] - //SKYRAT EDIT END - A.detach(src, user) - if(user.put_in_hands(A)) - to_chat(user, "You detach [A] from [src].") - else - to_chat(user, "You detach [A] from [src] and it falls on the floor.") + if(!LAZYLEN(attached_accessories)) + return + var/obj/item/clothing/accessory/accessory = attached_accessories[length(attached_accessories)] + accessory.detach(src, user) + if(user.put_in_hands(accessory)) + to_chat(user, span_notice("You detach [accessory] from [src].")) + else + to_chat(user, span_notice("You detach [accessory] from [src] and it falls on the floor.")) - if(ishuman(loc)) - var/mob/living/carbon/human/H = loc - H.update_inv_w_uniform() + if(ishuman(loc)) + var/mob/living/carbon/human/H = loc + H.update_inv_w_uniform() + if(accessory.above_suit) H.update_inv_wear_suit() - /obj/item/clothing/under/examine(mob/user) . = ..() if(can_adjust) @@ -234,10 +228,9 @@ . += "Its vital tracker appears to be enabled." if(SENSOR_COORDS) . += "Its vital tracker and tracking beacon appear to be enabled." - if(length(attached_accessories)) - for(var/obj/item/clothing/accessory/attached_accessory in attached_accessories) - . += "\A [attached_accessory] is attached to it." - //SKYRAT EDIT END + for(var/obj/item/clothing/accessory/attached_accessory as anything in attached_accessories) + . += "\A [attached_accessory] is attached to it." + //SANDSTORM EDIT END /obj/item/clothing/under/verb/toggle() set name = "Adjust Suit Sensors" diff --git a/code/modules/clothing/under/accessories.dm b/code/modules/clothing/under/accessories.dm index 011f64d3ec..cbfb9baf90 100644 --- a/code/modules/clothing/under/accessories.dm +++ b/code/modules/clothing/under/accessories.dm @@ -2,7 +2,7 @@ name = "Accessory" desc = "Something has gone wrong!" icon = 'icons/obj/clothing/accessories.dmi' - //skyrat edit + //sandstorm edit mob_overlay_icon = 'icons/mob/clothing/accessories.dmi' // icon_state = "plasma" @@ -13,48 +13,41 @@ var/above_suit = FALSE var/minimize_when_attached = TRUE // TRUE if shown as a small icon in corner, FALSE if overlayed var/datum/component/storage/detached_pockets - //skyrat edit - var/current_uniform = null - // -/obj/item/clothing/accessory/proc/attach(obj/item/clothing/under/U, user) +/obj/item/clothing/accessory/proc/attach(obj/item/clothing/under/uniform, user) var/datum/component/storage/storage = GetComponent(/datum/component/storage) if(storage) - if(SEND_SIGNAL(U, COMSIG_CONTAINS_STORAGE)) + if(SEND_SIGNAL(uniform, COMSIG_CONTAINS_STORAGE)) return FALSE - U.TakeComponent(storage) + uniform.TakeComponent(storage) detached_pockets = storage - //SKYRAT EDIT - U.attached_accessories |= src - force_unto(U) - current_uniform = U - //SKYRAT EDIT END - forceMove(U) + //SANDSTORM EDIT + LAZYADD(uniform.attached_accessories, src) + force_unto(uniform) + //SANDSTORM EDIT END + forceMove(uniform) - if (islist(U.armor) || isnull(U.armor)) // This proc can run before /obj/Initialize has run for U and src, - U.armor = getArmor(arglist(U.armor)) // we have to check that the armor list has been transformed into a datum before we try to call a proc on it + if (islist(uniform.armor) || isnull(uniform.armor)) // This proc can run before /obj/Initialize has run for uniform and src, + uniform.armor = getArmor(arglist(uniform.armor)) // we have to check that the armor list has been transformed into a datum before we try to call a proc on it // This is safe to do as /obj/Initialize only handles setting up the datum if actually needed. if (islist(armor) || isnull(armor)) armor = getArmor(arglist(armor)) - U.armor = U.armor.attachArmor(armor) + uniform.armor = uniform.armor.attachArmor(armor) if(isliving(user)) - on_uniform_equip(U, user) + on_uniform_equip(uniform, user) return TRUE -/obj/item/clothing/accessory/proc/detach(obj/item/clothing/under/U, user) - if(detached_pockets && detached_pockets.parent == U) +/obj/item/clothing/accessory/proc/detach(obj/item/clothing/under/uniform, user) + if(detached_pockets && detached_pockets.parent == uniform) TakeComponent(detached_pockets) - U.armor = U.armor.detachArmor(armor) - //SANDSTORM EDIT - current_uniform = null - //SANDSTORM EDIT END + uniform.armor = uniform.armor.detachArmor(armor) if(isliving(user)) - on_uniform_dropped(U, user) + on_uniform_dropped(uniform, user) if(minimize_when_attached) transform *= 2 @@ -62,48 +55,36 @@ pixel_y = 0 layer = initial(layer) plane = initial(plane) - U.cut_overlays() - U.attached_accessories -= src - U.accessory_overlays = list() - if(length(U.attached_accessories)) - U.accessory_overlays = list(mutable_appearance('icons/mob/clothing/accessories.dmi', "blank")) - for(var/obj/item/clothing/accessory/attached_accessory in U.attached_accessories) - attached_accessory.force_unto(U) - var/datum/element/polychromic/polychromic = LAZYACCESS(attached_accessory.comp_lookup, "item_worn_overlays") - if(!polychromic) - var/mutable_appearance/accessory_overlay = mutable_appearance(attached_accessory.mob_overlay_icon, attached_accessory.item_state || attached_accessory.icon_state, ABOVE_HUD_LAYER) - accessory_overlay.alpha = attached_accessory.alpha - accessory_overlay.color = attached_accessory.color - U.accessory_overlays += accessory_overlay - else - polychromic.apply_worn_overlays(attached_accessory, FALSE, attached_accessory.mob_overlay_icon, attached_accessory.item_state || attached_accessory.icon_state, NONE, U.accessory_overlays) + uniform.cut_overlays() + LAZYREMOVE(uniform.attached_accessories, src) + for(var/obj/item/clothing/accessory/attached_accessory as anything in uniform.attached_accessories) + uniform.add_overlay(attached_accessory) //SANDSTORM EDIT -/obj/item/clothing/accessory/proc/force_unto(obj/item/clothing/under/U) +/obj/item/clothing/accessory/proc/force_unto(obj/item/clothing/under/uniform) layer = FLOAT_LAYER plane = FLOAT_PLANE if(minimize_when_attached) - if(current_uniform != U) - transform *= 0.5 //halve the size so it doesn't overpower the under - pixel_x += 8 - pixel_y -= 8 - if(length(U.attached_accessories) > 1) - if(length(U.attached_accessories) <= 3 && !current_uniform) - pixel_y += 8 * (length(U.attached_accessories) - 1) - else if((length(U.attached_accessories) > 3) && (length(U.attached_accessories) <= 6) && !current_uniform) - pixel_x -= 8 - pixel_y += 8 * (length(U.attached_accessories) - 4) - else if((length(U.attached_accessories) > 6) && (length(U.attached_accessories) <= 9) && !current_uniform) - pixel_x -= 16 - pixel_y += 8 * (length(U.attached_accessories) - 7) - else - if(current_uniform != U) + transform *= 0.5 //halve the size so it doesn't overpower the under + pixel_x += 8 + pixel_y -= 8 + if(length(uniform.attached_accessories) > 1) + switch(LAZYLEN(uniform.attached_accessories)) + if(2 to 3) + pixel_y += 8 * (length(uniform.attached_accessories) - 1) + if(4 to 6) + pixel_x -= 8 + pixel_y += 8 * (length(uniform.attached_accessories) - 4) + if(7 to 9) + pixel_x -= 16 + pixel_y += 8 * (length(uniform.attached_accessories) - 7) + else //we ran out of space for accessories, so we just throw shit at the wall pixel_x = 0 pixel_y = 0 pixel_x += rand(-16, 16) pixel_y += rand(-16, 16) - U.add_overlay(src) + uniform.add_overlay(src) //SANDSTORM EDIT END /obj/item/clothing/accessory/proc/on_uniform_equip(obj/item/clothing/under/U, user) @@ -122,9 +103,9 @@ /obj/item/clothing/accessory/examine(mob/user) . = ..() - . += "\The [src] can be attached to [istype(src, /obj/item/clothing/accessory/ring) ? "gloves" : "a uniform"]. Alt-click to remove it once attached." + . += span_notice("\The [src] can be attached to [istype(src, /obj/item/clothing/accessory/ring) ? "gloves" : "a uniform"]. Alt-click to remove it once attached.") if(initial(above_suit)) - . += "\The [src] can be worn above or below your suit. Ctrl-click to toggle." + . += span_notice("\The [src] can be worn above or below your suit. Ctrl-click to toggle.") ////////////// //Waistcoats// diff --git a/code/modules/events/sentience.dm b/code/modules/events/sentience.dm index 8cccaba68b..d3a9172b96 100644 --- a/code/modules/events/sentience.dm +++ b/code/modules/events/sentience.dm @@ -55,7 +55,7 @@ SG.transfer_ckey(SA, FALSE) - SA.grant_all_languages(TRUE, FALSE, FALSE) + SA.grant_all_languages(UNDERSTOOD_LANGUAGE, grant_omnitongue = FALSE, source = LANGUAGE_ATOM) SA.sentience_act() diff --git a/code/modules/holodeck/items.dm b/code/modules/holodeck/items.dm index 73e55487bf..48bacef977 100644 --- a/code/modules/holodeck/items.dm +++ b/code/modules/holodeck/items.dm @@ -122,10 +122,10 @@ if (isitem(AM) && !istype(AM,/obj/item/projectile)) if(prob(50)) AM.forceMove(get_turf(src)) - visible_message("Swish! [AM] lands in [src].") + visible_message(span_warning("Swish! [AM] lands in [src].")) return else - visible_message("[AM] bounces off of [src]'s rim!") + visible_message(span_danger("[AM] bounces off of [src]'s rim!")) return ..() else return ..() diff --git a/code/modules/jobs/job_types/curator.dm b/code/modules/jobs/job_types/curator.dm index 6b5707d76f..a4dbb20c5c 100644 --- a/code/modules/jobs/job_types/curator.dm +++ b/code/modules/jobs/job_types/curator.dm @@ -50,4 +50,5 @@ if(visualsOnly) return - H.grant_all_languages(TRUE, TRUE, TRUE, LANGUAGE_CURATOR) + H.grant_all_languages(source = LANGUAGE_CURATOR) + H.remove_blocked_language(GLOB.all_languages, source=LANGUAGE_ALL) diff --git a/code/modules/language/codespeak.dm b/code/modules/language/codespeak.dm index d31d82e769..1ae4be1cf4 100644 --- a/code/modules/language/codespeak.dm +++ b/code/modules/language/codespeak.dm @@ -49,7 +49,7 @@ return to_chat(user, "You start skimming through [src], and suddenly your mind is filled with codewords and responses.") - user.grant_language(/datum/language/codespeak, TRUE, TRUE, LANGUAGE_MIND) + user.grant_language(/datum/language/codespeak, source = LANGUAGE_MIND) use_charge(user) @@ -68,7 +68,7 @@ M.visible_message("[user] beats [M] over the head with [src]!", "[user] beats you over the head with [src]!", "You hear smacking.") else M.visible_message("[user] teaches [M] by beating [M.p_them()] over the head with [src]!", "As [user] hits you with [src], codewords and responses flow through your mind.", "You hear smacking.") - M.grant_language(/datum/language/codespeak, TRUE, TRUE, LANGUAGE_MIND) + M.grant_language(/datum/language/codespeak, source = LANGUAGE_MIND) use_charge(user) /obj/item/codespeak_manual/proc/use_charge(mob/user) diff --git a/code/modules/language/language_holder.dm b/code/modules/language/language_holder.dm index 82bca377cf..91186ad5c9 100644 --- a/code/modules/language/language_holder.dm +++ b/code/modules/language/language_holder.dm @@ -1,23 +1,28 @@ -/*!Language holders will either exist in an atom/movable or a mind. Creation of language holders happens +/*!Language holders will either exist in an atom/movable. Creation of language holders happens automatically when they are needed, for example when something tries to speak. Where a mind is available, the mind language holder will be the one "in charge". The mind holder will update its languages based on the atom holder, and will get updated as part of transformations and other events that cause new languages to become available. + Every language holder has three lists of languages (and sources for each of them): - understood_languages - spoken_languages - blocked_languages + Understood languages let you understand them, spoken languages lets you speak them (if your tongue is compatible), and blocked languages will let you do neither no matter what the source of the language is. + Language holders are designed to mostly only ever require the use the helpers in atom/movable to achieve your goals, but it is also possible to work on them directly if needed. Any adding and removing of languages and sources should only happen through the procs, as directly changing these will mess something up somewhere down the line. + All atom movables have the initial_language_holder var which allows you to set the default language holder to create. For example, /datum/language_holder/alien will give you xenocommon and a block for galactic common. Human species also have a default language holder var that will be updated on species change, initial_species_holder. + Key procs * [grant_language](atom/movable.html#proc/grant_language) * [remove_language](atom/movable.html#proc/remove_language) @@ -28,83 +33,86 @@ Key procs * [has_language](atom/movable.html#proc/has_language) * [can_speak_language](atom/movable.html#proc/can_speak_language) * [get_selected_language](atom/movable.html#proc/get_selected_language) -* [update_atom_languages](atom/movable.html#proc/update_atom_languages) */ /datum/language_holder - /// Understood languages. - var/list/understood_languages = list(/datum/language/common = list(LANGUAGE_MIND)) - /// A list of languages that can be spoken. Tongue organ may also set limits beyond this list. + /// Lazyassoclist of all understood languages + var/list/understood_languages = list(/datum/language/common = list(LANGUAGE_ATOM)) + /// Lazyassoclist of languages that can be spoken. + /// Tongue organ may also set limits beyond this list. var/list/spoken_languages = list(/datum/language/common = list(LANGUAGE_ATOM)) - /// A list of blocked languages. Used to prevent understanding and speaking certain languages, ie for certain mobs, mutations etc. - var/list/blocked_languages = list() - /// If true, overrides tongue limitations. + /// Lazyassoclist of blocked languages. + /// Used to prevent understanding and speaking certain languages, ie for certain mobs, mutations etc. + var/list/blocked_languages + /// If true, overrides tongue aforementioned limitations. var/omnitongue = FALSE /// Handles displaying the language menu UI. var/datum/language_menu/language_menu /// Currently spoken language var/selected_language /// Tracks the entity that owns the holder. - var/owner + var/atom/movable/owner /// Initializes, and copies in the languages from the current atom if available. -/datum/language_holder/New(_owner) - owner = _owner - if(istype(owner, /datum/mind)) - var/datum/mind/M = owner - if(M.current) - update_atom_languages(M.current) - get_selected_language() +/datum/language_holder/New(atom/new_owner) + if(new_owner) + if(QDELETED(new_owner)) + CRASH("Langauge holder added to a qdeleting thing, what the fuck [text_ref(new_owner)]") + if(!ismovable(new_owner)) + CRASH("Language holder being added to a non-movable thing, this is invalid (was: [new_owner] / [new_owner.type])") + + owner = new_owner + + // If we have an owner, we'll set a default selected language + if(owner) + get_selected_language() /datum/language_holder/Destroy() QDEL_NULL(language_menu) + owner = null return ..() /// Grants the supplied language. -/datum/language_holder/proc/grant_language(language, understood = TRUE, spoken = TRUE, source = LANGUAGE_MIND) - if(understood) - if(!understood_languages[language]) - understood_languages[language] = list() - understood_languages[language] |= source +/datum/language_holder/proc/grant_language(language, language_flags = ALL, source = LANGUAGE_MIND) + if(language_flags & UNDERSTOOD_LANGUAGE) + LAZYORASSOCLIST(understood_languages, language, source) . = TRUE - if(spoken) - if(!spoken_languages[language]) - spoken_languages[language] = list() - spoken_languages[language] |= source + if(language_flags & SPOKEN_LANGUAGE) + LAZYORASSOCLIST(spoken_languages, language, source) . = TRUE + return . + /// Grants every language to understood and spoken, and gives omnitongue. -/datum/language_holder/proc/grant_all_languages(understood = TRUE, spoken = TRUE, grant_omnitongue = TRUE, source = LANGUAGE_MIND) +/datum/language_holder/proc/grant_all_languages(language_flags = ALL, grant_omnitongue = TRUE, source = LANGUAGE_MIND) for(var/language in GLOB.all_languages) - grant_language(language, understood, spoken, source) - if(grant_omnitongue) // Overrides tongue limitations. + grant_language(language, language_flags, source) + if(grant_omnitongue) // Overrides tongue limitations. omnitongue = TRUE return TRUE /// Removes a single language or source, removing all sources returns the pre-removal state of the language. -/datum/language_holder/proc/remove_language(language, understood = TRUE, spoken = TRUE, source = LANGUAGE_ALL) - if(understood && understood_languages[language]) +/datum/language_holder/proc/remove_language(language, language_flags = ALL, source = LANGUAGE_ALL) + if(language_flags & UNDERSTOOD_LANGUAGE) if(source == LANGUAGE_ALL) - understood_languages -= language + LAZYREMOVE(understood_languages, language) else - understood_languages[language] -= source - if(!length(understood_languages[language])) - understood_languages -= language + LAZYREMOVEASSOC(understood_languages, language, source) . = TRUE - if(spoken && spoken_languages[language]) + if(language_flags & SPOKEN_LANGUAGE) if(source == LANGUAGE_ALL) - spoken_languages -= language + LAZYREMOVE(spoken_languages, language) else - spoken_languages[language] -= source - if(!length(spoken_languages[language])) - spoken_languages -= language + LAZYREMOVEASSOC(spoken_languages, language, source) . = TRUE + return . + /// Removes every language and optionally sets omnitongue false. If a non default source is supplied, only removes that source. /datum/language_holder/proc/remove_all_languages(source = LANGUAGE_ALL, remove_omnitongue = FALSE) for(var/language in GLOB.all_languages) - remove_language(language, TRUE, TRUE, source) + remove_language(language, ALL, source) if(remove_omnitongue) omnitongue = FALSE return TRUE @@ -113,41 +121,41 @@ Key procs /datum/language_holder/proc/add_blocked_language(languages, source = LANGUAGE_MIND) if(!islist(languages)) languages = list(languages) + for(var/language in languages) - if(!blocked_languages[language]) - blocked_languages[language] = list() - blocked_languages[language] |= source + LAZYORASSOCLIST(blocked_languages, language, source) return TRUE /// Removes a single language or list of languages from the blocked language list. /datum/language_holder/proc/remove_blocked_language(languages, source = LANGUAGE_MIND) if(!islist(languages)) languages = list(languages) + for(var/language in languages) - if(blocked_languages[language]) - if(source == LANGUAGE_ALL) - blocked_languages -= language - else - blocked_languages[language] -= source - if(!length(blocked_languages[language])) - blocked_languages -= language + if(source == LANGUAGE_ALL) + LAZYREMOVE(blocked_languages, language) + else + LAZYREMOVEASSOC(blocked_languages, language, source) + return TRUE -/// Checks if you have the language. If spoken is true, only checks if you can speak the language. -/datum/language_holder/proc/has_language(language, spoken = FALSE) +/// Checks if you have the language passed. +/datum/language_holder/proc/has_language(language, flag_to_check = UNDERSTOOD_LANGUAGE) if(language in blocked_languages) return FALSE - if(spoken) - return language in spoken_languages - return language in understood_languages + + var/list/langs_to_check = list() + if(flag_to_check & SPOKEN_LANGUAGE) + langs_to_check |= spoken_languages + if(flag_to_check & UNDERSTOOD_LANGUAGE) + langs_to_check |= understood_languages + + return language in langs_to_check /// Checks if you can speak the language. Tongue limitations should be supplied as an argument. /datum/language_holder/proc/can_speak_language(language) - var/atom/movable/ouratom = get_atom() - var/tongue = ouratom.could_speak_language(language) - if((omnitongue || tongue) && has_language(language, TRUE)) - return TRUE - return FALSE + var/can_speak_language_path = omnitongue || owner.could_speak_language(language) + return (can_speak_language_path && has_language(language, SPOKEN_LANGUAGE)) /// Returns selected language if it can be spoken, or decides, sets and returns a new selected language if possible. /datum/language_holder/proc/get_selected_language() @@ -172,59 +180,79 @@ Key procs /datum/language_holder/proc/get_random_spoken_language() return pick(spoken_languages) +/// Gets a random spoken language, trying to get a non-common language. +/datum/language_holder/proc/get_random_spoken_uncommon_language() + var/list/languages_minus_common = assoc_to_keys(spoken_languages) - /datum/language/common + + // They have a language other than common + if(length(languages_minus_common)) + return pick(languages_minus_common) + + // They can only speak common, oh well. + else + return /datum/language/common + /// Opens a language menu reading from the language holder. /datum/language_holder/proc/open_language_menu(mob/user) if(!language_menu) language_menu = new (src) language_menu.ui_interact(user) -/// Gets the atom, since we some times need to check if the tongue has limitations. -/datum/language_holder/proc/get_atom() - if(owner) - if(istype(owner, /datum/mind)) - var/datum/mind/M = owner - return M.current - return owner - return FALSE - -/// Empties out the atom specific languages and updates them according to the supplied atoms language holder. -/datum/language_holder/proc/update_atom_languages(atom/movable/thing) - var/datum/language_holder/from_atom = thing.get_language_holder(FALSE) //Gets the atoms language holder - if(from_atom == src) //This could happen if called on an atom without a mind. - return FALSE - for(var/language in understood_languages) - remove_language(language, TRUE, FALSE, LANGUAGE_ATOM) - for(var/language in spoken_languages) - remove_language(language, FALSE, TRUE, LANGUAGE_ATOM) - for(var/language in blocked_languages) - remove_blocked_language(language, LANGUAGE_ATOM) - - copy_languages(from_atom) - get_selected_language() - return TRUE - /// Copies all languages from the supplied atom/language holder. Source should be overridden when you /// do not want the language overwritten by later atom updates or want to avoid blocked languages. -/datum/language_holder/proc/copy_languages(var/datum/language_holder/from_holder, source_override) - if(source_override) //No blocked languages here, for now only used by ling absorb. +/datum/language_holder/proc/copy_languages(datum/language_holder/from_holder, source_override) + if(source_override) //No blocked languages here, for now only used by ling absorb. for(var/language in from_holder.understood_languages) - grant_language(language, TRUE, FALSE, source_override) + grant_language(language, UNDERSTOOD_LANGUAGE, source_override) for(var/language in from_holder.spoken_languages) - grant_language(language, FALSE, TRUE, source_override) + grant_language(language, SPOKEN_LANGUAGE, source_override) else for(var/language in from_holder.understood_languages) - grant_language(language, TRUE, FALSE, from_holder.understood_languages[language]) + grant_language(language, UNDERSTOOD_LANGUAGE, from_holder.understood_languages[language]) for(var/language in from_holder.spoken_languages) - grant_language(language, FALSE, TRUE, from_holder.spoken_languages[language]) + grant_language(language, SPOKEN_LANGUAGE, from_holder.spoken_languages[language]) for(var/language in from_holder.blocked_languages) add_blocked_language(language, from_holder.blocked_languages[language]) return TRUE +/// Transfers all mind languages to the supplied language holder. +/datum/language_holder/proc/transfer_mind_languages(datum/language_holder/to_holder) + for(var/language in understood_languages) + if(LANGUAGE_MIND in understood_languages[language]) + remove_language(language, UNDERSTOOD_LANGUAGE, LANGUAGE_MIND) + to_holder.grant_language(language, UNDERSTOOD_LANGUAGE, LANGUAGE_MIND) + for(var/language in spoken_languages) + if(LANGUAGE_MIND in spoken_languages[language]) + remove_language(language, SPOKEN_LANGUAGE, LANGUAGE_MIND) + to_holder.grant_language(language, SPOKEN_LANGUAGE, LANGUAGE_MIND) + for(var/language in blocked_languages) + if(LANGUAGE_MIND in blocked_languages[language]) + remove_blocked_language(language, LANGUAGE_MIND) + to_holder.add_blocked_language(language, LANGUAGE_MIND) -//************************************************ -//* Specific language holders * -//* Use atom language sources only. * -//************************************************/ + if(owner) + get_selected_language() + if(to_holder.owner) + to_holder.get_selected_language() + +/// A global assoc list containing prototypes of all language holders +/// [Language holder typepath] to [language holder instance] +/// Used for easy reference of what can speak what without needing to constantly recreate language holders. +GLOBAL_LIST_INIT(prototype_language_holders, init_language_holder_prototypes()) + +/// Inits the global list of language holder prototypes. +/proc/init_language_holder_prototypes() + var/list/prototypes = list() + for(var/holdertype in typesof(/datum/language_holder)) + prototypes[holdertype] = new holdertype() + + return prototypes + +/* + * Specific language holders presets + * + * Prefer to use [LANGUGAE_ATOM]. Atom languages will stick through species changes but not mindswaps. + */ /datum/language_holder/alien @@ -252,6 +280,10 @@ Key procs /datum/language_holder/drone/syndicate blocked_languages = null +/datum/language_holder/human_basic + understood_languages = list(/datum/language/common = list(LANGUAGE_ATOM)) + spoken_languages = list(/datum/language/common = list(LANGUAGE_ATOM)) + /datum/language_holder/dwarf understood_languages = list(/datum/language/common = list(LANGUAGE_ATOM), /datum/language/dwarf = list(LANGUAGE_ATOM)) @@ -353,8 +385,12 @@ Key procs /datum/language/arachnid = list(LANGUAGE_ATOM)) /datum/language_holder/empty - understood_languages = list() - spoken_languages = list() + understood_languages = null + spoken_languages = null + +/datum/language_holder/universal + understood_languages = null + spoken_languages = null /datum/language_holder/universal/New() ..() diff --git a/code/modules/language/language_menu.dm b/code/modules/language/language_menu.dm index bffd3d59af..0bfb7a7997 100644 --- a/code/modules/language/language_menu.dm +++ b/code/modules/language/language_menu.dm @@ -20,109 +20,108 @@ /datum/language_menu/ui_data(mob/user) var/list/data = list() - var/atom/movable/AM = language_holder.get_atom() - if(isliving(AM)) - data["is_living"] = TRUE - else - data["is_living"] = FALSE - + var/atom/movable/speaker = language_holder.owner + data["is_living"] = isliving(speaker) data["languages"] = list() - for(var/lang in GLOB.all_languages) - var/result = language_holder.has_language(lang) || language_holder.has_language(lang, TRUE) + for(var/datum/language/language as anything in GLOB.all_languages) + var/result = language_holder.has_language(language) || language_holder.has_language(language, SPOKEN_LANGUAGE) if(!result) continue - var/datum/language/language = lang - var/list/L = list() + var/list/lang_data = list() - L["name"] = initial(language.name) - L["desc"] = initial(language.desc) - L["key"] = initial(language.key) - L["is_default"] = (language == language_holder.selected_language) - if(AM) - L["can_speak"] = AM.can_speak_language(language) - L["can_understand"] = AM.has_language(language) + lang_data["name"] = initial(language.name) + lang_data["desc"] = initial(language.desc) + lang_data["key"] = initial(language.key) + lang_data["is_default"] = (language == language_holder.selected_language) + if(speaker) + lang_data["can_speak"] = speaker.can_speak_language(language) + lang_data["can_understand"] = speaker.has_language(language) - data["languages"] += list(L) + UNTYPED_LIST_ADD(data["languages"], lang_data) - if(check_rights_for(user.client, R_ADMIN) || isobserver(AM)) + if(check_rights_for(user.client, R_ADMIN) || isobserver(speaker)) data["admin_mode"] = TRUE data["omnitongue"] = language_holder.omnitongue - data["unknown_languages"] = list() - for(var/lang in GLOB.all_languages) - if(language_holder.has_language(lang) || language_holder.has_language(lang, TRUE)) + for(var/datum/language/language as anything in GLOB.all_languages) + if(language_holder.has_language(language) || language_holder.has_language(language, SPOKEN_LANGUAGE)) continue - var/datum/language/language = lang - var/list/L = list() + var/list/lang_data = list() - L["name"] = initial(language.name) - L["desc"] = initial(language.desc) - L["key"] = initial(language.key) + lang_data["name"] = initial(language.name) + lang_data["desc"] = initial(language.desc) + lang_data["key"] = initial(language.key) + + UNTYPED_LIST_ADD(data["unknown_languages"], lang_data) - data["unknown_languages"] += list(L) return data /datum/language_menu/ui_act(action, params) - if(..()) + . = ..() + if(.) return var/mob/user = usr - var/atom/movable/AM = language_holder.get_atom() - + var/atom/movable/speaker = language_holder.owner + var/is_admin = check_rights_for(user.client, R_ADMIN) var/language_name = params["language_name"] var/datum/language/language_datum - for(var/lang in GLOB.all_languages) - var/datum/language/language = lang + for(var/datum/language/language as anything in GLOB.all_languages) if(language_name == initial(language.name)) language_datum = language - var/is_admin = check_rights_for(user.client, R_ADMIN) switch(action) if("select_default") - if(language_datum && AM.can_speak_language(language_datum)) + if(language_datum && speaker.can_speak_language(language_datum)) language_holder.selected_language = language_datum . = TRUE if("grant_language") - if((is_admin || isobserver(AM)) && language_datum) + if((is_admin || isobserver(speaker)) && language_datum) var/list/choices = list("Only Spoken", "Only Understood", "Both") - var/choice = input(user,"How do you want to add this language?","[language_datum]",null) as null|anything in choices - var/spoken = FALSE - var/understood = FALSE + var/choice = tgui_input_list(user, "How do you want to add this language?", "[language_datum]", choices) + if(isnull(choice)) + return + var/adding_flags = NONE switch(choice) if("Only Spoken") - spoken = TRUE + adding_flags |= SPOKEN_LANGUAGE if("Only Understood") - understood = TRUE + adding_flags |= UNDERSTOOD_LANGUAGE if("Both") - spoken = TRUE - understood = TRUE - language_holder.grant_language(language_datum, understood, spoken) + adding_flags |= ALL + + if(LAZYACCESS(language_holder.blocked_languages, language_datum)) + choice = tgui_alert(user, "Do you want to lift the blockage that's also preventing the language to be spoken or understood?", "[language_datum]", list("Yes", "No")) + if(choice == "Yes") + language_holder.remove_blocked_language(language_datum, LANGUAGE_ALL) + language_holder.grant_language(language_datum, adding_flags) if(is_admin) - message_admins("[key_name_admin(user)] granted the [language_name] language to [key_name_admin(AM)].") - log_admin("[key_name(user)] granted the language [language_name] to [key_name(AM)].") + message_admins("[key_name_admin(user)] granted the [language_name] language to [key_name_admin(speaker)].") + log_admin("[key_name(user)] granted the language [language_name] to [key_name(speaker)].") . = TRUE if("remove_language") - if((is_admin || isobserver(AM)) && language_datum) + if((is_admin || isobserver(speaker)) && language_datum) var/list/choices = list("Only Spoken", "Only Understood", "Both") - var/choice = input(user,"Which part do you wish to remove?","[language_datum]",null) as null|anything in choices - var/spoken = FALSE - var/understood = FALSE + var/choice = tgui_input_list(user, "Which part do you wish to remove?", "[language_datum]", choices) + if(isnull(choice)) + return + var/removing_flags = NONE switch(choice) if("Only Spoken") - spoken = TRUE + removing_flags |= SPOKEN_LANGUAGE if("Only Understood") - understood = TRUE + removing_flags |= UNDERSTOOD_LANGUAGE if("Both") - spoken = TRUE - understood = TRUE - language_holder.remove_language(language_datum, understood, spoken) + removing_flags |= ALL + + language_holder.remove_language(language_datum, removing_flags) if(is_admin) - message_admins("[key_name_admin(user)] removed the [language_name] language to [key_name_admin(AM)].") - log_admin("[key_name(user)] removed the language [language_name] to [key_name(AM)].") + message_admins("[key_name_admin(user)] removed the [language_name] language to [key_name_admin(speaker)].") + log_admin("[key_name(user)] removed the language [language_name] to [key_name(speaker)].") . = TRUE if("toggle_omnitongue") - if(is_admin || isobserver(AM)) + if(is_admin || isobserver(speaker)) language_holder.omnitongue = !language_holder.omnitongue if(is_admin) - message_admins("[key_name_admin(user)] [language_holder.omnitongue ? "enabled" : "disabled"] the ability to speak all languages (that they know) of [key_name_admin(AM)].") - log_admin("[key_name(user)] [language_holder.omnitongue ? "enabled" : "disabled"] the ability to speak all languages (that_they know) of [key_name(AM)].") + message_admins("[key_name_admin(user)] [language_holder.omnitongue ? "enabled" : "disabled"] the ability to speak all languages (that they know) of [key_name_admin(speaker)].") + log_admin("[key_name(user)] [language_holder.omnitongue ? "enabled" : "disabled"] the ability to speak all languages (that_they know) of [key_name(speaker)].") . = TRUE diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm index 566d412d80..2c4cf4c915 100644 --- a/code/modules/mining/lavaland/necropolis_chests.dm +++ b/code/modules/mining/lavaland/necropolis_chests.dm @@ -678,6 +678,7 @@ /obj/item/book_of_babel/attack_self(mob/user) to_chat(user, "You flip through the pages of the book, quickly and conveniently learning every language in existence. Somewhat less conveniently, the aging book crumbles to dust in the process. Whoops.") user.grant_all_languages() + user.remove_blocked_language(GLOB.all_languages, source = LANGUAGE_ALL) new /obj/effect/decal/cleanable/ash(get_turf(user)) qdel(src) diff --git a/code/modules/mob/dead/dead.dm b/code/modules/mob/dead/dead.dm index b455787e5c..f9631209f2 100644 --- a/code/modules/mob/dead/dead.dm +++ b/code/modules/mob/dead/dead.dm @@ -89,20 +89,20 @@ INITIALIZE_IMMEDIATE(/mob/dead) if(alert(src, "Jump to server [pick] ([addr])?", "Server Hop", "Yes", "No") != "Yes") return - var/client/C = client - to_chat(C, "Sending you to [pick].") - new /atom/movable/screen/splash(C) + var/client/hopper = client + to_chat(hopper, "Sending you to [pick].") + new /atom/movable/screen/splash(null, src, hopper, FALSE) mob_transforming = TRUE - sleep(29) //let the animation play + sleep(2.9 SECONDS) //let the animation play mob_transforming = FALSE - if(!C) + if(!hopper) return winset(src, null, "command=.options") //other wise the user never knows if byond is downloading resources - C << link("[addr]") + hopper << link("[addr]") /mob/dead/proc/update_z(new_z) // 1+ to register, null to unregister if (registered_z != new_z) diff --git a/code/modules/mob/dead/new_player/login.dm b/code/modules/mob/dead/new_player/login.dm index e40b467a79..2253e81814 100644 --- a/code/modules/mob/dead/new_player/login.dm +++ b/code/modules/mob/dead/new_player/login.dm @@ -41,7 +41,3 @@ else postfix = "soon" to_chat(src, "Please set up your character and select \"Ready\". The game will start [postfix].") - - var/datum/hud/new_player/NH = hud_used - if(istype(NH)) - NH.populate_buttons(src) diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm index 41e54ea109..bc0e275dd0 100644 --- a/code/modules/mob/dead/new_player/new_player.dm +++ b/code/modules/mob/dead/new_player/new_player.dm @@ -27,7 +27,7 @@ /mob/dead/new_player/Initialize(mapload) if(client && SSticker.state == GAME_STATE_STARTUP) - var/atom/movable/screen/splash/S = new(client, TRUE, TRUE) + var/atom/movable/screen/splash/S = new(null, null, client, TRUE) S.Fade(TRUE) if(length(GLOB.newplayer_start)) @@ -496,7 +496,7 @@ if(job && !job.override_latejoin_spawn(character)) SSjob.SendToLateJoin(character) if(!arrivals_docked) - var/atom/movable/screen/splash/Spl = new(character.client, TRUE) + var/atom/movable/screen/splash/Spl = new(null, character, character.client, TRUE) Spl.Fade(TRUE) character.playsound_local(get_turf(character), 'sound/voice/ApproachingTG.ogg', 25) diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 993928a24b..e25168df53 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -794,10 +794,6 @@ else hud_used.healths.icon_state = "health7" -/mob/living/carbon/proc/update_internals_hud_icon(internal_state = 0) - if(hud_used && hud_used.internals) - hud_used.internals.icon_state = "internal[internal_state]" - /mob/living/carbon/update_stat() if(status_flags & GODMODE) return diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index 2689f24b88..64f7aab78e 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -50,22 +50,15 @@ //accessory var/accessory_msg if(istype(w_uniform, /obj/item/clothing/under)) - var/obj/item/clothing/under/U = w_uniform - if(length(U.attached_accessories) && !(U.flags_inv & HIDEACCESSORY)) - var/list/weehoo = list() - var/dumb_icons = "" - for(var/obj/item/clothing/accessory/attached_accessory in U.attached_accessories) - if(!(attached_accessory.flags_inv & HIDEACCESSORY)) - weehoo += "\a [attached_accessory]" - dumb_icons = "[dumb_icons][icon2html(attached_accessory, user)]" - if(length(weehoo)) - accessory_msg += " with [dumb_icons]" - if(length(U.attached_accessories) >= 2) - accessory_msg += jointext(weehoo, ", ", 1, length(weehoo) - 1) - accessory_msg += " and [weehoo[length(weehoo)]]" - else - accessory_msg += weehoo[1] - + var/obj/item/clothing/under/worn_thing = w_uniform + if(!CHECK_BITFIELD(worn_thing.flags_inv, HIDEACCESSORY)) + var/list/accessory_preparation + for(var/obj/item/clothing/accessory/attached_accessory as anything in worn_thing.attached_accessories) + if(CHECK_BITFIELD(attached_accessory.flags_inv, HIDEACCESSORY)) + continue + LAZYADD(accessory_preparation, "[icon2html(attached_accessory, user)] [attached_accessory]") + if(length(accessory_preparation)) + accessory_msg = " with [english_list(accessory_preparation)]" . += "[t_He] [t_is] wearing [w_uniform.get_examine_string(user)][accessory_msg]." //head @@ -88,7 +81,20 @@ //gloves if(gloves && !(ITEM_SLOT_GLOVES in obscured)) - . += "[t_He] [t_has] [gloves.get_examine_string(user)] on [t_his] hands." + //accessory + var/accessory_msg + if(istype(gloves, /obj/item/clothing/gloves)) + var/obj/item/clothing/gloves/worn_thing = gloves + if(!CHECK_BITFIELD(worn_thing.flags_inv, HIDEACCESSORY)) + var/list/accessory_preparation + for(var/obj/item/clothing/accessory/ring/attached_accessory as anything in worn_thing.attached_accessories) + if(CHECK_BITFIELD(attached_accessory.flags_inv, HIDEACCESSORY)) + continue + LAZYADD(accessory_preparation, "[icon2html(attached_accessory, user)] [attached_accessory]") + if(length(accessory_preparation)) + accessory_msg = " with [english_list(accessory_preparation)] on [t_his] fingers" + + . += "[t_He] [t_has] [gloves.get_examine_string(user)] on [t_his] hands[accessory_msg]." else if(length(blood_DNA)) var/hand_number = get_num_arms(FALSE) if(hand_number) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 9406750fdf..93658ad508 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -678,11 +678,11 @@ if(hal_screwyhud == SCREWYHUD_HEALTHY) icon_num = 0 if(icon_num) - hud_used.healthdoll.add_overlay(mutable_appearance('icons/mob/screen_gen.dmi', "[BP.body_zone][icon_num]")) + hud_used.healthdoll.add_overlay(mutable_appearance(ui_style_modular(hud_used.ui_style, "health"), "[BP.body_zone][icon_num]")) for(var/t in get_missing_limbs()) //Missing limbs - hud_used.healthdoll.add_overlay(mutable_appearance('icons/mob/screen_gen.dmi', "[t]6")) + hud_used.healthdoll.add_overlay(mutable_appearance(ui_style_modular(hud_used.ui_style, "health"), "[t]6")) for(var/t in get_disabled_limbs()) //Disabled limbs - hud_used.healthdoll.add_overlay(mutable_appearance('icons/mob/screen_gen.dmi', "[t]7")) + hud_used.healthdoll.add_overlay(mutable_appearance(ui_style_modular(hud_used.ui_style, "health"), "[t]7")) else hud_used.healthdoll.icon_state = "healthdoll_DEAD" diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index ab36cebd34..2b52bb3a0b 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -6,6 +6,7 @@ can_buckle = TRUE buckle_lying = FALSE mob_biotypes = MOB_ORGANIC|MOB_HUMANOID + initial_language_holder = /datum/language_holder/empty // We get stuff from our species /// Enable stamina combat combat_flags = COMBAT_FLAGS_STAMINA_COMBAT | COMBAT_FLAG_UNARMED_PARRY status_flags = CANSTUN|CANKNOCKDOWN|CANUNCONSCIOUS|CANPUSH|CANSTAGGER diff --git a/code/modules/mob/living/carbon/human/human_stripping.dm b/code/modules/mob/living/carbon/human/human_stripping.dm index 489c8f66d9..9c59c48be1 100644 --- a/code/modules/mob/living/carbon/human/human_stripping.dm +++ b/code/modules/mob/living/carbon/human/human_stripping.dm @@ -292,12 +292,9 @@ GLOBAL_LIST_INIT(strippable_human_items, create_strippable_list(list( if(carbon_source.internal) carbon_source.internal = null - // This isn't meant to be FALSE, it correlates to the icon's name. - carbon_source.update_internals_hud_icon(0) else if (!QDELETED(item)) if(internals || carbon_source.getorganslot(ORGAN_SLOT_BREATHING_TUBE)) carbon_source.internal = item - carbon_source.update_internals_hud_icon(1) carbon_source.visible_message( span_danger("[user] [isnull(carbon_source.internal) ? "closes": "opens"] the valve on [source]'s [item.name]."), diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm index 667bf59f86..4e2bb29bb3 100644 --- a/code/modules/mob/living/carbon/human/inventory.dm +++ b/code/modules/mob/living/carbon/human/inventory.dm @@ -319,7 +319,6 @@ if((C.flags_inv & (HIDEHAIR|HIDEFACIALHAIR)) || (initial(C.flags_inv) & (HIDEHAIR|HIDEFACIALHAIR))) update_hair() if(toggle_off && internal && !getorganslot(ORGAN_SLOT_BREATHING_TUBE)) - update_internals_hud_icon(0) internal = null if(C.flags_inv & HIDEEYES) update_inv_glasses() diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index c2505565ac..6419555f00 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -90,8 +90,10 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) var/dangerous_existence //A flag for transformation spells that tells them "hey if you turn a person into one of these without preperation, they'll probably die!" ///Affects the speech message, for example: Motharula flutters, "My speech message is flutters!" var/say_mod = "says" - ///What languages this species can understand and say. Use a [language holder datum][/datum/language_holder] in this var. - var/species_language_holder = /datum/language_holder + /// What languages this species can understand and say. + /// Use a [language holder datum][/datum/language_holder] typepath in this var. + /// Should never be null. + var/datum/language_holder/species_language_holder = /datum/language_holder/human_basic /** * Visible CURRENT bodyparts that are unique to a species. * DO NOT USE THIS AS A LIST OF ALL POSSIBLE BODYPARTS AS IT WILL FUCK @@ -558,6 +560,16 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) for(var/obj/item/bodypart/B in C.bodyparts) B.change_bodypart_status(BODYPART_HYBRID, FALSE, TRUE) // Makes all Bodyparts 'robotic'. + // All languages associated with this language holder are added with source [LANGUAGE_SPECIES] + // rather than source [LANGUAGE_ATOM], so we can track what to remove if our species changes again + var/datum/language_holder/gaining_holder = GLOB.prototype_language_holders[species_language_holder] + for(var/language in gaining_holder.understood_languages) + C.grant_language(language, UNDERSTOOD_LANGUAGE, LANGUAGE_SPECIES) + for(var/language in gaining_holder.spoken_languages) + C.grant_language(language, SPOKEN_LANGUAGE, LANGUAGE_SPECIES) + for(var/language in gaining_holder.blocked_languages) + C.add_blocked_language(language, LANGUAGE_SPECIES) + SEND_SIGNAL(C, COMSIG_SPECIES_GAIN, src, old_species) /datum/species/proc/update_species_slowdown(mob/living/carbon/human/H) @@ -1650,15 +1662,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) H.Jitter(5) hunger_rate = 3 * HUNGER_FACTOR hunger_rate *= H.physiology.hunger_mod - - // SANDSTORM EDIT - if (H.client) - H.adjust_nutrition(-hunger_rate) - else - // Do not allow SSD players to get too hungry. - if (H.nutrition >= NUTRITION_LEVEL_FED) - H.adjust_nutrition(-hunger_rate) - // End of sandstorm edit + H.adjust_nutrition(-hunger_rate) if (H.nutrition > NUTRITION_LEVEL_FULL) diff --git a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm index 78bd993f21..5c93370196 100644 --- a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm +++ b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm @@ -70,7 +70,6 @@ H.equipOutfit(O, visualsOnly) H.internal = H.get_item_for_held_index(2) - H.update_internals_hud_icon(1) return FALSE /datum/species/plasmaman/random_name(gender,unique,lastname) diff --git a/code/modules/mob/living/carbon/human/status_procs.dm b/code/modules/mob/living/carbon/human/status_procs.dm index ec961da4dd..697e3a257f 100644 --- a/code/modules/mob/living/carbon/human/status_procs.dm +++ b/code/modules/mob/living/carbon/human/status_procs.dm @@ -34,11 +34,11 @@ /mob/living/carbon/human/set_drugginess(amount) ..() if(!amount) - remove_language(/datum/language/beachbum, TRUE, TRUE, LANGUAGE_HIGH) + remove_language(/datum/language/beachbum, source = LANGUAGE_HIGH) /mob/living/carbon/human/adjust_drugginess(amount) ..() if(druggy) - grant_language(/datum/language/beachbum, TRUE, TRUE, LANGUAGE_HIGH) + grant_language(/datum/language/beachbum, source = LANGUAGE_HIGH) else - remove_language(/datum/language/beachbum, TRUE, TRUE, LANGUAGE_HIGH) + remove_language(/datum/language/beachbum, source = LANGUAGE_HIGH) diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index 3a28f65d4d..486c97d20b 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -340,12 +340,9 @@ if(internal) if(internal.loc != src) internal = null - update_internals_hud_icon(0) else if (!internals && !getorganslot(ORGAN_SLOT_BREATHING_TUBE)) internal = null - update_internals_hud_icon(0) else - update_internals_hud_icon(1) . = internal.remove_air_volume(volume_needed) if(!.) return FALSE //to differentiate between no internals and active, but empty internals diff --git a/code/modules/mob/living/carbon/monkey/combat.dm b/code/modules/mob/living/carbon/monkey/combat.dm index 8976a0cc6d..6af29ca689 100644 --- a/code/modules/mob/living/carbon/monkey/combat.dm +++ b/code/modules/mob/living/carbon/monkey/combat.dm @@ -397,7 +397,7 @@ return ..() /mob/living/carbon/monkey/hitby(atom/movable/hitting_atom, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum) - if(istype(hitting_atom, /obj/item)) + if(isitem(hitting_atom)) var/obj/item/item_hitby = hitting_atom var/mob/thrown_by = item_hitby.thrownby?.resolve() if(item_hitby.throwforce < src.health && thrown_by && ishuman(thrown_by)) diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index 5db4e123b9..dc30b9b1e8 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -107,14 +107,17 @@ return FALSE /mob/living/hitby(atom/movable/AM, skipcatch, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum) + var/zone = ran_zone(BODY_ZONE_CHEST, 65)//Hits a random part of the body, geared towards the chest if(!isitem(AM)) // Filled with made up numbers for non-items. - if(mob_run_block(AM, 30, "\the [AM.name]", ATTACK_TYPE_THROWN, 0, throwingdatum?.thrower, throwingdatum?.thrower?.zone_selected, list())) + if(mob_run_block(AM, 30, "\the [AM.name]", ATTACK_TYPE_THROWN, 0, throwingdatum?.thrower, throwingdatum?.thrower?.zone_selected, list()) & BLOCK_SUCCESS) hitpush = FALSE skipcatch = TRUE blocked = TRUE + return TRUE else playsound(loc, 'sound/weapons/genhit.ogg', 50, TRUE, -1) //Item sounds are handled in the item itself + log_combat(AM, src, "hit ") return ..() var/obj/item/thrown_item = AM @@ -126,18 +129,20 @@ skipcatch = TRUE blocked = TRUE - var/zone = ran_zone(BODY_ZONE_CHEST, 65)//Hits a random part of the body, geared towards the chest + // zone moved up because things need it early while checking it from the thrower is unnecessary var/nosell_hit = SEND_SIGNAL(thrown_item, COMSIG_MOVABLE_IMPACT_ZONE, src, zone, throwingdatum, blocked, FALSE) if(nosell_hit) skipcatch = TRUE hitpush = FALSE if(blocked) - return TRUE + return BLOCK_SUCCESS var/mob/thrown_by = thrown_item.thrownby?.resolve() if(thrown_by) log_combat(thrown_by, src, "threw and hit", thrown_item) + else + log_combat(thrown_item, src, "hit ") if(nosell_hit) return ..() visible_message(span_danger("[src] is hit by [thrown_item]!"), \ diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index e06096f2e7..1a82fe3620 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -501,8 +501,3 @@ GLOBAL_LIST_INIT(department_radio_keys, list( // End of Skyrat edits /mob/living/whisper(message, bubble_type, list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null) say("#[message]", bubble_type, spans, sanitize, language, ignore_spam, forced) - -/mob/living/get_language_holder(get_minds = TRUE) - if(get_minds && mind) - return mind.get_language_holder() - . = ..() diff --git a/code/modules/mob/living/silicon/ai/multicam.dm b/code/modules/mob/living/silicon/ai/multicam.dm index b48b39a885..de96327540 100644 --- a/code/modules/mob/living/silicon/ai/multicam.dm +++ b/code/modules/mob/living/silicon/ai/multicam.dm @@ -6,7 +6,7 @@ var/highlighted = FALSE var/mob/camera/aiEye/pic_in_pic/aiEye -/atom/movable/screen/movable/pic_in_pic/ai/Initialize(mapload) +/atom/movable/screen/movable/pic_in_pic/ai/Initialize(mapload, datum/hud/hud_owner) . = ..() aiEye = new /mob/camera/aiEye/pic_in_pic() aiEye.screen = src diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index b41b7c97dc..c76bb2ab1a 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -138,13 +138,11 @@ var/datum/action/innate/pai/light/AL = new /datum/action/innate/pai/light var/datum/action/innate/custom_holoform/custom_holoform = new /datum/action/innate/custom_holoform - var/datum/action/language_menu/ALM = new SW.Grant(src) AS.Grant(src) AC.Grant(src) AR.Grant(src) AL.Grant(src) - ALM.Grant(src) custom_holoform.Grant(src) emitter_next_use = world.time + 10 SECONDS diff --git a/code/modules/mob/living/silicon/pai/software.dm b/code/modules/mob/living/silicon/pai/software.dm index 87cef96415..951fa56f68 100644 --- a/code/modules/mob/living/silicon/pai/software.dm +++ b/code/modules/mob/living/silicon/pai/software.dm @@ -270,7 +270,7 @@ encryptmod = TRUE if("translator") if(href_list["toggle"]) //This is permanent. - grant_all_languages(TRUE, TRUE, TRUE, LANGUAGE_SOFTWARE) + grant_all_languages(source = LANGUAGE_SOFTWARE) if("doorjack") if(href_list["jack"]) if(cable && cable.machine) diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index e4b86ff584..6d9d6a7621 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -24,9 +24,9 @@ robot_modules_background.layer = HUD_LAYER //Objects that appear on screen are on layer ABOVE_HUD_LAYER, UI should be just below it. robot_modules_background.plane = HUD_PLANE - inv1 = new /atom/movable/screen/robot/module1() - inv2 = new /atom/movable/screen/robot/module2() - inv3 = new /atom/movable/screen/robot/module3() + inv1 = new /atom/movable/screen/robot/module1(null, src) + inv2 = new /atom/movable/screen/robot/module2(null, src) + inv3 = new /atom/movable/screen/robot/module3(null, src) ident = rand(1, 999) diff --git a/code/modules/mob/living/simple_animal/bot/honkbot.dm b/code/modules/mob/living/simple_animal/bot/honkbot.dm index a5b2655a09..c6af5ff770 100644 --- a/code/modules/mob/living/simple_animal/bot/honkbot.dm +++ b/code/modules/mob/living/simple_animal/bot/honkbot.dm @@ -139,7 +139,7 @@ /mob/living/simple_animal/bot/honkbot/hitby(atom/movable/hitting_atom, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum) - if(istype(hitting_atom, /obj/item)) + if(isitem(hitting_atom)) playsound(src, honksound, 50, TRUE, -1) var/obj/item/item_hitby = hitting_atom var/mob/thrown_by = item_hitby.thrownby?.resolve() diff --git a/code/modules/mob/living/simple_animal/bot/secbot.dm b/code/modules/mob/living/simple_animal/bot/secbot.dm index 4a228e29a1..464e430bfd 100644 --- a/code/modules/mob/living/simple_animal/bot/secbot.dm +++ b/code/modules/mob/living/simple_animal/bot/secbot.dm @@ -352,7 +352,7 @@ /mob/living/simple_animal/bot/secbot/hitby(atom/movable/hitting_atom, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum) - if(istype(hitting_atom, /obj/item)) + if(isitem(hitting_atom)) var/obj/item/item_hitby = hitting_atom var/mob/thrown_by = item_hitby.thrownby?.resolve() if(item_hitby.throwforce < src.health && thrown_by && ishuman(thrown_by)) diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/mining_mobs.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/mining_mobs.dm index 2463431ad3..9494f2de78 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/mining_mobs.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/mining_mobs.dm @@ -44,13 +44,13 @@ visible_message("[P] has a reduced effect on [src]!") return ..() -/mob/living/simple_animal/hostile/asteroid/hitby(atom/movable/AM, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum)//No floor tiling them to death, wiseguy - if(istype(AM, /obj/item)) - var/obj/item/T = AM +/mob/living/simple_animal/hostile/asteroid/hitby(atom/movable/hitting_atom, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum)//No floor tiling them to death, wiseguy + if(isitem(hitting_atom)) + var/obj/item/item_hitby = hitting_atom if(!stat) Aggro() - if(T.throwforce <= 20) - visible_message(span_notice("The [T.name] [throw_message] [src.name]!")) + if(item_hitby.throwforce <= 20) + visible_message(span_notice("\The [item_hitby] [throw_message] [src]!")) return ..() diff --git a/code/modules/mob/living/simple_animal/hostile/mushroom.dm b/code/modules/mob/living/simple_animal/hostile/mushroom.dm index 368cc33597..7fdf000e2f 100644 --- a/code/modules/mob/living/simple_animal/hostile/mushroom.dm +++ b/code/modules/mob/living/simple_animal/hostile/mushroom.dm @@ -180,11 +180,11 @@ if(M.a_intent == INTENT_HARM) Bruise() -/mob/living/simple_animal/hostile/mushroom/hitby(atom/movable/AM, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum) +/mob/living/simple_animal/hostile/mushroom/hitby(atom/movable/hitting_atom, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum) ..() - if(istype(AM, /obj/item)) - var/obj/item/T = AM - if(T.throwforce) + if(isitem(hitting_atom)) + var/obj/item/item_hitby = hitting_atom + if(item_hitby.throwforce) Bruise() /mob/living/simple_animal/hostile/mushroom/bullet_act(obj/item/projectile/P) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 7c4f0fd510..ddb6bcf53a 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -49,7 +49,7 @@ dispose_rendering() qdel(hud_used) QDEL_LIST(client_colours) - ghostize(can_reenter_corpse = FALSE) //False, since we're deleting it currently + ghostize() if(mind?.current == src) //Let's just be safe yeah? This will occasionally be cleared, but not always. Can't do it with ghostize without changing behavior mind.set_current(null) // if(mock_client) @@ -1051,12 +1051,11 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0) //Do not do parent's actions, as we *usually* do this differently. fully_replace_character_name(real_name, new_name) -/mob/verb/open_language_menu() +/mob/verb/open_language_menu_verb() set name = "Open Language Menu" set category = "IC" - var/datum/language_holder/H = get_language_holder() - H.open_language_menu(usr) + get_language_holder().open_language_menu(usr) ///Adjust the nutrition of a mob /mob/proc/adjust_nutrition(change, max = INFINITY) //Honestly FUCK the oldcoders for putting nutrition on /mob someone else can move it up because holy hell I'd have to fix SO many typechecks diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index e0073dc0a9..facd6f6b20 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -308,7 +308,7 @@ It's fairly easy to fix if dealing with single letters but not so much with comp a_intent = possible_a_intents[current_intent] if(hud_used && hud_used.action_intent) - hud_used.action_intent.icon_state = "[a_intent]" + hud_used.action_intent.update_icon() /proc/is_blind(A) diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index ac18cb23f8..ee1a32505e 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -438,7 +438,6 @@ mind.transfer_to(new_xeno) else transfer_ckey(new_xeno) - update_atom_languages() to_chat(new_xeno, "You are now an alien.") . = new_xeno diff --git a/code/modules/research/designs/autolathe_desings/autolathe_designs_sec_and_hacked.dm b/code/modules/research/designs/autolathe_desings/autolathe_designs_sec_and_hacked.dm index bf9d5886a0..1c8bd86a31 100644 --- a/code/modules/research/designs/autolathe_desings/autolathe_designs_sec_and_hacked.dm +++ b/code/modules/research/designs/autolathe_desings/autolathe_designs_sec_and_hacked.dm @@ -58,9 +58,9 @@ build_path = /obj/item/construction/rcd category = list("hacked", "Construction") -/datum/design/rpd +/datum/design/rpd_autolathe name = "Rapid Pipe Dispenser (RPD)" - id = "rpd" + id = "rpd_autolathe" build_type = AUTOLATHE | NO_PUBLIC_LATHE materials = list(/datum/material/iron = 75000, /datum/material/glass = 37500) build_path = /obj/item/pipe_dispenser diff --git a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm index 5d46329462..ab4f5dc76b 100644 --- a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm +++ b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm @@ -552,7 +552,7 @@ if(S.amount < S.max_amount) sheets += S - if(sheets.len > 0) + if(length(sheets)) var/obj/item/stack/sheet/S = pick(sheets) S.add(1) // Dare var edit directly again and i'll strangle you. to_chat(owner, "[linked_extract] adds a layer of slime to [S], which metamorphosizes into another sheet of material!") @@ -587,6 +587,7 @@ /obj/item/hothands name = "burning fingertips" desc = "You shouldn't see this." + item_flags = ABSTRACT /obj/item/hothands/get_temperature() return 290 //Below what's required to ignite plasma. @@ -595,11 +596,11 @@ id = "stabilizeddarkpurple" colour = "dark purple" var/obj/item/hothands/fire - examine_text = "Their fingertips burn brightly!" + examine_text = span_notice("Their fingertips burn brightly!") /datum/status_effect/stabilized/darkpurple/on_apply() ADD_TRAIT(owner, TRAIT_RESISTHEATHANDS, "slimestatus") - fire = new(owner) + fire = new() return ..() /datum/status_effect/stabilized/darkpurple/tick() @@ -607,7 +608,7 @@ if(item) var/obj/item/reagent_containers/food/snacks/F = item if(istype(F) && F.cooked_type) - to_chat(owner, "[linked_extract] flares up brightly, and your hands alone are enough cook [F]!") + to_chat(owner, span_warning("[linked_extract] flares up brightly, and your hands alone are enough cook [F]!")) F.microwave_act() else item.attackby(fire, owner) @@ -980,7 +981,6 @@ familiar.copy_languages(owner, LANGUAGE_MASTER) if(linked.saved_mind) linked.saved_mind.transfer_to(familiar) - familiar.update_atom_languages() familiar.ckey = linked.saved_mind.key else if(familiar.mind) diff --git a/code/modules/ruins/lavalandruin_code/elephantgraveyard.dm b/code/modules/ruins/lavalandruin_code/elephantgraveyard.dm index e78628dcd6..fe8a9464bb 100644 --- a/code/modules/ruins/lavalandruin_code/elephantgraveyard.dm +++ b/code/modules/ruins/lavalandruin_code/elephantgraveyard.dm @@ -35,7 +35,7 @@ icon_state = "wasteland" environment_type = "wasteland" baseturfs = /turf/open/floor/plating/asteroid/basalt/wasteland - digResult = /obj/item/stack/ore/glass/basalt + dig_result = /obj/item/stack/ore/glass/basalt initial_gas_mix = LAVALAND_DEFAULT_ATMOS slowdown = 0.5 floor_variance = 30 diff --git a/code/modules/ruins/spaceruin_code/TheDerelict.dm b/code/modules/ruins/spaceruin_code/TheDerelict.dm index d26e023df0..cae5c53090 100644 --- a/code/modules/ruins/spaceruin_code/TheDerelict.dm +++ b/code/modules/ruins/spaceruin_code/TheDerelict.dm @@ -159,7 +159,7 @@ to_chat(user, "You start skimming through [src], but you already know dronespeak.") else to_chat(user, "You start skimming through [src], and suddenly the drone chittering makes sense.") - user.grant_language(/datum/language/drone, TRUE, TRUE)//, LANGUAGE_MIND) + user.grant_language(/datum/language/drone, source = LANGUAGE_MIND) return if(user.has_language(/datum/language/drone)) @@ -180,7 +180,7 @@ M.visible_message("[user] beats [M] over the head with [src]!", "[user] beats you over the head with [src]!", "You hear smacking.") else M.visible_message("[user] teaches [M] by beating [M.p_them()] over the head with [src]!", "As [user] hits you with [src], chitters resonate in your mind.", "You hear smacking.") - M.grant_language(/datum/language/drone, TRUE, TRUE) //, LANGUAGE_MIND) + M.grant_language(/datum/language/drone, source = LANGUAGE_MIND) return /obj/structure/fluff/oldturret diff --git a/code/modules/shuttle/on_move.dm b/code/modules/shuttle/on_move.dm index 1f424f5522..d898752d18 100644 --- a/code/modules/shuttle/on_move.dm +++ b/code/modules/shuttle/on_move.dm @@ -69,6 +69,7 @@ All ShuttleMove procs go here /turf/proc/afterShuttleMove(turf/oldT, rotation) //Dealing with the turf we left behind oldT.TransferComponents(src) + SEND_SIGNAL(oldT, COMSIG_TURF_AFTER_SHUTTLE_MOVE, src) //Mostly for decals var/shuttle_boundary = baseturfs.Find(/turf/baseturf_skipover/shuttle) if(shuttle_boundary) oldT.ScrapeAway(baseturfs.len - shuttle_boundary + 1) diff --git a/code/modules/tgui/states/language_menu.dm b/code/modules/tgui/states/language_menu.dm index eaaa125786..1786175f05 100644 --- a/code/modules/tgui/states/language_menu.dm +++ b/code/modules/tgui/states/language_menu.dm @@ -14,6 +14,6 @@ GLOBAL_DATUM_INIT(language_menu_state, /datum/ui_state/language_menu, new) if(check_rights_for(user.client, R_ADMIN)) . = UI_INTERACTIVE else if(istype(src_object, /datum/language_menu)) - var/datum/language_menu/LM = src_object - if(LM.language_holder.get_atom() == user) + var/datum/language_menu/my_languages = src_object + if(my_languages.language_holder.owner == user) . = UI_INTERACTIVE diff --git a/code/modules/tooltip/tooltip.dm b/code/modules/tooltip/tooltip.dm index 290f610f41..ace7f1f280 100644 --- a/code/modules/tooltip/tooltip.dm +++ b/code/modules/tooltip/tooltip.dm @@ -44,7 +44,13 @@ Notes: owner = C var/datum/asset/stuff = get_asset_datum(/datum/asset/simple/jquery) stuff.send(owner) - owner << browse(file2text('code/modules/tooltip/tooltip.html'), "window=[control]") + var/datum/asset/simple/namespaced/fonts/fonts = get_asset_datum(/datum/asset/simple/namespaced/fonts) + fonts.send(owner) + var/static/file2send + if(!file2send) + file2send = replacetext(file2text('code/modules/tooltip/tooltip.html'), "THE_FONT_GOES_HERE!!!!!!!!!!!!!!!", SSassets.transport.get_asset_url("fonts.css")) + + owner << browse(file2send, "window=[control]") ..() diff --git a/code/modules/tooltip/tooltip.html b/code/modules/tooltip/tooltip.html index b772ef0019..f8fa555c45 100644 --- a/code/modules/tooltip/tooltip.html +++ b/code/modules/tooltip/tooltip.html @@ -4,6 +4,7 @@ Tooltip + diff --git a/code/modules/unit_tests/_unit_tests.dm b/code/modules/unit_tests/_unit_tests.dm index b86e9430aa..747e0ae3fa 100644 --- a/code/modules/unit_tests/_unit_tests.dm +++ b/code/modules/unit_tests/_unit_tests.dm @@ -93,6 +93,7 @@ // #include "holidays.dm" // #include "hydroponics_harvest.dm" // #include "keybinding_init.dm" +// #include "language_transfer.dm" #include "machine_disassembly.dm" #include "medical_wounds.dm" #include "merge_type.dm" diff --git a/code/modules/unit_tests/language_transfer.dm b/code/modules/unit_tests/language_transfer.dm new file mode 100644 index 0000000000..7e031f3a8b --- /dev/null +++ b/code/modules/unit_tests/language_transfer.dm @@ -0,0 +1,191 @@ +// Dedicated to testing language holders + +/// Simply tests that swapping to a new species gives you the languages of that species and removes the languages of the old species +/datum/unit_test/language_species_swap_simple + +/datum/unit_test/language_species_swap_simple/Run() + var/mob/living/carbon/human/dummy = allocate(/mob/living/carbon/human/consistent) + + var/datum/language_holder/holder = dummy.get_language_holder() + + var/list/initial_spoken = holder.spoken_languages.Copy() + var/list/initial_understood = holder.understood_languages.Copy() + + TEST_ASSERT(length(initial_spoken) == 1, \ + "Dummy should only speak one language! Instead, it knew the following: [print_language_list(initial_spoken)]") + TEST_ASSERT(length(initial_understood) == 1, \ + "Dummy should only understand one language! Instead, it knew the following: [print_language_list(initial_understood)]") + + dummy.set_species(/datum/species/lizard) + + TEST_ASSERT(length(holder.spoken_languages) == 2, \ + "Dummy should speak two languages - Common and Draconic! Instead, it knew the following: [print_language_list(holder.spoken_languages)]") + + TEST_ASSERT(length(holder.understood_languages) == 2, \ + "Dummy should understand two languages - Common and Draconic! Instead, it knew the following: [print_language_list(holder.understood_languages)]") + + dummy.set_species(/datum/species/human) + + TEST_ASSERT(length(initial_spoken & holder.spoken_languages) == 1, \ + "Dummy did not speak Common after returning to human! Instead, it knew the following: [print_language_list(holder.spoken_languages)]") + + TEST_ASSERT(length(initial_understood & holder.understood_languages) == 1, \ + "Dummy did not understand Common after returning to human! Instead, it knew the following: [print_language_list(holder.understood_languages)]") + +/// Tests species changes which are more complex are functional (e.g. from a species which speaks common to one which does not) +/datum/unit_test/language_species_swap_complex + +/datum/unit_test/language_species_swap_complex/Run() + var/mob/living/carbon/human/dummy = allocate(/mob/living/carbon/human/consistent) + + var/datum/language_holder/holder = dummy.get_language_holder() + + dummy.set_species(/datum/species/lizard/silverscale) + + TEST_ASSERT(!dummy.has_language(/datum/language/common, SPOKEN_LANGUAGE), \ + "Changing a mob's species from one which speaks common to one which does not should remove the language!") + + TEST_ASSERT(dummy.has_language(/datum/language/common, UNDERSTOOD_LANGUAGE), \ + "Changing a mob's species from one which understands common another which does should not remove the language!") + + TEST_ASSERT(length(holder.spoken_languages) == 2, \ + "Dummy should speak two languages - Uncommon and Draconic! Instead, it knew the following: [print_language_list(holder.spoken_languages)]") + + TEST_ASSERT(length(holder.understood_languages) == 3, \ + "Dummy should understand two languages - Common, Uncommon and Draconic! Instead, it knew the following: [print_language_list(holder.understood_languages)]") + +/// Test that other random languages known are not lost on species change +/datum/unit_test/language_species_change_other_known + +/datum/unit_test/language_species_change_other_known/Run() + var/mob/living/carbon/human/dummy = allocate(/mob/living/carbon/human/consistent) + dummy.grant_language(/datum/language/piratespeak, source = LANGUAGE_MIND) + dummy.grant_language(/datum/language/draconic, source = LANGUAGE_ATOM) + dummy.set_species(/datum/species/lizard) + + TEST_ASSERT(dummy.has_language(/datum/language/piratespeak, SPOKEN_LANGUAGE), \ + "Dummy should still speak Pirate after changing species, as it's a mind language!") + + TEST_ASSERT(dummy.has_language(/datum/language/piratespeak, UNDERSTOOD_LANGUAGE), \ + "Dummy should still understand Pirate after changing species, as it's a mind language!") + + dummy.set_species(/datum/species/human) + + TEST_ASSERT(dummy.has_language(/datum/language/draconic, SPOKEN_LANGUAGE), \ + "Dummy should still speak Draconic after changing species, as it's an atom language!") + + TEST_ASSERT(dummy.has_language(/datum/language/draconic, UNDERSTOOD_LANGUAGE), \ + "Dummy should still understand Draconic after changing species, as it's an atom language!") + +/// Tests that mind bound languages are not lost swapping into a new mob, but other languages are +/datum/unit_test/language_mind_transfer + +/datum/unit_test/language_mind_transfer/Run() + var/mob/living/carbon/human/dummy = allocate(/mob/living/carbon/human/consistent) + var/mob/living/basic/pet/dog/corgi/transfer_target = allocate(/mob/living/basic/pet/dog/corgi) + dummy.mind_initialize() + dummy.grant_language(/datum/language/piratespeak, source = LANGUAGE_MIND) + dummy.grant_language(/datum/language/draconic, source = LANGUAGE_ATOM) + dummy.set_species(/datum/species/lizard/silverscale) + + dummy.mind.transfer_to(transfer_target) + + // transfer_target should speak and understand pirate + TEST_ASSERT(!dummy.has_language(/datum/language/piratespeak, SPOKEN_LANGUAGE), \ + "Dummy should no longer be speaking Pirate after losing their mind!") + TEST_ASSERT(transfer_target.has_language(/datum/language/piratespeak, SPOKEN_LANGUAGE), \ + "Dummy's new mob should be capable of speaking Pirate!") + + TEST_ASSERT(!dummy.has_language(/datum/language/piratespeak, UNDERSTOOD_LANGUAGE), \ + "Dummy should no longer be understanding Pirate after losing their mind!") + TEST_ASSERT(transfer_target.has_language(/datum/language/piratespeak, UNDERSTOOD_LANGUAGE), \ + "Dummy's new mob should be capable of understanding Pirate!") + + // transfer_target should NOT speak and understand draconic + TEST_ASSERT(dummy.has_language(/datum/language/draconic, SPOKEN_LANGUAGE), \ + "Dummy should still understand Draconic after losing their mind - it's an atom language!") + TEST_ASSERT(!transfer_target.has_language(/datum/language/draconic, SPOKEN_LANGUAGE), \ + "Dummy's new mob should not understand Draconic - it's an atom language!") + + TEST_ASSERT(dummy.has_language(/datum/language/draconic, UNDERSTOOD_LANGUAGE), \ + "Dummy should still understand Draconic after losing their mind - it's an atom language!") + TEST_ASSERT(!transfer_target.has_language(/datum/language/draconic, UNDERSTOOD_LANGUAGE), \ + "Dummy's new mob should not understand Draconic - it's an atom language!") + + // transfer_target should NOT speak and understand uncommon + TEST_ASSERT(dummy.has_language(/datum/language/uncommon, SPOKEN_LANGUAGE), \ + "Dummy should still understand Uncommon after losing their mind - it's a species language!") + TEST_ASSERT(!transfer_target.has_language(/datum/language/uncommon, SPOKEN_LANGUAGE), \ + "Dummy's new mob should not understand Uncommon - it's a species language!") + + TEST_ASSERT(dummy.has_language(/datum/language/uncommon, UNDERSTOOD_LANGUAGE), \ + "Dummy should still understand Uncommon after losing their mind - it's a species language!") + TEST_ASSERT(!transfer_target.has_language(/datum/language/uncommon, UNDERSTOOD_LANGUAGE), \ + "Dummy's new mob should not understand Uncommon - it's a species language!") + +/// Tests that mind bound languages are not lost when swapping with another person (wiz mindswap) +/datum/unit_test/language_mind_swap + +/datum/unit_test/language_mind_swap/Run() + var/mob/living/carbon/human/dummy_A = allocate(/mob/living/carbon/human/consistent) + var/mob/living/carbon/human/dummy_B = allocate(/mob/living/carbon/human/consistent) + + dummy_A.mind_initialize() + dummy_B.mind_initialize() + + var/datum/mind/dummy_A_mind = dummy_A.mind + var/datum/mind/dummy_B_mind = dummy_B.mind + + dummy_A.set_species(/datum/species/lizard) + dummy_B.grant_language(/datum/language/piratespeak, source = LANGUAGE_MIND) + + dummy_A_mind.transfer_to(dummy_B) + dummy_B_mind.transfer_to(dummy_A) + + var/datum/language_holder/holder_A = dummy_A.get_language_holder() + var/datum/language_holder/holder_B = dummy_B.get_language_holder() + + // Holder A is a lizard: starts with 2 languages (common, draconic) + // Holder B is a human with a mind language: starts with 2 language (common, pirate) + // Swap occurs + // Holder A is a lizard with 2 languages, but should now also have pirate: 3 languages (common, draconic, pirate) + // Holder B is a human with just 1 language left over (common) + + TEST_ASSERT_EQUAL(length(holder_A.spoken_languages), 3, \ + "Holder A / Dummy A / Dummy B mind should speak Common, Draconic, and Pirate! \ + Instead, it knew the following: [print_language_list(holder_A.spoken_languages)]") + + TEST_ASSERT_EQUAL(length(holder_A.understood_languages), 3, \ + "Holder A / Dummy A / Dummy B mind should only understand Common, Draconic, and Pirate! \ + Instead, it knew the following: [print_language_list(holder_A.understood_languages)]") + + TEST_ASSERT_EQUAL(length(holder_B.spoken_languages), 1, \ + "Holder B / Dummy B / Dummy A mind should only speak 1 language - Common! \ + Instead, it knew the following: [print_language_list(holder_B.spoken_languages)]") + + TEST_ASSERT_EQUAL(length(holder_B.understood_languages), 1, \ + "Holder B / Dummy B / Dummy A mind only understand 1 language - Common! \ + Instead, it knew the following: [print_language_list(holder_B.understood_languages)]") + +/// Tests that the book of babel, and by extension grant_all_languages, works as intended +/datum/unit_test/book_of_babel + +/datum/unit_test/book_of_babel/Run() + var/mob/living/carbon/human/dummy = allocate(/mob/living/carbon/human/consistent) + var/obj/item/book_of_babel/book = allocate(/obj/item/book_of_babel) + var/datum/language_holder/holder = dummy.get_language_holder() + var/expected_amount = length(GLOB.all_languages) + + book.attack_self(dummy) + TEST_ASSERT_EQUAL(length(holder.spoken_languages), expected_amount, "Book of Babel failed to give all languages out!") + dummy.set_species(/datum/species/lizard) + TEST_ASSERT_EQUAL(length(holder.spoken_languages), expected_amount, "Changing species after using the Book of Bable should not remove languages!") + +/// Helper proc to print a list of languages in a human readable format +/proc/print_language_list(list/languages_to_print) + var/list/printed_languages = list() + + for(var/datum/language/language as anything in languages_to_print) + printed_languages += initial(language.name) + + return english_list(printed_languages) diff --git a/code/modules/vending/_vending.dm b/code/modules/vending/_vending.dm index 7af2aca81b..618308b509 100644 --- a/code/modules/vending/_vending.dm +++ b/code/modules/vending/_vending.dm @@ -1027,13 +1027,13 @@ GLOBAL_LIST_EMPTY(vending_products) /obj/machinery/vending/proc/canLoadItem(obj/item/I, mob/user) return FALSE -/obj/machinery/vending/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) +/obj/machinery/vending/hitby(atom/movable/hitting_atom, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) . = ..() - var/mob/living/L = AM - if(tilted || !istype(L) || !prob(20 * (throwingdatum.speed - L.throw_speed))) // hulk throw = +20%, neckgrab throw = +20% + var/mob/living/living_mob = hitting_atom + if(tilted || !istype(living_mob) || !prob(20 * (throwingdatum.speed - living_mob.throw_speed))) // hulk throw = +20%, neckgrab throw = +20% return - tilt(L) + tilt(living_mob) /obj/machinery/vending/attack_tk_grab(mob/user) to_chat(user, span_warning("[src] seems to resist your mental grasp!")) diff --git a/code/modules/vore/eating/vorepanel.dm b/code/modules/vore/eating/vorepanel.dm index a44760ae69..d283078758 100644 --- a/code/modules/vore/eating/vorepanel.dm +++ b/code/modules/vore/eating/vorepanel.dm @@ -369,10 +369,7 @@ switch(intent) if("Examine") //Examine a mob inside another mob - var/list/results = target.examine(host) - if(!results || !results.len) - results = list("You were unable to examine that. Tell a developer!") - to_chat(user, jointext(results, "
")) + host.examinate(target) return TRUE if("Use Hand") @@ -469,10 +466,7 @@ intent = tgui_alert(user, "What would you like to do with [target]?", "Vore Pick", available_options) switch(intent) if("Examine") - var/list/results = target.examine(host) - if(!results || !results.len) - results = list("You were unable to examine that. Tell a developer!") - to_chat(user, jointext(results, "
")) + host.examinate(target) return TRUE if("Eject") diff --git a/html/changelogs/archive/2025-02.yml b/html/changelogs/archive/2025-02.yml index 92d45de8a8..0af9870e4b 100644 --- a/html/changelogs/archive/2025-02.yml +++ b/html/changelogs/archive/2025-02.yml @@ -23,3 +23,8 @@ - tweak: Sci mains are now public as on every map - rscadd: Several random map gens - rscadd: Nav beacons +2025-02-10: + SandPoot: + - rscadd: Rings attached to gloves show in people's examines like accessories. + - refactor: Touched up a lot of broken accessory code, it needs more work in the + future, but for now it's actually working. diff --git a/html/changelogs/archive/2025-04.yml b/html/changelogs/archive/2025-04.yml new file mode 100644 index 0000000000..1e6ed581c4 --- /dev/null +++ b/html/changelogs/archive/2025-04.yml @@ -0,0 +1,11 @@ +2025-04-22: + ElectoriaLegend: + - tweak: switched boob sprites to use old Skyrat's ones. + - tweak: made the max boob size by default "I" instead of "H", since these sprites + look relatively smaller and it edges less on excessive hyper-ism now. + - rscadd: Frotting but awesome. + SandPoot: + - rscadd: Ashstorms cover dug up holes in lavaland. + - rscadd: Added some tips about interactions to the ui. + - bugfix: Fixed said tips not accepting more than one tip for a single interaction. + - tweak: Tweaked some tgui code, hopefully won't break anything. diff --git a/icons/hud/64x16_actions.dmi b/icons/hud/64x16_actions.dmi index cec3d4b9d1..a2cdafc584 100644 Binary files a/icons/hud/64x16_actions.dmi and b/icons/hud/64x16_actions.dmi differ diff --git a/icons/hud/lobby/background.dmi b/icons/hud/lobby/background.dmi index 554543ecf3..5fb9085da0 100644 Binary files a/icons/hud/lobby/background.dmi and b/icons/hud/lobby/background.dmi differ diff --git a/icons/hud/lobby/collapse_expand.dmi b/icons/hud/lobby/collapse_expand.dmi index 03f9f02f3d..133a096f94 100644 Binary files a/icons/hud/lobby/collapse_expand.dmi and b/icons/hud/lobby/collapse_expand.dmi differ diff --git a/icons/hud/lobby/signup_button.dmi b/icons/hud/lobby/signup_button.dmi new file mode 100644 index 0000000000..26d32e9af8 Binary files /dev/null and b/icons/hud/lobby/signup_button.dmi differ diff --git a/icons/hud/lobby/start_now.dmi b/icons/hud/lobby/start_now.dmi new file mode 100644 index 0000000000..ec77059011 Binary files /dev/null and b/icons/hud/lobby/start_now.dmi differ diff --git a/icons/mob/actions.dmi b/icons/mob/actions.dmi index e6e0abe111..53648fbba6 100644 Binary files a/icons/mob/actions.dmi and b/icons/mob/actions.dmi differ diff --git a/icons/mob/screen_clockwork.dmi b/icons/mob/screen_clockwork.dmi index d84503c768..2ae2ea123a 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 index 5de29ad1e8..8bf99f67c6 100644 Binary files a/icons/mob/screen_detective.dmi and b/icons/mob/screen_detective.dmi differ diff --git a/icons/mob/screen_glass.dmi b/icons/mob/screen_glass.dmi index 4948171883..992b556cf8 100644 Binary files a/icons/mob/screen_glass.dmi and b/icons/mob/screen_glass.dmi differ diff --git a/icons/mob/screen_midnight.dmi b/icons/mob/screen_midnight.dmi index c180ed4f37..5a7c729a75 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 8e2eeaa315..e41e2bcec0 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 18f99515b9..912dfc4447 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 8c8b920908..5d17b10686 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 91b01910e3..4e38efbba5 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 index bf229f7bad..86e0d076ae 100644 Binary files a/icons/mob/screen_trasenknox.dmi and b/icons/mob/screen_trasenknox.dmi differ diff --git a/icons/obj/genitals/breasts_onmob.dmi b/icons/obj/genitals/breasts_onmob.dmi index f647ba48cc..b362a2427e 100644 Binary files a/icons/obj/genitals/breasts_onmob.dmi and b/icons/obj/genitals/breasts_onmob.dmi differ diff --git a/icons/UI_Icons/Achievements/Boss/bbgum.png b/icons/ui_icons/Achievements/Boss/bbgum.png similarity index 100% rename from icons/UI_Icons/Achievements/Boss/bbgum.png rename to icons/ui_icons/Achievements/Boss/bbgum.png diff --git a/icons/UI_Icons/Achievements/Boss/colossus.png b/icons/ui_icons/Achievements/Boss/colossus.png similarity index 100% rename from icons/UI_Icons/Achievements/Boss/colossus.png rename to icons/ui_icons/Achievements/Boss/colossus.png diff --git a/icons/UI_Icons/Achievements/Boss/drake.png b/icons/ui_icons/Achievements/Boss/drake.png similarity index 100% rename from icons/UI_Icons/Achievements/Boss/drake.png rename to icons/ui_icons/Achievements/Boss/drake.png diff --git a/icons/UI_Icons/Achievements/Boss/hierophant.png b/icons/ui_icons/Achievements/Boss/hierophant.png similarity index 100% rename from icons/UI_Icons/Achievements/Boss/hierophant.png rename to icons/ui_icons/Achievements/Boss/hierophant.png diff --git a/icons/UI_Icons/Achievements/Boss/legion.png b/icons/ui_icons/Achievements/Boss/legion.png similarity index 100% rename from icons/UI_Icons/Achievements/Boss/legion.png rename to icons/ui_icons/Achievements/Boss/legion.png diff --git a/icons/UI_Icons/Achievements/Boss/miner.png b/icons/ui_icons/Achievements/Boss/miner.png similarity index 100% rename from icons/UI_Icons/Achievements/Boss/miner.png rename to icons/ui_icons/Achievements/Boss/miner.png diff --git a/icons/UI_Icons/Achievements/Boss/swarmer.png b/icons/ui_icons/Achievements/Boss/swarmer.png similarity index 100% rename from icons/UI_Icons/Achievements/Boss/swarmer.png rename to icons/ui_icons/Achievements/Boss/swarmer.png diff --git a/icons/UI_Icons/Achievements/Boss/tendril.png b/icons/ui_icons/Achievements/Boss/tendril.png similarity index 100% rename from icons/UI_Icons/Achievements/Boss/tendril.png rename to icons/ui_icons/Achievements/Boss/tendril.png diff --git a/icons/UI_Icons/Achievements/Mafia/hated.png b/icons/ui_icons/Achievements/Mafia/hated.png similarity index 100% rename from icons/UI_Icons/Achievements/Mafia/hated.png rename to icons/ui_icons/Achievements/Mafia/hated.png diff --git a/icons/UI_Icons/Achievements/Mafia/mafia.png b/icons/ui_icons/Achievements/Mafia/mafia.png similarity index 100% rename from icons/UI_Icons/Achievements/Mafia/mafia.png rename to icons/ui_icons/Achievements/Mafia/mafia.png diff --git a/icons/UI_Icons/Achievements/Mafia/neutral.png b/icons/ui_icons/Achievements/Mafia/neutral.png similarity index 100% rename from icons/UI_Icons/Achievements/Mafia/neutral.png rename to icons/ui_icons/Achievements/Mafia/neutral.png diff --git a/icons/UI_Icons/Achievements/Mafia/town.png b/icons/ui_icons/Achievements/Mafia/town.png similarity index 100% rename from icons/UI_Icons/Achievements/Mafia/town.png rename to icons/ui_icons/Achievements/Mafia/town.png diff --git a/icons/UI_Icons/Achievements/Misc/ascension.png b/icons/ui_icons/Achievements/Misc/ascension.png similarity index 100% rename from icons/UI_Icons/Achievements/Misc/ascension.png rename to icons/ui_icons/Achievements/Misc/ascension.png diff --git a/icons/UI_Icons/Achievements/Misc/ashascend.png b/icons/ui_icons/Achievements/Misc/ashascend.png similarity index 100% rename from icons/UI_Icons/Achievements/Misc/ashascend.png rename to icons/ui_icons/Achievements/Misc/ashascend.png diff --git a/icons/UI_Icons/Achievements/Misc/chem_tut.png b/icons/ui_icons/Achievements/Misc/chem_tut.png similarity index 100% rename from icons/UI_Icons/Achievements/Misc/chem_tut.png rename to icons/ui_icons/Achievements/Misc/chem_tut.png diff --git a/icons/UI_Icons/Achievements/Misc/clownking.png b/icons/ui_icons/Achievements/Misc/clownking.png similarity index 100% rename from icons/UI_Icons/Achievements/Misc/clownking.png rename to icons/ui_icons/Achievements/Misc/clownking.png diff --git a/icons/UI_Icons/Achievements/Misc/clownthanks.png b/icons/ui_icons/Achievements/Misc/clownthanks.png similarity index 100% rename from icons/UI_Icons/Achievements/Misc/clownthanks.png rename to icons/ui_icons/Achievements/Misc/clownthanks.png diff --git a/icons/UI_Icons/Achievements/Misc/featofstrength.png b/icons/ui_icons/Achievements/Misc/featofstrength.png similarity index 100% rename from icons/UI_Icons/Achievements/Misc/featofstrength.png rename to icons/ui_icons/Achievements/Misc/featofstrength.png diff --git a/icons/UI_Icons/Achievements/Misc/fleshascend.png b/icons/ui_icons/Achievements/Misc/fleshascend.png similarity index 100% rename from icons/UI_Icons/Achievements/Misc/fleshascend.png rename to icons/ui_icons/Achievements/Misc/fleshascend.png diff --git a/icons/UI_Icons/Achievements/Misc/frenchingthebubble.png b/icons/ui_icons/Achievements/Misc/frenchingthebubble.png similarity index 100% rename from icons/UI_Icons/Achievements/Misc/frenchingthebubble.png rename to icons/ui_icons/Achievements/Misc/frenchingthebubble.png diff --git a/icons/UI_Icons/Achievements/Misc/helbital.png b/icons/ui_icons/Achievements/Misc/helbital.png similarity index 100% rename from icons/UI_Icons/Achievements/Misc/helbital.png rename to icons/ui_icons/Achievements/Misc/helbital.png diff --git a/icons/UI_Icons/Achievements/Misc/jackpot.png b/icons/ui_icons/Achievements/Misc/jackpot.png similarity index 100% rename from icons/UI_Icons/Achievements/Misc/jackpot.png rename to icons/ui_icons/Achievements/Misc/jackpot.png diff --git a/icons/UI_Icons/Achievements/Misc/longshift.png b/icons/ui_icons/Achievements/Misc/longshift.png similarity index 100% rename from icons/UI_Icons/Achievements/Misc/longshift.png rename to icons/ui_icons/Achievements/Misc/longshift.png diff --git a/icons/UI_Icons/Achievements/Misc/meteors.png b/icons/ui_icons/Achievements/Misc/meteors.png similarity index 100% rename from icons/UI_Icons/Achievements/Misc/meteors.png rename to icons/ui_icons/Achievements/Misc/meteors.png diff --git a/icons/UI_Icons/Achievements/Misc/rule8.png b/icons/ui_icons/Achievements/Misc/rule8.png similarity index 100% rename from icons/UI_Icons/Achievements/Misc/rule8.png rename to icons/ui_icons/Achievements/Misc/rule8.png diff --git a/icons/UI_Icons/Achievements/Misc/rustascend.png b/icons/ui_icons/Achievements/Misc/rustascend.png similarity index 100% rename from icons/UI_Icons/Achievements/Misc/rustascend.png rename to icons/ui_icons/Achievements/Misc/rustascend.png diff --git a/icons/UI_Icons/Achievements/Misc/snail.png b/icons/ui_icons/Achievements/Misc/snail.png similarity index 100% rename from icons/UI_Icons/Achievements/Misc/snail.png rename to icons/ui_icons/Achievements/Misc/snail.png diff --git a/icons/UI_Icons/Achievements/Misc/timewaste.png b/icons/ui_icons/Achievements/Misc/timewaste.png similarity index 100% rename from icons/UI_Icons/Achievements/Misc/timewaste.png rename to icons/ui_icons/Achievements/Misc/timewaste.png diff --git a/icons/UI_Icons/Achievements/Misc/toolbox_soul.png b/icons/ui_icons/Achievements/Misc/toolbox_soul.png similarity index 100% rename from icons/UI_Icons/Achievements/Misc/toolbox_soul.png rename to icons/ui_icons/Achievements/Misc/toolbox_soul.png diff --git a/icons/UI_Icons/Achievements/Misc/upgrade.png b/icons/ui_icons/Achievements/Misc/upgrade.png similarity index 100% rename from icons/UI_Icons/Achievements/Misc/upgrade.png rename to icons/ui_icons/Achievements/Misc/upgrade.png diff --git a/icons/UI_Icons/Achievements/Misc/voidascend.png b/icons/ui_icons/Achievements/Misc/voidascend.png similarity index 100% rename from icons/UI_Icons/Achievements/Misc/voidascend.png rename to icons/ui_icons/Achievements/Misc/voidascend.png diff --git a/icons/UI_Icons/Achievements/Skills/mining.png b/icons/ui_icons/Achievements/Skills/mining.png similarity index 100% rename from icons/UI_Icons/Achievements/Skills/mining.png rename to icons/ui_icons/Achievements/Skills/mining.png diff --git a/icons/UI_Icons/Achievements/baseboss.png b/icons/ui_icons/Achievements/baseboss.png similarity index 100% rename from icons/UI_Icons/Achievements/baseboss.png rename to icons/ui_icons/Achievements/baseboss.png diff --git a/icons/UI_Icons/Achievements/basemafia.png b/icons/ui_icons/Achievements/basemafia.png similarity index 100% rename from icons/UI_Icons/Achievements/basemafia.png rename to icons/ui_icons/Achievements/basemafia.png diff --git a/icons/UI_Icons/Achievements/basemisc.png b/icons/ui_icons/Achievements/basemisc.png similarity index 100% rename from icons/UI_Icons/Achievements/basemisc.png rename to icons/ui_icons/Achievements/basemisc.png diff --git a/icons/UI_Icons/Achievements/baseskill.png b/icons/ui_icons/Achievements/baseskill.png similarity index 100% rename from icons/UI_Icons/Achievements/baseskill.png rename to icons/ui_icons/Achievements/baseskill.png diff --git a/icons/UI_Icons/Achievements/default.png b/icons/ui_icons/Achievements/default.png similarity index 100% rename from icons/UI_Icons/Achievements/default.png rename to icons/ui_icons/Achievements/default.png diff --git a/icons/UI_Icons/Advisors/chem_help_advisor.gif b/icons/ui_icons/Advisors/chem_help_advisor.gif similarity index 100% rename from icons/UI_Icons/Advisors/chem_help_advisor.gif rename to icons/ui_icons/Advisors/chem_help_advisor.gif diff --git a/icons/UI_Icons/Arcade/boss1.gif b/icons/ui_icons/Arcade/boss1.gif similarity index 100% rename from icons/UI_Icons/Arcade/boss1.gif rename to icons/ui_icons/Arcade/boss1.gif diff --git a/icons/UI_Icons/Arcade/boss2.gif b/icons/ui_icons/Arcade/boss2.gif similarity index 100% rename from icons/UI_Icons/Arcade/boss2.gif rename to icons/ui_icons/Arcade/boss2.gif diff --git a/icons/UI_Icons/Arcade/boss3.gif b/icons/ui_icons/Arcade/boss3.gif similarity index 100% rename from icons/UI_Icons/Arcade/boss3.gif rename to icons/ui_icons/Arcade/boss3.gif diff --git a/icons/UI_Icons/Arcade/boss4.gif b/icons/ui_icons/Arcade/boss4.gif similarity index 100% rename from icons/UI_Icons/Arcade/boss4.gif rename to icons/ui_icons/Arcade/boss4.gif diff --git a/icons/UI_Icons/Arcade/boss5.gif b/icons/ui_icons/Arcade/boss5.gif similarity index 100% rename from icons/UI_Icons/Arcade/boss5.gif rename to icons/ui_icons/Arcade/boss5.gif diff --git a/icons/UI_Icons/Arcade/boss6.gif b/icons/ui_icons/Arcade/boss6.gif similarity index 100% rename from icons/UI_Icons/Arcade/boss6.gif rename to icons/ui_icons/Arcade/boss6.gif diff --git a/icons/UI_Icons/Condiments/bbqsauce.png b/icons/ui_icons/Condiments/bbqsauce.png similarity index 100% rename from icons/UI_Icons/Condiments/bbqsauce.png rename to icons/ui_icons/Condiments/bbqsauce.png diff --git a/icons/UI_Icons/Condiments/coldsauce.png b/icons/ui_icons/Condiments/coldsauce.png similarity index 100% rename from icons/UI_Icons/Condiments/coldsauce.png rename to icons/ui_icons/Condiments/coldsauce.png diff --git a/icons/UI_Icons/Condiments/condi_empty.png b/icons/ui_icons/Condiments/condi_empty.png similarity index 100% rename from icons/UI_Icons/Condiments/condi_empty.png rename to icons/ui_icons/Condiments/condi_empty.png diff --git a/icons/UI_Icons/Condiments/emptycondiment.png b/icons/ui_icons/Condiments/emptycondiment.png similarity index 100% rename from icons/UI_Icons/Condiments/emptycondiment.png rename to icons/ui_icons/Condiments/emptycondiment.png diff --git a/icons/UI_Icons/Condiments/enzyme.png b/icons/ui_icons/Condiments/enzyme.png similarity index 100% rename from icons/UI_Icons/Condiments/enzyme.png rename to icons/ui_icons/Condiments/enzyme.png diff --git a/icons/UI_Icons/Condiments/flour.png b/icons/ui_icons/Condiments/flour.png similarity index 100% rename from icons/UI_Icons/Condiments/flour.png rename to icons/ui_icons/Condiments/flour.png diff --git a/icons/UI_Icons/Condiments/hotsauce.png b/icons/ui_icons/Condiments/hotsauce.png similarity index 100% rename from icons/UI_Icons/Condiments/hotsauce.png rename to icons/ui_icons/Condiments/hotsauce.png diff --git a/icons/UI_Icons/Condiments/ketchup.png b/icons/ui_icons/Condiments/ketchup.png similarity index 100% rename from icons/UI_Icons/Condiments/ketchup.png rename to icons/ui_icons/Condiments/ketchup.png diff --git a/icons/UI_Icons/Condiments/mayonnaise.png b/icons/ui_icons/Condiments/mayonnaise.png similarity index 100% rename from icons/UI_Icons/Condiments/mayonnaise.png rename to icons/ui_icons/Condiments/mayonnaise.png diff --git a/icons/UI_Icons/Condiments/milk.png b/icons/ui_icons/Condiments/milk.png similarity index 100% rename from icons/UI_Icons/Condiments/milk.png rename to icons/ui_icons/Condiments/milk.png diff --git a/icons/UI_Icons/Condiments/oliveoil.png b/icons/ui_icons/Condiments/oliveoil.png similarity index 100% rename from icons/UI_Icons/Condiments/oliveoil.png rename to icons/ui_icons/Condiments/oliveoil.png diff --git a/icons/UI_Icons/Condiments/peppermillsmall.png b/icons/ui_icons/Condiments/peppermillsmall.png similarity index 100% rename from icons/UI_Icons/Condiments/peppermillsmall.png rename to icons/ui_icons/Condiments/peppermillsmall.png diff --git a/icons/UI_Icons/Condiments/rice.png b/icons/ui_icons/Condiments/rice.png similarity index 100% rename from icons/UI_Icons/Condiments/rice.png rename to icons/ui_icons/Condiments/rice.png diff --git a/icons/UI_Icons/Condiments/saltshakersmall.png b/icons/ui_icons/Condiments/saltshakersmall.png similarity index 100% rename from icons/UI_Icons/Condiments/saltshakersmall.png rename to icons/ui_icons/Condiments/saltshakersmall.png diff --git a/icons/UI_Icons/Condiments/soymilk.png b/icons/ui_icons/Condiments/soymilk.png similarity index 100% rename from icons/UI_Icons/Condiments/soymilk.png rename to icons/ui_icons/Condiments/soymilk.png diff --git a/icons/UI_Icons/Condiments/soysauce.png b/icons/ui_icons/Condiments/soysauce.png similarity index 100% rename from icons/UI_Icons/Condiments/soysauce.png rename to icons/ui_icons/Condiments/soysauce.png diff --git a/icons/UI_Icons/Condiments/sugar.png b/icons/ui_icons/Condiments/sugar.png similarity index 100% rename from icons/UI_Icons/Condiments/sugar.png rename to icons/ui_icons/Condiments/sugar.png diff --git a/icons/UI_Icons/Pills/pill1.png b/icons/ui_icons/Pills/pill1.png similarity index 100% rename from icons/UI_Icons/Pills/pill1.png rename to icons/ui_icons/Pills/pill1.png diff --git a/icons/UI_Icons/Pills/pill10.png b/icons/ui_icons/Pills/pill10.png similarity index 100% rename from icons/UI_Icons/Pills/pill10.png rename to icons/ui_icons/Pills/pill10.png diff --git a/icons/UI_Icons/Pills/pill11.png b/icons/ui_icons/Pills/pill11.png similarity index 100% rename from icons/UI_Icons/Pills/pill11.png rename to icons/ui_icons/Pills/pill11.png diff --git a/icons/UI_Icons/Pills/pill12.png b/icons/ui_icons/Pills/pill12.png similarity index 100% rename from icons/UI_Icons/Pills/pill12.png rename to icons/ui_icons/Pills/pill12.png diff --git a/icons/UI_Icons/Pills/pill13.png b/icons/ui_icons/Pills/pill13.png similarity index 100% rename from icons/UI_Icons/Pills/pill13.png rename to icons/ui_icons/Pills/pill13.png diff --git a/icons/UI_Icons/Pills/pill14.png b/icons/ui_icons/Pills/pill14.png similarity index 100% rename from icons/UI_Icons/Pills/pill14.png rename to icons/ui_icons/Pills/pill14.png diff --git a/icons/UI_Icons/Pills/pill15.png b/icons/ui_icons/Pills/pill15.png similarity index 100% rename from icons/UI_Icons/Pills/pill15.png rename to icons/ui_icons/Pills/pill15.png diff --git a/icons/UI_Icons/Pills/pill16.png b/icons/ui_icons/Pills/pill16.png similarity index 100% rename from icons/UI_Icons/Pills/pill16.png rename to icons/ui_icons/Pills/pill16.png diff --git a/icons/UI_Icons/Pills/pill17.png b/icons/ui_icons/Pills/pill17.png similarity index 100% rename from icons/UI_Icons/Pills/pill17.png rename to icons/ui_icons/Pills/pill17.png diff --git a/icons/UI_Icons/Pills/pill18.png b/icons/ui_icons/Pills/pill18.png similarity index 100% rename from icons/UI_Icons/Pills/pill18.png rename to icons/ui_icons/Pills/pill18.png diff --git a/icons/UI_Icons/Pills/pill19.png b/icons/ui_icons/Pills/pill19.png similarity index 100% rename from icons/UI_Icons/Pills/pill19.png rename to icons/ui_icons/Pills/pill19.png diff --git a/icons/UI_Icons/Pills/pill2.png b/icons/ui_icons/Pills/pill2.png similarity index 100% rename from icons/UI_Icons/Pills/pill2.png rename to icons/ui_icons/Pills/pill2.png diff --git a/icons/UI_Icons/Pills/pill20.png b/icons/ui_icons/Pills/pill20.png similarity index 100% rename from icons/UI_Icons/Pills/pill20.png rename to icons/ui_icons/Pills/pill20.png diff --git a/icons/UI_Icons/Pills/pill21.png b/icons/ui_icons/Pills/pill21.png similarity index 100% rename from icons/UI_Icons/Pills/pill21.png rename to icons/ui_icons/Pills/pill21.png diff --git a/icons/UI_Icons/Pills/pill22.png b/icons/ui_icons/Pills/pill22.png similarity index 100% rename from icons/UI_Icons/Pills/pill22.png rename to icons/ui_icons/Pills/pill22.png diff --git a/icons/UI_Icons/Pills/pill3.png b/icons/ui_icons/Pills/pill3.png similarity index 100% rename from icons/UI_Icons/Pills/pill3.png rename to icons/ui_icons/Pills/pill3.png diff --git a/icons/UI_Icons/Pills/pill4.png b/icons/ui_icons/Pills/pill4.png similarity index 100% rename from icons/UI_Icons/Pills/pill4.png rename to icons/ui_icons/Pills/pill4.png diff --git a/icons/UI_Icons/Pills/pill5.png b/icons/ui_icons/Pills/pill5.png similarity index 100% rename from icons/UI_Icons/Pills/pill5.png rename to icons/ui_icons/Pills/pill5.png diff --git a/icons/UI_Icons/Pills/pill6.png b/icons/ui_icons/Pills/pill6.png similarity index 100% rename from icons/UI_Icons/Pills/pill6.png rename to icons/ui_icons/Pills/pill6.png diff --git a/icons/UI_Icons/Pills/pill7.png b/icons/ui_icons/Pills/pill7.png similarity index 100% rename from icons/UI_Icons/Pills/pill7.png rename to icons/ui_icons/Pills/pill7.png diff --git a/icons/UI_Icons/Pills/pill8.png b/icons/ui_icons/Pills/pill8.png similarity index 100% rename from icons/UI_Icons/Pills/pill8.png rename to icons/ui_icons/Pills/pill8.png diff --git a/icons/UI_Icons/Pills/pill9.png b/icons/ui_icons/Pills/pill9.png similarity index 100% rename from icons/UI_Icons/Pills/pill9.png rename to icons/ui_icons/Pills/pill9.png diff --git a/icons/UI_Icons/adventure/default.png b/icons/ui_icons/adventure/default.png similarity index 100% rename from icons/UI_Icons/adventure/default.png rename to icons/ui_icons/adventure/default.png diff --git a/icons/UI_Icons/adventure/grue.png b/icons/ui_icons/adventure/grue.png similarity index 100% rename from icons/UI_Icons/adventure/grue.png rename to icons/ui_icons/adventure/grue.png diff --git a/icons/UI_Icons/adventure/signal_lost.png b/icons/ui_icons/adventure/signal_lost.png similarity index 100% rename from icons/UI_Icons/adventure/signal_lost.png rename to icons/ui_icons/adventure/signal_lost.png diff --git a/icons/UI_Icons/adventure/trade.png b/icons/ui_icons/adventure/trade.png similarity index 100% rename from icons/UI_Icons/adventure/trade.png rename to icons/ui_icons/adventure/trade.png diff --git a/icons/UI_Icons/chat/chat_icons.dmi b/icons/ui_icons/chat/chat_icons.dmi similarity index 100% rename from icons/UI_Icons/chat/chat_icons.dmi rename to icons/ui_icons/chat/chat_icons.dmi diff --git a/icons/UI_Icons/inventory/back.png b/icons/ui_icons/inventory/back.png similarity index 100% rename from icons/UI_Icons/inventory/back.png rename to icons/ui_icons/inventory/back.png diff --git a/icons/UI_Icons/inventory/belt.png b/icons/ui_icons/inventory/belt.png similarity index 100% rename from icons/UI_Icons/inventory/belt.png rename to icons/ui_icons/inventory/belt.png diff --git a/icons/UI_Icons/inventory/collar.png b/icons/ui_icons/inventory/collar.png similarity index 100% rename from icons/UI_Icons/inventory/collar.png rename to icons/ui_icons/inventory/collar.png diff --git a/icons/UI_Icons/inventory/ears.png b/icons/ui_icons/inventory/ears.png similarity index 100% rename from icons/UI_Icons/inventory/ears.png rename to icons/ui_icons/inventory/ears.png diff --git a/icons/UI_Icons/inventory/glasses.png b/icons/ui_icons/inventory/glasses.png similarity index 100% rename from icons/UI_Icons/inventory/glasses.png rename to icons/ui_icons/inventory/glasses.png diff --git a/icons/UI_Icons/inventory/gloves.png b/icons/ui_icons/inventory/gloves.png similarity index 100% rename from icons/UI_Icons/inventory/gloves.png rename to icons/ui_icons/inventory/gloves.png diff --git a/icons/UI_Icons/inventory/hand_l.png b/icons/ui_icons/inventory/hand_l.png similarity index 100% rename from icons/UI_Icons/inventory/hand_l.png rename to icons/ui_icons/inventory/hand_l.png diff --git a/icons/UI_Icons/inventory/hand_r.png b/icons/ui_icons/inventory/hand_r.png similarity index 100% rename from icons/UI_Icons/inventory/hand_r.png rename to icons/ui_icons/inventory/hand_r.png diff --git a/icons/UI_Icons/inventory/head.png b/icons/ui_icons/inventory/head.png similarity index 100% rename from icons/UI_Icons/inventory/head.png rename to icons/ui_icons/inventory/head.png diff --git a/icons/UI_Icons/inventory/id.png b/icons/ui_icons/inventory/id.png similarity index 100% rename from icons/UI_Icons/inventory/id.png rename to icons/ui_icons/inventory/id.png diff --git a/icons/UI_Icons/inventory/mask.png b/icons/ui_icons/inventory/mask.png similarity index 100% rename from icons/UI_Icons/inventory/mask.png rename to icons/ui_icons/inventory/mask.png diff --git a/icons/UI_Icons/inventory/neck.png b/icons/ui_icons/inventory/neck.png similarity index 100% rename from icons/UI_Icons/inventory/neck.png rename to icons/ui_icons/inventory/neck.png diff --git a/icons/UI_Icons/inventory/pocket.png b/icons/ui_icons/inventory/pocket.png similarity index 100% rename from icons/UI_Icons/inventory/pocket.png rename to icons/ui_icons/inventory/pocket.png diff --git a/icons/UI_Icons/inventory/shoes.png b/icons/ui_icons/inventory/shoes.png similarity index 100% rename from icons/UI_Icons/inventory/shoes.png rename to icons/ui_icons/inventory/shoes.png diff --git a/icons/UI_Icons/inventory/suit.png b/icons/ui_icons/inventory/suit.png similarity index 100% rename from icons/UI_Icons/inventory/suit.png rename to icons/ui_icons/inventory/suit.png diff --git a/icons/UI_Icons/inventory/suit_storage.png b/icons/ui_icons/inventory/suit_storage.png similarity index 100% rename from icons/UI_Icons/inventory/suit_storage.png rename to icons/ui_icons/inventory/suit_storage.png diff --git a/icons/UI_Icons/inventory/uniform.png b/icons/ui_icons/inventory/uniform.png similarity index 100% rename from icons/UI_Icons/inventory/uniform.png rename to icons/ui_icons/inventory/uniform.png diff --git a/icons/UI_Icons/minesweeper_tiles/eight.png b/icons/ui_icons/minesweeper_tiles/eight.png similarity index 100% rename from icons/UI_Icons/minesweeper_tiles/eight.png rename to icons/ui_icons/minesweeper_tiles/eight.png diff --git a/icons/UI_Icons/minesweeper_tiles/empty.png b/icons/ui_icons/minesweeper_tiles/empty.png similarity index 100% rename from icons/UI_Icons/minesweeper_tiles/empty.png rename to icons/ui_icons/minesweeper_tiles/empty.png diff --git a/icons/UI_Icons/minesweeper_tiles/five.png b/icons/ui_icons/minesweeper_tiles/five.png similarity index 100% rename from icons/UI_Icons/minesweeper_tiles/five.png rename to icons/ui_icons/minesweeper_tiles/five.png diff --git a/icons/UI_Icons/minesweeper_tiles/flag.png b/icons/ui_icons/minesweeper_tiles/flag.png similarity index 100% rename from icons/UI_Icons/minesweeper_tiles/flag.png rename to icons/ui_icons/minesweeper_tiles/flag.png diff --git a/icons/UI_Icons/minesweeper_tiles/four.png b/icons/ui_icons/minesweeper_tiles/four.png similarity index 100% rename from icons/UI_Icons/minesweeper_tiles/four.png rename to icons/ui_icons/minesweeper_tiles/four.png diff --git a/icons/UI_Icons/minesweeper_tiles/hidden.png b/icons/ui_icons/minesweeper_tiles/hidden.png similarity index 100% rename from icons/UI_Icons/minesweeper_tiles/hidden.png rename to icons/ui_icons/minesweeper_tiles/hidden.png diff --git a/icons/UI_Icons/minesweeper_tiles/mine.png b/icons/ui_icons/minesweeper_tiles/mine.png similarity index 100% rename from icons/UI_Icons/minesweeper_tiles/mine.png rename to icons/ui_icons/minesweeper_tiles/mine.png diff --git a/icons/UI_Icons/minesweeper_tiles/minehit.png b/icons/ui_icons/minesweeper_tiles/minehit.png similarity index 100% rename from icons/UI_Icons/minesweeper_tiles/minehit.png rename to icons/ui_icons/minesweeper_tiles/minehit.png diff --git a/icons/UI_Icons/minesweeper_tiles/one.png b/icons/ui_icons/minesweeper_tiles/one.png similarity index 100% rename from icons/UI_Icons/minesweeper_tiles/one.png rename to icons/ui_icons/minesweeper_tiles/one.png diff --git a/icons/UI_Icons/minesweeper_tiles/seven.png b/icons/ui_icons/minesweeper_tiles/seven.png similarity index 100% rename from icons/UI_Icons/minesweeper_tiles/seven.png rename to icons/ui_icons/minesweeper_tiles/seven.png diff --git a/icons/UI_Icons/minesweeper_tiles/six.png b/icons/ui_icons/minesweeper_tiles/six.png similarity index 100% rename from icons/UI_Icons/minesweeper_tiles/six.png rename to icons/ui_icons/minesweeper_tiles/six.png diff --git a/icons/UI_Icons/minesweeper_tiles/three.png b/icons/ui_icons/minesweeper_tiles/three.png similarity index 100% rename from icons/UI_Icons/minesweeper_tiles/three.png rename to icons/ui_icons/minesweeper_tiles/three.png diff --git a/icons/UI_Icons/minesweeper_tiles/two.png b/icons/ui_icons/minesweeper_tiles/two.png similarity index 100% rename from icons/UI_Icons/minesweeper_tiles/two.png rename to icons/ui_icons/minesweeper_tiles/two.png diff --git a/icons/UI_Icons/screentips/cursor_hints.dmi b/icons/ui_icons/screentips/cursor_hints.dmi similarity index 100% rename from icons/UI_Icons/screentips/cursor_hints.dmi rename to icons/ui_icons/screentips/cursor_hints.dmi diff --git a/icons/UI_Icons/screentips/full_mouse.dmi b/icons/ui_icons/screentips/full_mouse.dmi similarity index 100% rename from icons/UI_Icons/screentips/full_mouse.dmi rename to icons/ui_icons/screentips/full_mouse.dmi diff --git a/icons/UI_Icons/tgui/grid_background.png b/icons/ui_icons/tgui/grid_background.png similarity index 100% rename from icons/UI_Icons/tgui/grid_background.png rename to icons/ui_icons/tgui/grid_background.png diff --git a/icons/UI_Icons/tgui/jobs.dmi b/icons/ui_icons/tgui/jobs.dmi similarity index 100% rename from icons/UI_Icons/tgui/jobs.dmi rename to icons/ui_icons/tgui/jobs.dmi diff --git a/icons/UI_Icons/tgui/ntosradar_background.png b/icons/ui_icons/tgui/ntosradar_background.png similarity index 100% rename from icons/UI_Icons/tgui/ntosradar_background.png rename to icons/ui_icons/tgui/ntosradar_background.png diff --git a/icons/UI_Icons/tgui/ntosradar_pointer.png b/icons/ui_icons/tgui/ntosradar_pointer.png similarity index 100% rename from icons/UI_Icons/tgui/ntosradar_pointer.png rename to icons/ui_icons/tgui/ntosradar_pointer.png diff --git a/icons/UI_Icons/tgui/ntosradar_pointer_S.png b/icons/ui_icons/tgui/ntosradar_pointer_S.png similarity index 100% rename from icons/UI_Icons/tgui/ntosradar_pointer_S.png rename to icons/ui_icons/tgui/ntosradar_pointer_S.png diff --git a/interface/fonts/SpaceMono.ttf b/interface/fonts/SpaceMono.ttf new file mode 100644 index 0000000000..04e56b923f Binary files /dev/null and b/interface/fonts/SpaceMono.ttf differ diff --git a/interface/fonts/fonts.css b/interface/fonts/fonts.css new file mode 100644 index 0000000000..2fa13f3325 --- /dev/null +++ b/interface/fonts/fonts.css @@ -0,0 +1,29 @@ +@font-face { + font-family: "Grand9K Pixel"; + src: url("Grand9K_Pixel.ttf"); +} + +@font-face { + font-family: "Pixellari"; + src: url("Pixellari.ttf"); +} + +@font-face { + font-family: "Space Mono"; + src: url("SpaceMono.ttf"); +} + +@font-face { + font-family: "Spess Font"; + src: url("SpessFont.ttf"); +} + +@font-face { + font-family: "Tiny Unicode"; + src: url("TinyUnicode.ttf"); +} + +@font-face { + font-family: "VCR OSD Mono"; + src: url("VCR_OSD_MONO.ttf"); +} diff --git a/interface/fonts/license.txt b/interface/fonts/license.txt index 9aa70fbac2..b7e6fe6446 100644 --- a/interface/fonts/license.txt +++ b/interface/fonts/license.txt @@ -6,6 +6,9 @@ Pixellari created by Zacchary Dempsey-Plante. Website indicates free for commerc Spess Font created by MTandi (discord) for /tg/station. +Space Mono Licensed by Google under SIL Open Font License, V1.1. +(https://openfontlicense.org) (https://fonts.google.com/specimen/Space+Mono) + Tiny Unicode created by Jakob Riedle/DuffsDevice. Website indicates free for commercial use. (https://fontmeme.com/fonts/tiny-unicode-font/) diff --git a/interface/fonts/space_mono.dm b/interface/fonts/space_mono.dm new file mode 100644 index 0000000000..3df5e1e954 --- /dev/null +++ b/interface/fonts/space_mono.dm @@ -0,0 +1,3 @@ +/datum/font/spacemono + name = "Space Mono" + font_family = 'interface/fonts/SpaceMono.ttf' diff --git a/modular_sand/code/_onclick/hud/hud.dm b/modular_sand/code/_onclick/hud/hud.dm index e925228264..202a1afdb2 100644 --- a/modular_sand/code/_onclick/hud/hud.dm +++ b/modular_sand/code/_onclick/hud/hud.dm @@ -9,24 +9,38 @@ /// UI element for thirst var/atom/movable/screen/thirst -// Used for getting icons for extra inventory slots -GLOBAL_LIST_INIT(modular_ui_styles, list( - 'icons/mob/screen_midnight.dmi' = 'modular_sand/icons/mob/screen_midnight.dmi', - 'icons/mob/screen_retro.dmi' = 'modular_sand/icons/mob/screen_retro.dmi', - 'icons/mob/screen_plasmafire.dmi' = 'modular_sand/icons/mob/screen_plasmafire.dmi', - 'icons/mob/screen_slimecore.dmi' = 'modular_sand/icons/mob/screen_slimecore.dmi', - 'icons/mob/screen_operative.dmi' = 'modular_sand/icons/mob/screen_operative.dmi', - 'icons/mob/screen_clockwork.dmi' = 'modular_sand/icons/mob/screen_clockwork.dmi', - 'icons/mob/screen_trasenknox.dmi' = 'modular_sand/icons/mob/screen_trasenknox.dmi', - 'modular_sand/icons/mob/screen_liteweb.dmi' = 'modular_sand/icons/mob/screen_liteweb.dmi' -)) +/proc/ui_style_modular(ui_style, variant = "base") + var/static/cache = list() -// Same as above -/proc/ui_style_modular(ui_style) - if(isfile(ui_style)) - return GLOB.modular_ui_styles[ui_style] || GLOB.modular_ui_styles[GLOB.modular_ui_styles[1]] - else - return GLOB.modular_ui_styles[ui_style] || GLOB.modular_ui_styles[GLOB.modular_ui_styles[1]] + var/check = LAZYACCESSASSOC(cache, ui_style, variant) + if(check) + return check + + switch(ui_style) + if('icons/mob/screen_plasmafire.dmi') + . = "modular_sand/icons/hud/screen_plasmafire/" + if('icons/mob/screen_slimecore.dmi') + . = "modular_sand/icons/hud/screen_slimecore/" + if('icons/mob/screen_operative.dmi') + . = "modular_sand/icons/hud/screen_operative/" + if('icons/mob/screen_clockwork.dmi') + . = "modular_sand/icons/hud/screen_clockwork/" + if('icons/mob/screen_glass.dmi') + . = "modular_sand/icons/hud/screen_glass/" + if('icons/mob/screen_trasenknox.dmi') + . = "modular_sand/icons/hud/screen_trasenknox/" + if('icons/mob/screen_detective.dmi') + . = "modular_sand/icons/hud/screen_detective/" + if('modular_sand/icons/hud/screen_liteweb/base.dmi') + . = "modular_sand/icons/hud/screen_liteweb/" + if('modular_sand/icons/hud/screen_corru/base.dmi') + . = "modular_sand/icons/hud/screen_corru/" + else + . = "modular_sand/icons/hud/screen_midnight/" + + . = file("[.][variant].dmi") + LAZYADDASSOC(cache, ui_style, variant) + cache[ui_style][variant] = . // Called after updating extra inventory /datum/hud/proc/extra_inventory_update() diff --git a/modular_sand/code/_onclick/hud/screen_objects.dm b/modular_sand/code/_onclick/hud/screen_objects.dm index 62040916c5..c00e378213 100644 --- a/modular_sand/code/_onclick/hud/screen_objects.dm +++ b/modular_sand/code/_onclick/hud/screen_objects.dm @@ -1,14 +1,14 @@ -#define ui_hunger_thirst "EAST-1:28,CENTER+1:51" +#define ui_hunger_thirst "EAST-1:28,CENTER+1:24" /atom/movable/screen/hunger name = "hunger" - icon = 'modular_sand/icons/mob/screen_gen.dmi' + icon = 'modular_sand/icons/hud/screen_gen.dmi' icon_state = "nutrition0" screen_loc = ui_hunger_thirst /atom/movable/screen/thirst name = "thirst" - icon = 'modular_sand/icons/mob/screen_gen.dmi' + icon = 'modular_sand/icons/hud/screen_gen.dmi' icon_state = "hydration0" screen_loc = ui_hunger_thirst diff --git a/modular_sand/code/controllers/subsystem/interactions.dm b/modular_sand/code/controllers/subsystem/interactions.dm index 57047c0347..e3e6d6aff6 100644 --- a/modular_sand/code/controllers/subsystem/interactions.dm +++ b/modular_sand/code/controllers/subsystem/interactions.dm @@ -1,8 +1,9 @@ -SUBSYSTEM_DEF(interactions) +PROCESSING_SUBSYSTEM_DEF(interactions) name = "Interactions" - flags = SS_NO_FIRE + wait = 0.5 SECONDS + stat_tag = "ACT" init_order = INIT_ORDER_INTERACTIONS - var/list/interactions + flags = SS_BACKGROUND|SS_POST_FIRE_TIMING VAR_PROTECTED/list/blacklisted_mobs = list( /mob/dead, /mob/dview, @@ -22,8 +23,9 @@ SUBSYSTEM_DEF(interactions) /mob/living/simple_animal/hostile/retaliate/goat ) VAR_PROTECTED/initialized_blacklist + var/list/interactions = list() -/datum/controller/subsystem/interactions/Initialize(timeofday) +/datum/controller/subsystem/processing/interactions/Initialize(timeofday) prepare_interactions() prepare_blacklisted_mobs() . = ..() @@ -31,13 +33,13 @@ SUBSYSTEM_DEF(interactions) to_chat(world, span_boldannounce(extra_info)) log_subsystem(src, extra_info) -/datum/controller/subsystem/interactions/stat_entry(msg) +/datum/controller/subsystem/processing/interactions/stat_entry(msg) msg += "|🖐:[LAZYLEN(interactions)]|" msg += "🚫👨:[LAZYLEN(blacklisted_mobs)]" return ..() /// Makes the interactions, they're also a global list because having it as a list and just hanging around there is stupid -/datum/controller/subsystem/interactions/proc/prepare_interactions() +/datum/controller/subsystem/processing/interactions/proc/prepare_interactions() QDEL_NULL_LIST(interactions) interactions = list() for(var/datum/interaction/interaction as anything in subtypesof(/datum/interaction)) @@ -48,7 +50,7 @@ SUBSYSTEM_DEF(interactions) interactions["[interaction.type]"] = interaction /// Blacklisting! -/datum/controller/subsystem/interactions/proc/prepare_blacklisted_mobs() +/datum/controller/subsystem/processing/interactions/proc/prepare_blacklisted_mobs() blacklisted_mobs = typecacheof(blacklisted_mobs) initialized_blacklist = TRUE @@ -56,7 +58,7 @@ SUBSYSTEM_DEF(interactions) * Lewd interactions have a blacklist for certain mobs. When we evalute the user and target, both of * their requirements must be satisfied, and the mob must not be of a blacklisted type. */ -/datum/controller/subsystem/interactions/proc/is_blacklisted(mob/living/creature) +/datum/controller/subsystem/processing/interactions/proc/is_blacklisted(mob/living/creature) if(!creature || !initialized_blacklist) return TRUE if(is_type_in_typecache(creature, blacklisted_mobs)) diff --git a/modular_sand/code/controllers/subsystem/language.dm b/modular_sand/code/controllers/subsystem/language.dm index 7d04177fe9..ae2a4f5b1a 100644 --- a/modular_sand/code/controllers/subsystem/language.dm +++ b/modular_sand/code/controllers/subsystem/language.dm @@ -9,12 +9,12 @@ var/datum/language/language_datum = LAZYACCESS(SSlanguage.languages_by_name, language) if(language_datum) if(!language_datum.restricted || (language_datum.name in client.prefs.pref_species.languagewhitelist)) - user.grant_language(language_datum.type, TRUE, TRUE, LANGUAGE_ADDITIONAL) + user.grant_language(language_datum.type) LAZYADD(valid_languages, language) else for(var/datum/quirk/quirk in client.prefs.all_quirks) if(language_datum.name in quirk.languagewhitelist) - user.grant_language(language_datum.type, TRUE, TRUE, LANGUAGE_ADDITIONAL) + user.grant_language(language_datum.type) LAZYADD(valid_languages, language) continue LAZYADD(invalid_languages, language) diff --git a/modular_sand/code/datums/components/interaction_menu_granter.dm b/modular_sand/code/datums/components/interaction_menu_granter.dm index 0df302fae9..59be6f6cae 100644 --- a/modular_sand/code/datums/components/interaction_menu_granter.dm +++ b/modular_sand/code/datums/components/interaction_menu_granter.dm @@ -15,14 +15,32 @@ return menu.open_menu(usr, src) -#define INTERACTION_NORMAL 0 -#define INTERACTION_LEWD 1 -#define INTERACTION_EXTREME 2 #define INTERACTION_UNHOLY 3 //SPLURT Edit /// The menu itself, only var is target which is the mob you are interacting with /datum/component/interaction_menu_granter var/mob/living/target + var/mob/living/auto_interaction_target + var/datum/interaction/currently_active_interaction + var/next_interaction_time + var/auto_interaction_pace = 1 SECONDS + +/datum/component/interaction_menu_granter/process(delta_time) + if(!currently_active_interaction) + auto_interaction_target = null + currently_active_interaction = null + return PROCESS_KILL + if(QDELETED(auto_interaction_target)) + auto_interaction_target = null + currently_active_interaction = null + return PROCESS_KILL + if(world.time <= next_interaction_time) + return + next_interaction_time = world.time + auto_interaction_pace + if(!currently_active_interaction.do_action(parent, auto_interaction_target, apply_cooldown = FALSE)) + auto_interaction_target = null + currently_active_interaction = null + return PROCESS_KILL /datum/component/interaction_menu_granter/Initialize(...) if(!ismob(parent)) @@ -30,21 +48,24 @@ var/mob/parent_mob = parent if(!parent_mob.client) return COMPONENT_INCOMPATIBLE - . = ..() + return ..() /datum/component/interaction_menu_granter/RegisterWithParent() . = ..() RegisterSignal(parent, COMSIG_MOB_CTRLSHIFTCLICKON, PROC_REF(open_menu)) /datum/component/interaction_menu_granter/Destroy(force, ...) - target = null - . = ..() + STOP_PROCESSING(SSinteractions, src) + if(target) + UnregisterSignal(target, COMSIG_PARENT_QDELETING) + target = null + auto_interaction_target = null + currently_active_interaction = null + return ..() /datum/component/interaction_menu_granter/UnregisterFromParent() UnregisterSignal(parent, COMSIG_MOB_CTRLSHIFTCLICKON) - if(target) - UnregisterSignal(target, COMSIG_PARENT_QDELETING) - . = ..() + return ..() /// The one interacting is clicker, the interacted is clicked. /datum/component/interaction_menu_granter/proc/open_menu(mob/clicker, mob/clicked) @@ -96,8 +117,9 @@ //Getting player var/mob/living/self = parent //Getting info - .["isTargetSelf"] = target == self - .["interactingWith"] = target != self ? "Interacting with \the [target]..." : "Interacting with yourself..." + .["isTargetSelf"] = target == self // Why all of these? + .["user"] = self // Because people may have the same name + .["target"] = target // target == self can distinguish .["selfAttributes"] = self.list_interaction_attributes(self) .["lust"] = self.get_lust() .["maxLust"] = self.get_lust_tolerance() * 3 @@ -365,6 +387,10 @@ if(istype(C.handcuffed, /obj/item/restraints/bondage_rope) || istype(C.legcuffed, /obj/item/restraints/bondage_rope)) .["theyHaveBondage"] = TRUE //SPLURT EDIT END + .["auto_interaction_pace"] = auto_interaction_pace + .["is_auto_target_self"] = auto_interaction_target == self + .["auto_interaction_target"] = auto_interaction_target + .["currently_active_interaction"] = currently_active_interaction?.type //Get their genitals var/list/genitals = list() @@ -499,6 +525,7 @@ interaction["additionalDetails"] = I.additional_details sent_interactions += list(interaction) .["interactions"] = sent_interactions + .["interaction_speeds"] = GLOB.interaction_speeds /proc/num_to_pref(num) switch(num) @@ -516,21 +543,41 @@ switch(action) if("interact") var/datum/interaction/o = SSinteractions.interactions[params["interaction"]] - if(o) - o.do_action(parent_mob, target) + if(!o) + return FALSE + if(o == currently_active_interaction) + to_chat(parent_mob, span_notice("This interaction is being automated, sit back, relax or do a different one during it.")) return TRUE - return FALSE + o.do_action(parent_mob, target) + return TRUE + if("interaction_pace") + var/speed = params["speed"] + if(!(speed in GLOB.interaction_speeds)) + return FALSE + src.auto_interaction_pace = speed + return TRUE + if("toggle_auto_interaction") + var/datum/interaction/o = SSinteractions.interactions[params["interaction"]] + if(!o || (currently_active_interaction == o) && (auto_interaction_target == target)) + auto_interaction_target = null + currently_active_interaction = null + STOP_PROCESSING(SSinteractions, src) + else + auto_interaction_target = target + currently_active_interaction = o + START_PROCESSING(SSinteractions, src) + return TRUE if("favorite") var/datum/interaction/interaction = SSinteractions.interactions[params["interaction"]] - if(interaction) - var/datum/preferences/prefs = parent_mob.client.prefs - if(interaction.type in prefs.favorite_interactions) - LAZYREMOVE(prefs.favorite_interactions, interaction.type) - else - LAZYADD(prefs.favorite_interactions, interaction.type) - prefs.save_preferences() - return TRUE - return FALSE + if(!interaction) + return FALSE + var/datum/preferences/prefs = parent_mob.client.prefs + if(interaction.type in prefs.favorite_interactions) + LAZYREMOVE(prefs.favorite_interactions, interaction.type) + else + LAZYADD(prefs.favorite_interactions, interaction.type) + prefs.save_preferences() + return TRUE if("genital") var/mob/living/carbon/self = parent_mob if("visibility" in params) @@ -681,7 +728,4 @@ prefs.save_preferences() return TRUE -#undef INTERACTION_NORMAL -#undef INTERACTION_LEWD -#undef INTERACTION_EXTREME #undef INTERACTION_UNHOLY //SPLURT Edit diff --git a/modular_sand/code/datums/interactions/_interaction.dm b/modular_sand/code/datums/interactions/_interaction.dm index 1c5c067257..8692ef974e 100644 --- a/modular_sand/code/datums/interactions/_interaction.dm +++ b/modular_sand/code/datums/interactions/_interaction.dm @@ -42,11 +42,11 @@ var/required_from_target_exposed = NONE var/required_from_target_unexposed = NONE - /// Refuses to accept more than one entry for some reason, fix sometime + /// Additional details to be shown in the interaction menu, accepts more than one entry var/list/additional_details /// Checks if user can do an interaction, action_check is for whether you're actually doing it or not (useful for the menu and not removing the buttons) -/datum/interaction/proc/evaluate_user(mob/living/user, silent = TRUE, action_check = TRUE) +/datum/interaction/proc/evaluate_user(mob/living/user, silent = TRUE, apply_cooldown = TRUE) if(SSinteractions.is_blacklisted(user)) return FALSE @@ -70,7 +70,7 @@ if(COOLDOWN_FINISHED(user, last_interaction_time)) return TRUE - if(action_check) + if(apply_cooldown) return FALSE else return TRUE @@ -106,21 +106,21 @@ return TRUE /// Actually doing the action, has a few checks to see if it's valid, usually overwritten to be make things actually happen and what-not -/datum/interaction/proc/do_action(mob/living/user, mob/living/target) +/datum/interaction/proc/do_action(mob/living/user, mob/living/target, apply_cooldown = TRUE) if(!(interaction_flags & INTERACTION_FLAG_USER_IS_TARGET)) if(user == target) //tactical href fix to_chat(user, span_warning("You cannot target yourself.")) - return + return FALSE if(get_dist(user, target) > max_distance) to_chat(user, span_warning("They are too far away.")) - return + return FALSE if(interaction_flags & INTERACTION_FLAG_ADJACENT && !(user.Adjacent(target) && target.Adjacent(user))) to_chat(user, span_warning("You cannot get to them.")) - return - if(!evaluate_user(user, silent = FALSE)) - return + return FALSE + if(!evaluate_user(user, silent = FALSE, apply_cooldown = apply_cooldown)) + return FALSE if(!evaluate_target(user, target, silent = FALSE)) - return + return FALSE if(write_log_user) user.log_message("[write_log_user] [target]", LOG_ATTACK) @@ -128,7 +128,8 @@ target.log_message("[write_log_target] [user]", LOG_VICTIM, log_globally = FALSE) display_interaction(user, target) - post_interaction(user, target) + post_interaction(user, target, apply_cooldown) + return TRUE /// Display the message /datum/interaction/proc/display_interaction(mob/living/user, mob/living/target) @@ -138,8 +139,9 @@ user.visible_message("[capitalize(use_message)]") /// After the interaction, the base only plays the sound and only if it has one -/datum/interaction/proc/post_interaction(mob/living/user, mob/living/target) - COOLDOWN_START(user, last_interaction_time, 0.55 SECONDS) +/datum/interaction/proc/post_interaction(mob/living/user, mob/living/target, apply_cooldown = TRUE) + if(apply_cooldown) + COOLDOWN_START(user, last_interaction_time, 0.5 SECONDS) if(interaction_sound) var/soundfile_to_play diff --git a/modular_sand/code/datums/interactions/interaction_datums/lewd/breasts.dm b/modular_sand/code/datums/interactions/interaction_datums/lewd/breasts.dm index f58b5212ff..d85a7050b9 100644 --- a/modular_sand/code/datums/interactions/interaction_datums/lewd/breasts.dm +++ b/modular_sand/code/datums/interactions/interaction_datums/lewd/breasts.dm @@ -5,6 +5,13 @@ write_log_user = "breastfed" write_log_target = "was breastfed by" interaction_sound = null + additional_details = list( + list( + "info" = "Will feed the target with your breasts' reagents if any", + "icon" = "cow", + "color" = "white" + ) + ) /datum/interaction/lewd/do_breastfeed/display_interaction(mob/living/user, mob/living/target) var/message diff --git a/modular_sand/code/datums/interactions/interaction_datums/lewd/cursed/earfuck.dm b/modular_sand/code/datums/interactions/interaction_datums/lewd/cursed/earfuck.dm index df10e5e5c2..3ea426457b 100644 --- a/modular_sand/code/datums/interactions/interaction_datums/lewd/cursed/earfuck.dm +++ b/modular_sand/code/datums/interactions/interaction_datums/lewd/cursed/earfuck.dm @@ -6,6 +6,13 @@ interaction_flags = INTERACTION_FLAG_ADJACENT | INTERACTION_FLAG_OOC_CONSENT | INTERACTION_FLAG_EXTREME_CONTENT write_log_user = "earfucked" write_log_target = "had their ear fucked by" + additional_details = list( + list( + "info" = "With the preference enabled causes slight bleeding, ear and brain damage", + "icon" = "ear-deaf", + "color" = "white" + ) + ) /datum/interaction/lewd/earfuck/earsocketfuck description = "Fuck their earsocket." diff --git a/modular_sand/code/datums/interactions/interaction_datums/lewd/cursed/eyefuck.dm b/modular_sand/code/datums/interactions/interaction_datums/lewd/cursed/eyefuck.dm index e2c31c8549..3900fe468b 100644 --- a/modular_sand/code/datums/interactions/interaction_datums/lewd/cursed/eyefuck.dm +++ b/modular_sand/code/datums/interactions/interaction_datums/lewd/cursed/eyefuck.dm @@ -6,6 +6,13 @@ interaction_flags = INTERACTION_FLAG_ADJACENT | INTERACTION_FLAG_OOC_CONSENT | INTERACTION_FLAG_EXTREME_CONTENT write_log_user = "eyefucked" write_log_target = "had their eye fucked by" + additional_details = list( + list( + "info" = "With the preference enabled causes slight bleeding, eye and brain damage", + "icon" = "eye", + "color" = "white" + ) + ) /datum/interaction/lewd/eyefuck/eyesocketfuck description = "Fuck their eyesocket." diff --git a/modular_sand/code/datums/interactions/interaction_datums/lewd/facefuck.dm b/modular_sand/code/datums/interactions/interaction_datums/lewd/facefuck.dm index 7311dc95b4..a7cbfab68e 100644 --- a/modular_sand/code/datums/interactions/interaction_datums/lewd/facefuck.dm +++ b/modular_sand/code/datums/interactions/interaction_datums/lewd/facefuck.dm @@ -110,10 +110,17 @@ user.handle_post_sex(NORMAL_LUST, CUM_TARGET_MOUTH, partner, genital) //SPLURT edit /datum/interaction/lewd/throatfuck - description = "Fuck their throat. | Does oxy damage." + description = "Fuck their throat" interaction_sound = null required_from_user_exposed = INTERACTION_REQUIRE_PENIS required_from_target = INTERACTION_REQUIRE_MOUTH + additional_details = list( + list( + "info" = "Causes oxygen damage", + "icon" = "lungs", + "color" = "blue" + ) + ) /datum/interaction/lewd/throatfuck/display_interaction(mob/living/user, mob/living/partner) var/message diff --git a/modular_sand/code/datums/interactions/interaction_datums/lewd/frotting.dm b/modular_sand/code/datums/interactions/interaction_datums/lewd/frotting.dm index 4859d6b72f..51d66efa85 100644 --- a/modular_sand/code/datums/interactions/interaction_datums/lewd/frotting.dm +++ b/modular_sand/code/datums/interactions/interaction_datums/lewd/frotting.dm @@ -11,7 +11,10 @@ var/t_His = user.p_their() var/genital_name = user.get_penetrating_genital_name() - message = "rubs [t_His] [genital_name] against [partner]'s." + message = "[pick("rubs [t_His] [genital_name] against [partner]'s.", + "pushes [t_His] [genital_name] against [partner]'s.", + "[t_His] works themselves against [partner].", + "[t_His] meets their hip with [partner]'s as their rods meet together.")]" user.set_is_fucking(partner, CUM_TARGET_PENIS, user.getorganslot(ORGAN_SLOT_PENIS)) user.visible_message(span_lewd("\The [user] [message]"), ignored_mobs = user.get_unconsenting()) if(user.can_penetrating_genital_cum()) diff --git a/modular_sand/code/datums/interactions/interaction_datums/lewd/fuck.dm b/modular_sand/code/datums/interactions/interaction_datums/lewd/fuck.dm index 7a38fbedad..1c2ac50c1c 100644 --- a/modular_sand/code/datums/interactions/interaction_datums/lewd/fuck.dm +++ b/modular_sand/code/datums/interactions/interaction_datums/lewd/fuck.dm @@ -5,6 +5,9 @@ write_log_user = "fucked" write_log_target = "was fucked by" interaction_sound = null + additional_details = list( + INTERACTION_MAY_CAUSE_PREGNANCY + ) /datum/interaction/lewd/fuck/display_interaction(mob/living/user, mob/living/partner) var/message @@ -31,6 +34,7 @@ /datum/interaction/lewd/fuck/anal description = "Fuck their ass." required_from_target_exposed = INTERACTION_REQUIRE_ANUS + additional_details = null // no pregnancy /datum/interaction/lewd/fuck/anal/display_interaction(mob/living/user, mob/living/partner) var/message diff --git a/modular_sand/code/datums/interactions/interaction_datums/lewd/kiss.dm b/modular_sand/code/datums/interactions/interaction_datums/lewd/kiss.dm index bcdc93126b..749fdd33df 100644 --- a/modular_sand/code/datums/interactions/interaction_datums/lewd/kiss.dm +++ b/modular_sand/code/datums/interactions/interaction_datums/lewd/kiss.dm @@ -5,6 +5,13 @@ write_log_user = "kissed" write_log_target = "was kissed by" interaction_sound = null + additional_details = list( + list( + "info" = "Sets lust of both to 5 if less than 5", + "icon" = "heart", + "color" = "red" + ) + ) /datum/interaction/lewd/kiss/post_interaction(mob/living/user, mob/living/partner) . = ..() diff --git a/modular_sand/code/datums/interactions/interaction_datums/lewd/mount.dm b/modular_sand/code/datums/interactions/interaction_datums/lewd/mount.dm index 2c69e82814..7c0700451f 100644 --- a/modular_sand/code/datums/interactions/interaction_datums/lewd/mount.dm +++ b/modular_sand/code/datums/interactions/interaction_datums/lewd/mount.dm @@ -3,6 +3,9 @@ interaction_sound = null required_from_user_exposed = INTERACTION_REQUIRE_VAGINA required_from_target_exposed = INTERACTION_REQUIRE_PENIS + additional_details = list( + INTERACTION_MAY_CAUSE_PREGNANCY + ) /datum/interaction/lewd/mount/display_interaction(mob/living/user, mob/living/partner) var/message diff --git a/modular_sand/code/datums/interactions/interaction_datums/lewd/nipsuck.dm b/modular_sand/code/datums/interactions/interaction_datums/lewd/nipsuck.dm index 7078074466..ac646dae63 100644 --- a/modular_sand/code/datums/interactions/interaction_datums/lewd/nipsuck.dm +++ b/modular_sand/code/datums/interactions/interaction_datums/lewd/nipsuck.dm @@ -5,6 +5,9 @@ write_log_user = "sucked nipples" write_log_target = "had their nipples sucked by" interaction_sound = null + additional_details = list( + INTERACTION_MAY_CONTAIN_DRINK + ) /datum/interaction/lewd/nipsuck/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target) var/user_message diff --git a/modular_sand/code/datums/interactions/interaction_datums/lewd/oral.dm b/modular_sand/code/datums/interactions/interaction_datums/lewd/oral.dm index 24676f54ef..0514bccffd 100644 --- a/modular_sand/code/datums/interactions/interaction_datums/lewd/oral.dm +++ b/modular_sand/code/datums/interactions/interaction_datums/lewd/oral.dm @@ -5,6 +5,9 @@ write_log_user = "gave head to" write_log_target = "was given head by" interaction_sound = null + additional_details = list( + INTERACTION_MAY_CONTAIN_DRINK + ) var/fucktarget = "vagina" /datum/interaction/lewd/oral/blowjob diff --git a/modular_sand/code/datums/interactions/interaction_datums/lewd/self/breasts.dm b/modular_sand/code/datums/interactions/interaction_datums/lewd/self/breasts.dm index c3036081a3..960d56fb89 100644 --- a/modular_sand/code/datums/interactions/interaction_datums/lewd/self/breasts.dm +++ b/modular_sand/code/datums/interactions/interaction_datums/lewd/self/breasts.dm @@ -71,6 +71,9 @@ max_distance = 0 write_log_user = "sucked their own nips" write_log_target = null + additional_details = list( + INTERACTION_MAY_CONTAIN_DRINK + ) /datum/interaction/lewd/self_nipsuck/display_interaction(mob/living/user, mob/living/target) var/message diff --git a/modular_sand/code/datums/interactions/lewd_interactions.dm b/modular_sand/code/datums/interactions/lewd_interactions.dm index 79caf65221..ca68241f18 100644 --- a/modular_sand/code/datums/interactions/lewd_interactions.dm +++ b/modular_sand/code/datums/interactions/lewd_interactions.dm @@ -12,7 +12,7 @@ var/user_refractory_cost var/target_refractory_cost -/datum/interaction/lewd/evaluate_user(mob/living/user, silent = TRUE, action_check = TRUE) +/datum/interaction/lewd/evaluate_user(mob/living/user, silent = TRUE, apply_cooldown = TRUE) . = ..() if(!.) return FALSE @@ -45,11 +45,11 @@ if(!(has_penis == TRUE)) if((user_require_penis_exposed) && has_penis == HAS_UNEXPOSED_GENITAL) if(!silent) - to_chat(user, span_warning("Your penis need to be exposed.")) + to_chat(user, span_warning("Your penis needs to be exposed.")) return FALSE if((user_require_penis_unexposed) && has_penis == HAS_EXPOSED_GENITAL) if(!silent) - to_chat(user, span_warning("Your penis need to be unexposed.")) + to_chat(user, span_warning("Your penis needs to be unexposed.")) return FALSE var/user_require_balls_exposed = !!(required_from_user_exposed & INTERACTION_REQUIRE_BALLS) @@ -243,8 +243,6 @@ if(interaction_flags & INTERACTION_FLAG_OOC_CONSENT) if((!user.ckey) || (user.client && user.client.prefs.toggles & VERB_CONSENT)) return TRUE - if(action_check) - return FALSE return FALSE /datum/interaction/lewd/evaluate_target(mob/living/user, mob/living/target, silent = TRUE) diff --git a/modular_sand/code/datums/status_effects/buffs.dm b/modular_sand/code/datums/status_effects/buffs.dm index 165f58c64a..8804fb604b 100644 --- a/modular_sand/code/datums/status_effects/buffs.dm +++ b/modular_sand/code/datums/status_effects/buffs.dm @@ -8,5 +8,5 @@ /atom/movable/screen/alert/status_effect/argent name = "Argent Energized" desc = "Argent energy rushes through your body! You'll only take 10% damage for the duration of the energy rush!" - icon = 'modular_sand/icons/mob/screen_alert.dmi' + icon = 'modular_sand/icons/hud/screen_alert.dmi' icon_state = "argent" diff --git a/modular_sand/code/datums/status_effects/neutral.dm b/modular_sand/code/datums/status_effects/neutral.dm index 60d9fb13dc..6bbf129bbb 100644 --- a/modular_sand/code/datums/status_effects/neutral.dm +++ b/modular_sand/code/datums/status_effects/neutral.dm @@ -84,7 +84,7 @@ /atom/movable/screen/alert/status_effect/dripping_cum name = "Dripping Cum" desc = "Your last affairs left you dripping someone's seed." - icon = 'modular_sand/icons/mob/screen_alert.dmi' + icon = 'modular_sand/icons/hud/screen_alert.dmi' icon_state = "dripping_cum" /atom/movable/screen/alert/status_effect/dripping_cum/MouseEntered(location,control,params) diff --git a/modular_sand/code/modules/clothing/gloves/_gloves.dm b/modular_sand/code/modules/clothing/gloves/_gloves.dm index 7b21d86c73..e18ccaeff8 100644 --- a/modular_sand/code/modules/clothing/gloves/_gloves.dm +++ b/modular_sand/code/modules/clothing/gloves/_gloves.dm @@ -1,8 +1,7 @@ /obj/item/clothing/gloves var/dummy_thick = FALSE // is able to hold accessories on its item var/max_accessories = 1 - var/list/obj/item/clothing/accessory/ring/attached_accessories = list() - var/list/mutable_appearance/accessory_overlays = list() + var/list/obj/item/clothing/accessory/ring/attached_accessories /obj/item/clothing/gloves/Destroy() QDEL_LIST(attached_accessories) @@ -10,9 +9,12 @@ /obj/item/clothing/gloves/worn_overlays(isinhands = FALSE, icon_file, used_state, style_flags = NONE) . = ..() - if(!isinhands) - if(length(accessory_overlays)) - . += accessory_overlays + if(CHECK_BITFIELD(flags_inv, HIDEACCESSORY)) + return + for(var/obj/item/clothing/accessory/ring/attached_accessory as anything in attached_accessories) + if(CHECK_BITFIELD(attached_accessory.flags_inv, HIDEACCESSORY)) + continue + . += attached_accessory.build_worn_icon() /obj/item/clothing/gloves/attackby(obj/item/I, mob/user, params) if(!attach_accessory(I, user)) @@ -28,66 +30,43 @@ /obj/item/clothing/gloves/equipped(mob/user, slot) ..() - // Sandstorm edit - for(var/obj/item/clothing/accessory/ring/attached_accessory in attached_accessories) - if(attached_accessory && slot != ITEM_SLOT_HANDS && ishuman(user)) - var/mob/living/carbon/human/H = user + for(var/obj/item/clothing/accessory/ring/attached_accessory as anything in attached_accessories) + if(attached_accessory && slot == ITEM_SLOT_HANDS && ishuman(user)) attached_accessory.on_uniform_equip(src, user) - if(attached_accessory.above_suit) - H.update_inv_wear_suit() - // Sandstorm edit END /obj/item/clothing/gloves/dropped(mob/user) - // Sandstorm edit - for(var/obj/item/clothing/accessory/ring/attached_accessory in attached_accessories) + for(var/obj/item/clothing/accessory/ring/attached_accessory as anything in attached_accessories) attached_accessory.on_uniform_dropped(src, user) - if(ishuman(user)) - var/mob/living/carbon/human/H = user - if(attached_accessory.above_suit) - H.update_inv_wear_suit() - // Sandstorm edit END ..() -/obj/item/clothing/gloves/proc/attach_accessory(obj/item/I, mob/user, notifyAttach = 1) +/obj/item/clothing/gloves/proc/attach_accessory(obj/item/clothing/accessory/ring/accessory, mob/user, notifyAttach = 1) . = FALSE - if(istype(I, /obj/item/clothing/accessory/ring)) - var/obj/item/clothing/accessory/ring/A = I - if(length(attached_accessories) >= max_accessories) - if(user) - to_chat(user, span_warning("[src] already has [length(attached_accessories)] accessories.")) - return - if(dummy_thick) - if(user) - to_chat(user, span_warning("[src] is too bulky and cannot have accessories attached to it!")) - return - else - if(user && !user.temporarilyRemoveItemFromInventory(I)) - return - if(!A.attach(src, user)) - return + if(!istype(accessory)) + return + if(length(attached_accessories) >= max_accessories) + if(user) + to_chat(user, "[src] already has [length(attached_accessories)] accessories.") + return + if(dummy_thick) + if(user) + to_chat(user, "[src] is too bulky and cannot have accessories attached to it!") + return + if(user && !user.temporarilyRemoveItemFromInventory(accessory)) + return + if(!accessory.attach(src, user)) + return - if(user && notifyAttach) - to_chat(user, span_notice("You attach [I] to [src].")) + if(user && notifyAttach) + to_chat(user, "You attach [accessory] to [src].") - if((flags_inv & HIDEACCESSORY) || (A.flags_inv & HIDEACCESSORY)) - return TRUE + if((flags_inv & HIDEACCESSORY) || (accessory.flags_inv & HIDEACCESSORY)) + return TRUE - accessory_overlays = list(mutable_appearance('icons/mob/clothing/accessories.dmi', "blank")) - for(var/obj/item/clothing/accessory/attached_accessory in attached_accessories) - var/datum/element/polychromic/polychromic = LAZYACCESS(attached_accessory.comp_lookup, "item_worn_overlays") - if(!polychromic) - var/mutable_appearance/accessory_overlay = mutable_appearance(attached_accessory.mob_overlay_icon, attached_accessory.item_state || attached_accessory.icon_state, ABOVE_HUD_LAYER) - accessory_overlay.alpha = attached_accessory.alpha - accessory_overlay.color = attached_accessory.color - accessory_overlays += accessory_overlay - else - polychromic.apply_worn_overlays(attached_accessory, FALSE, attached_accessory.mob_overlay_icon, attached_accessory.item_state || attached_accessory.icon_state, NONE, accessory_overlays) + if(ishuman(loc)) + var/mob/living/carbon/human/H = loc + H.update_inv_gloves() - if(ishuman(loc)) - var/mob/living/carbon/human/H = loc - H.update_inv_gloves() - - return TRUE + return TRUE /obj/item/clothing/gloves/proc/remove_accessory(mob/user) if(!isliving(user)) @@ -95,20 +74,20 @@ if(!can_use(user)) return - if(length(attached_accessories)) - var/obj/item/clothing/accessory/ring/A = attached_accessories[length(attached_accessories)] - A.detach(src, user) - if(user.put_in_hands(A)) - to_chat(user, span_notice("You detach [A] from [src].")) - else - to_chat(user, span_notice("You detach [A] from [src] and it falls on the floor.")) + if(!LAZYLEN(attached_accessories)) + return + var/obj/item/clothing/accessory/ring/accessory = attached_accessories[length(attached_accessories)] + accessory.detach(src, user) + if(user.put_in_hands(accessory)) + to_chat(user, span_notice("You detach [accessory] from [src].")) + else + to_chat(user, span_notice("You detach [accessory] from [src] and it falls on the floor.")) - if(ishuman(loc)) - var/mob/living/carbon/human/H = loc - H.update_inv_gloves() + if(ishuman(loc)) + var/mob/living/carbon/human/H = loc + H.update_inv_gloves() /obj/item/clothing/gloves/examine(mob/user) . = ..() - if(length(attached_accessories)) - for(var/obj/item/clothing/accessory/ring/attached_accessory in attached_accessories) - . += "\A [attached_accessory] is attached to one of it's fingers." + for(var/obj/item/clothing/accessory/ring/attached_accessory as anything in attached_accessories) + . += "\A [attached_accessory] is attached to one of its fingers." diff --git a/modular_sand/code/modules/clothing/gloves/accessories.dm b/modular_sand/code/modules/clothing/gloves/accessories.dm index e2afe193ff..c6bf70c536 100644 --- a/modular_sand/code/modules/clothing/gloves/accessories.dm +++ b/modular_sand/code/modules/clothing/gloves/accessories.dm @@ -10,6 +10,8 @@ icon_state = "ringgold" item_state = "gring" strip_delay = 40 + /// Here as a reminder, do not add this, unsupported. + above_suit = FALSE var/transfer_prints = FALSE var/transfer_blood = 0 var/strip_mod = 1 diff --git a/modular_sand/code/modules/mob/living/carbon/human/species.dm b/modular_sand/code/modules/mob/living/carbon/human/species.dm index 6f3ba0c8a5..e40880f128 100644 --- a/modular_sand/code/modules/mob/living/carbon/human/species.dm +++ b/modular_sand/code/modules/mob/living/carbon/human/species.dm @@ -3,12 +3,7 @@ return //Put more things here if you plan on adding more things. I know this proc is a bit empty at the moment - if (H.client) - H.adjust_thirst(-THIRST_FACTOR) - else - // Do not allow SSD players to too thirsty. - if (H.thirst >= THIRST_LEVEL_QUENCHED) - H.adjust_thirst(-THIRST_FACTOR) + H.adjust_thirst(-THIRST_FACTOR) /* switch(get_thirst(src)) if(THIRST_LEVEL_THIRSTY to INFINITY) diff --git a/modular_sand/icons/mob/screen_alert.dmi b/modular_sand/icons/hud/screen_alert.dmi similarity index 100% rename from modular_sand/icons/mob/screen_alert.dmi rename to modular_sand/icons/hud/screen_alert.dmi diff --git a/modular_sand/icons/hud/screen_clockwork/base.dmi b/modular_sand/icons/hud/screen_clockwork/base.dmi new file mode 100644 index 0000000000..1cafaa97a0 Binary files /dev/null and b/modular_sand/icons/hud/screen_clockwork/base.dmi differ diff --git a/modular_sand/icons/hud/screen_clockwork/health.dmi b/modular_sand/icons/hud/screen_clockwork/health.dmi new file mode 100644 index 0000000000..bd33d814fa Binary files /dev/null and b/modular_sand/icons/hud/screen_clockwork/health.dmi differ diff --git a/modular_sand/icons/hud/screen_clockwork/stamina.dmi b/modular_sand/icons/hud/screen_clockwork/stamina.dmi new file mode 100644 index 0000000000..69f5b69b50 Binary files /dev/null and b/modular_sand/icons/hud/screen_clockwork/stamina.dmi differ diff --git a/modular_sand/icons/hud/screen_clockwork/zone.dmi b/modular_sand/icons/hud/screen_clockwork/zone.dmi new file mode 100644 index 0000000000..5a19d8803a Binary files /dev/null and b/modular_sand/icons/hud/screen_clockwork/zone.dmi differ diff --git a/modular_sand/icons/hud/screen_corru/base.dmi b/modular_sand/icons/hud/screen_corru/base.dmi new file mode 100644 index 0000000000..f5bc0454d3 Binary files /dev/null and b/modular_sand/icons/hud/screen_corru/base.dmi differ diff --git a/modular_sand/icons/hud/screen_corru/health.dmi b/modular_sand/icons/hud/screen_corru/health.dmi new file mode 100644 index 0000000000..21b9ce4b8f Binary files /dev/null and b/modular_sand/icons/hud/screen_corru/health.dmi differ diff --git a/modular_sand/icons/hud/screen_corru/stamina.dmi b/modular_sand/icons/hud/screen_corru/stamina.dmi new file mode 100644 index 0000000000..4dde592968 Binary files /dev/null and b/modular_sand/icons/hud/screen_corru/stamina.dmi differ diff --git a/modular_sand/icons/hud/screen_corru/zone.dmi b/modular_sand/icons/hud/screen_corru/zone.dmi new file mode 100644 index 0000000000..aa0b660b63 Binary files /dev/null and b/modular_sand/icons/hud/screen_corru/zone.dmi differ diff --git a/modular_sand/icons/hud/screen_detective/base.dmi b/modular_sand/icons/hud/screen_detective/base.dmi new file mode 100644 index 0000000000..89832a30e1 Binary files /dev/null and b/modular_sand/icons/hud/screen_detective/base.dmi differ diff --git a/modular_sand/icons/hud/screen_detective/health.dmi b/modular_sand/icons/hud/screen_detective/health.dmi new file mode 100644 index 0000000000..bd33d814fa Binary files /dev/null and b/modular_sand/icons/hud/screen_detective/health.dmi differ diff --git a/modular_sand/icons/hud/screen_detective/stamina.dmi b/modular_sand/icons/hud/screen_detective/stamina.dmi new file mode 100644 index 0000000000..69f5b69b50 Binary files /dev/null and b/modular_sand/icons/hud/screen_detective/stamina.dmi differ diff --git a/modular_sand/icons/hud/screen_detective/zone.dmi b/modular_sand/icons/hud/screen_detective/zone.dmi new file mode 100644 index 0000000000..5a19d8803a Binary files /dev/null and b/modular_sand/icons/hud/screen_detective/zone.dmi differ diff --git a/modular_sand/icons/mob/screen_gen.dmi b/modular_sand/icons/hud/screen_gen.dmi similarity index 100% rename from modular_sand/icons/mob/screen_gen.dmi rename to modular_sand/icons/hud/screen_gen.dmi diff --git a/modular_sand/icons/hud/screen_glass/base.dmi b/modular_sand/icons/hud/screen_glass/base.dmi new file mode 100644 index 0000000000..7fd9dba2be Binary files /dev/null and b/modular_sand/icons/hud/screen_glass/base.dmi differ diff --git a/modular_sand/icons/hud/screen_glass/health.dmi b/modular_sand/icons/hud/screen_glass/health.dmi new file mode 100644 index 0000000000..bd33d814fa Binary files /dev/null and b/modular_sand/icons/hud/screen_glass/health.dmi differ diff --git a/modular_sand/icons/hud/screen_glass/stamina.dmi b/modular_sand/icons/hud/screen_glass/stamina.dmi new file mode 100644 index 0000000000..69f5b69b50 Binary files /dev/null and b/modular_sand/icons/hud/screen_glass/stamina.dmi differ diff --git a/modular_sand/icons/hud/screen_glass/zone.dmi b/modular_sand/icons/hud/screen_glass/zone.dmi new file mode 100644 index 0000000000..5a19d8803a Binary files /dev/null and b/modular_sand/icons/hud/screen_glass/zone.dmi differ diff --git a/modular_sand/icons/hud/screen_liteweb/base.dmi b/modular_sand/icons/hud/screen_liteweb/base.dmi new file mode 100644 index 0000000000..b44e2f944f Binary files /dev/null and b/modular_sand/icons/hud/screen_liteweb/base.dmi differ diff --git a/modular_sand/icons/hud/screen_liteweb/health.dmi b/modular_sand/icons/hud/screen_liteweb/health.dmi new file mode 100644 index 0000000000..bd33d814fa Binary files /dev/null and b/modular_sand/icons/hud/screen_liteweb/health.dmi differ diff --git a/modular_sand/icons/hud/screen_liteweb/stamina.dmi b/modular_sand/icons/hud/screen_liteweb/stamina.dmi new file mode 100644 index 0000000000..69f5b69b50 Binary files /dev/null and b/modular_sand/icons/hud/screen_liteweb/stamina.dmi differ diff --git a/modular_sand/icons/hud/screen_liteweb/zone.dmi b/modular_sand/icons/hud/screen_liteweb/zone.dmi new file mode 100644 index 0000000000..5a19d8803a Binary files /dev/null and b/modular_sand/icons/hud/screen_liteweb/zone.dmi differ diff --git a/modular_sand/icons/hud/screen_midnight/base.dmi b/modular_sand/icons/hud/screen_midnight/base.dmi new file mode 100644 index 0000000000..89832a30e1 Binary files /dev/null and b/modular_sand/icons/hud/screen_midnight/base.dmi differ diff --git a/modular_sand/icons/hud/screen_midnight/health.dmi b/modular_sand/icons/hud/screen_midnight/health.dmi new file mode 100644 index 0000000000..bd33d814fa Binary files /dev/null and b/modular_sand/icons/hud/screen_midnight/health.dmi differ diff --git a/modular_sand/icons/hud/screen_midnight/stamina.dmi b/modular_sand/icons/hud/screen_midnight/stamina.dmi new file mode 100644 index 0000000000..69f5b69b50 Binary files /dev/null and b/modular_sand/icons/hud/screen_midnight/stamina.dmi differ diff --git a/modular_sand/icons/hud/screen_midnight/zone.dmi b/modular_sand/icons/hud/screen_midnight/zone.dmi new file mode 100644 index 0000000000..5a19d8803a Binary files /dev/null and b/modular_sand/icons/hud/screen_midnight/zone.dmi differ diff --git a/modular_sand/icons/hud/screen_operative/base.dmi b/modular_sand/icons/hud/screen_operative/base.dmi new file mode 100644 index 0000000000..bc3a651875 Binary files /dev/null and b/modular_sand/icons/hud/screen_operative/base.dmi differ diff --git a/modular_sand/icons/hud/screen_operative/health.dmi b/modular_sand/icons/hud/screen_operative/health.dmi new file mode 100644 index 0000000000..bd33d814fa Binary files /dev/null and b/modular_sand/icons/hud/screen_operative/health.dmi differ diff --git a/modular_sand/icons/hud/screen_operative/stamina.dmi b/modular_sand/icons/hud/screen_operative/stamina.dmi new file mode 100644 index 0000000000..69f5b69b50 Binary files /dev/null and b/modular_sand/icons/hud/screen_operative/stamina.dmi differ diff --git a/modular_sand/icons/hud/screen_operative/zone.dmi b/modular_sand/icons/hud/screen_operative/zone.dmi new file mode 100644 index 0000000000..5a19d8803a Binary files /dev/null and b/modular_sand/icons/hud/screen_operative/zone.dmi differ diff --git a/modular_sand/icons/hud/screen_plasmafire/base.dmi b/modular_sand/icons/hud/screen_plasmafire/base.dmi new file mode 100644 index 0000000000..24aa4de840 Binary files /dev/null and b/modular_sand/icons/hud/screen_plasmafire/base.dmi differ diff --git a/modular_sand/icons/hud/screen_plasmafire/health.dmi b/modular_sand/icons/hud/screen_plasmafire/health.dmi new file mode 100644 index 0000000000..bd33d814fa Binary files /dev/null and b/modular_sand/icons/hud/screen_plasmafire/health.dmi differ diff --git a/modular_sand/icons/hud/screen_plasmafire/stamina.dmi b/modular_sand/icons/hud/screen_plasmafire/stamina.dmi new file mode 100644 index 0000000000..69f5b69b50 Binary files /dev/null and b/modular_sand/icons/hud/screen_plasmafire/stamina.dmi differ diff --git a/modular_sand/icons/hud/screen_plasmafire/zone.dmi b/modular_sand/icons/hud/screen_plasmafire/zone.dmi new file mode 100644 index 0000000000..5a19d8803a Binary files /dev/null and b/modular_sand/icons/hud/screen_plasmafire/zone.dmi differ diff --git a/modular_sand/icons/hud/screen_retro/base.dmi b/modular_sand/icons/hud/screen_retro/base.dmi new file mode 100644 index 0000000000..fa95f0e5a7 Binary files /dev/null and b/modular_sand/icons/hud/screen_retro/base.dmi differ diff --git a/modular_sand/icons/hud/screen_retro/health.dmi b/modular_sand/icons/hud/screen_retro/health.dmi new file mode 100644 index 0000000000..bd2900d344 Binary files /dev/null and b/modular_sand/icons/hud/screen_retro/health.dmi differ diff --git a/modular_sand/icons/hud/screen_retro/stamina.dmi b/modular_sand/icons/hud/screen_retro/stamina.dmi new file mode 100644 index 0000000000..2102225b8a Binary files /dev/null and b/modular_sand/icons/hud/screen_retro/stamina.dmi differ diff --git a/modular_sand/icons/hud/screen_retro/zone.dmi b/modular_sand/icons/hud/screen_retro/zone.dmi new file mode 100644 index 0000000000..e19907bbc8 Binary files /dev/null and b/modular_sand/icons/hud/screen_retro/zone.dmi differ diff --git a/modular_sand/icons/hud/screen_slimecore/base.dmi b/modular_sand/icons/hud/screen_slimecore/base.dmi new file mode 100644 index 0000000000..dc0fde238e Binary files /dev/null and b/modular_sand/icons/hud/screen_slimecore/base.dmi differ diff --git a/modular_sand/icons/hud/screen_slimecore/health.dmi b/modular_sand/icons/hud/screen_slimecore/health.dmi new file mode 100644 index 0000000000..bd33d814fa Binary files /dev/null and b/modular_sand/icons/hud/screen_slimecore/health.dmi differ diff --git a/modular_sand/icons/hud/screen_slimecore/stamina.dmi b/modular_sand/icons/hud/screen_slimecore/stamina.dmi new file mode 100644 index 0000000000..69f5b69b50 Binary files /dev/null and b/modular_sand/icons/hud/screen_slimecore/stamina.dmi differ diff --git a/modular_sand/icons/hud/screen_slimecore/zone.dmi b/modular_sand/icons/hud/screen_slimecore/zone.dmi new file mode 100644 index 0000000000..5a19d8803a Binary files /dev/null and b/modular_sand/icons/hud/screen_slimecore/zone.dmi differ diff --git a/modular_sand/icons/hud/screen_trasenknox/base.dmi b/modular_sand/icons/hud/screen_trasenknox/base.dmi new file mode 100644 index 0000000000..9cae260e4a Binary files /dev/null and b/modular_sand/icons/hud/screen_trasenknox/base.dmi differ diff --git a/modular_sand/icons/hud/screen_trasenknox/health.dmi b/modular_sand/icons/hud/screen_trasenknox/health.dmi new file mode 100644 index 0000000000..bd33d814fa Binary files /dev/null and b/modular_sand/icons/hud/screen_trasenknox/health.dmi differ diff --git a/modular_sand/icons/hud/screen_trasenknox/stamina.dmi b/modular_sand/icons/hud/screen_trasenknox/stamina.dmi new file mode 100644 index 0000000000..69f5b69b50 Binary files /dev/null and b/modular_sand/icons/hud/screen_trasenknox/stamina.dmi differ diff --git a/modular_sand/icons/hud/screen_trasenknox/zone.dmi b/modular_sand/icons/hud/screen_trasenknox/zone.dmi new file mode 100644 index 0000000000..5a19d8803a Binary files /dev/null and b/modular_sand/icons/hud/screen_trasenknox/zone.dmi differ diff --git a/modular_sand/icons/mob/screen_clockwork.dmi b/modular_sand/icons/mob/screen_clockwork.dmi deleted file mode 100644 index eefd18fdc5..0000000000 Binary files a/modular_sand/icons/mob/screen_clockwork.dmi and /dev/null differ diff --git a/modular_sand/icons/mob/screen_liteweb.dmi b/modular_sand/icons/mob/screen_liteweb.dmi deleted file mode 100644 index b4d8cbeac0..0000000000 Binary files a/modular_sand/icons/mob/screen_liteweb.dmi and /dev/null differ diff --git a/modular_sand/icons/mob/screen_midnight.dmi b/modular_sand/icons/mob/screen_midnight.dmi deleted file mode 100644 index 9366925181..0000000000 Binary files a/modular_sand/icons/mob/screen_midnight.dmi and /dev/null differ diff --git a/modular_sand/icons/mob/screen_operative.dmi b/modular_sand/icons/mob/screen_operative.dmi deleted file mode 100644 index a435e1bece..0000000000 Binary files a/modular_sand/icons/mob/screen_operative.dmi and /dev/null differ diff --git a/modular_sand/icons/mob/screen_plasmafire.dmi b/modular_sand/icons/mob/screen_plasmafire.dmi deleted file mode 100644 index 61d501dbe2..0000000000 Binary files a/modular_sand/icons/mob/screen_plasmafire.dmi and /dev/null differ diff --git a/modular_sand/icons/mob/screen_retro.dmi b/modular_sand/icons/mob/screen_retro.dmi deleted file mode 100644 index a25def4d11..0000000000 Binary files a/modular_sand/icons/mob/screen_retro.dmi and /dev/null differ diff --git a/modular_sand/icons/mob/screen_slimecore.dmi b/modular_sand/icons/mob/screen_slimecore.dmi deleted file mode 100644 index 1b51613f97..0000000000 Binary files a/modular_sand/icons/mob/screen_slimecore.dmi and /dev/null differ diff --git a/modular_sand/icons/mob/screen_trasenknox.dmi b/modular_sand/icons/mob/screen_trasenknox.dmi deleted file mode 100644 index 2cd7d59617..0000000000 Binary files a/modular_sand/icons/mob/screen_trasenknox.dmi and /dev/null differ diff --git a/sound/misc/menu/attribution.txt b/sound/misc/menu/attribution.txt new file mode 100644 index 0000000000..fa89d4cf4c --- /dev/null +++ b/sound/misc/menu/attribution.txt @@ -0,0 +1,6 @@ +ui_select made by sadboysuss +license: CC-BY-SA + +rolldown and rollup are heavily modified of: +Yunon YN500 Camera Shutter by yfjesse -- https://freesound.org/s/579884/ -- License: Creative Commons 0 + diff --git a/sound/misc/menu/menu_rolldown1.ogg b/sound/misc/menu/menu_rolldown1.ogg new file mode 100644 index 0000000000..a59529b4ad Binary files /dev/null and b/sound/misc/menu/menu_rolldown1.ogg differ diff --git a/sound/misc/menu/menu_rollup1.ogg b/sound/misc/menu/menu_rollup1.ogg new file mode 100644 index 0000000000..5f21f3adf0 Binary files /dev/null and b/sound/misc/menu/menu_rollup1.ogg differ diff --git a/sound/misc/menu/ui_select1.ogg b/sound/misc/menu/ui_select1.ogg new file mode 100644 index 0000000000..d9b3ac8f61 Binary files /dev/null and b/sound/misc/menu/ui_select1.ogg differ diff --git a/tgstation.dme b/tgstation.dme index 969c9e6a2b..b4a615444e 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -197,6 +197,7 @@ #include "code\__HELPERS\_lists.dm" #include "code\__HELPERS\_logging.dm" #include "code\__HELPERS\_string_lists.dm" +#include "code\__HELPERS\admin.dm" #include "code\__HELPERS\angles.dm" #include "code\__HELPERS\areas.dm" #include "code\__HELPERS\chat.dm" @@ -1985,6 +1986,7 @@ #include "code\modules\asset_cache\assets\common.dm" #include "code\modules\asset_cache\assets\condiments.dm" #include "code\modules\asset_cache\assets\fish.dm" +#include "code\modules\asset_cache\assets\font.dm" #include "code\modules\asset_cache\assets\fontawesome.dm" #include "code\modules\asset_cache\assets\genetics.dm" #include "code\modules\asset_cache\assets\headers.dm" @@ -4004,6 +4006,7 @@ #include "interface\fonts\fonts_datum.dm" #include "interface\fonts\grand_9k.dm" #include "interface\fonts\pixellari.dm" +#include "interface\fonts\space_mono.dm" #include "interface\fonts\spess_font.dm" #include "interface\fonts\tiny_unicode.dm" #include "interface\fonts\vcr_osd_mono.dm" diff --git a/tgui/packages/tgui/interfaces/MobInteraction/InfoSection.tsx b/tgui/packages/tgui/interfaces/MobInteraction/InfoSection.tsx index 579ebc7445..1fe6184f17 100644 --- a/tgui/packages/tgui/interfaces/MobInteraction/InfoSection.tsx +++ b/tgui/packages/tgui/interfaces/MobInteraction/InfoSection.tsx @@ -3,7 +3,7 @@ import { BlockQuote, Button, Icon, ProgressBar, Section, Slider, Stack, Tooltip type HeaderInfo = { isTargetSelf: boolean; - interactingWith: string; + target: string; lust: number; maxLust: number; selfAttributes: string[]; @@ -22,7 +22,7 @@ export const InfoSection = (props, context) => { const { act, data } = useBackend(context); const { isTargetSelf, - interactingWith, + target, lust, maxLust, selfAttributes, @@ -37,7 +37,7 @@ export const InfoSection = (props, context) => { moaning_multiplier, } = data; return ( -
+
diff --git a/tgui/packages/tgui/interfaces/MobInteraction/MainContent.tsx b/tgui/packages/tgui/interfaces/MobInteraction/MainContent.tsx index 5ab2b4bba1..f4d2393027 100644 --- a/tgui/packages/tgui/interfaces/MobInteraction/MainContent.tsx +++ b/tgui/packages/tgui/interfaces/MobInteraction/MainContent.tsx @@ -1,5 +1,6 @@ -import { useLocalState } from '../../backend'; -import { Button, Icon, Input, Section, Stack, Tabs } from '../../components'; +import { useBackend, useLocalState } from '../../backend'; +import { Button, Icon, Input, Section, Tabs, Stack, Slider } from '../../components'; + import { CharacterPrefsTab, ContentPreferencesTab, @@ -7,13 +8,27 @@ import { InteractionsTab, } from './tabs'; +type MainTypes = { + interaction_speeds: number[]; + currently_active_interaction: string; + auto_interaction_pace: number; + auto_interaction_target: string; + is_auto_target_self: boolean; +} + export const MainContent = (props, context) => { + const { act, data } = useBackend(context); const [ searchText, setSearchText, ] = useLocalState(context, 'searchText', ''); const [tabIndex, setTabIndex] = useLocalState(context, 'tabIndex', 0); + const [inFavorites, setInFavorites] = useLocalState(context, 'inFavorites', false); + + const interaction_speeds = (data.interaction_speeds || []) as number[]; + const { auto_interaction_pace, auto_interaction_target, currently_active_interaction, is_auto_target_self } = data; + return (
@@ -58,7 +73,7 @@ export const MainContent = (props, context) => { - +
{(() => { switch (tabIndex) { @@ -74,6 +89,35 @@ export const MainContent = (props, context) => { })()}
+ {tabIndex === 0 && ( + + + {!!currently_active_interaction && ( + +
); diff --git a/tgui/packages/tgui/interfaces/MobInteraction/tabs/InteractionsTab.tsx b/tgui/packages/tgui/interfaces/MobInteraction/tabs/InteractionsTab.tsx index fcc51d678d..567219f151 100644 --- a/tgui/packages/tgui/interfaces/MobInteraction/tabs/InteractionsTab.tsx +++ b/tgui/packages/tgui/interfaces/MobInteraction/tabs/InteractionsTab.tsx @@ -10,14 +10,24 @@ type ContentInfo = { interactions: InteractionData[]; favorite_interactions: string[]; user_is_blacklisted: boolean; + target: string; target_is_blacklisted: boolean; + currently_active_interaction: string; + is_auto_target_self: boolean; + auto_interaction_target: string; } type InteractionData = { key: string; desc: string; type: number; - additionalDetails: string[]; + additionalDetails: additionalDetailsContent[]; +} + +type additionalDetailsContent = { + info: string; + icon: string; + color: string; } const INTERACTION_NORMAL = 0; @@ -53,7 +63,7 @@ export const InteractionsTab = (props, context) => { ? valid_favorites : interactions; - const { user_is_blacklisted, target_is_blacklisted } = data; + const { auto_interaction_target, currently_active_interaction, is_auto_target_self, user_is_blacklisted, target, target_is_blacklisted } = data; return ( @@ -62,6 +72,21 @@ export const InteractionsTab = (props, context) => { interactions_to_display.map((interaction) => ( + {interaction.type !== INTERACTION_NORMAL && ( + +