diff --git a/code/__DEFINES/hud.dm b/code/__DEFINES/hud.dm index afea0d10c93..75e42833694 100644 --- a/code/__DEFINES/hud.dm +++ b/code/__DEFINES/hud.dm @@ -22,6 +22,155 @@ /// Largest viewport possible, required for checking if someone can see an object #define LARGEST_VIEWPORT_SIZE WIDESCREEN_VIEWPORT_SIZE +// Hud group keys +/// Static elements that are always present in standard hud +#define HUD_GROUP_STATIC 1 +/// Inventory elements toggled by the inventory switch +#define HUD_GROUP_TOGGLEABLE_INVENTORY 2 +/// Info display HUD elements +#define HUD_GROUP_INFO 3 +/// Permanently on-screen elements, regardless of your HUD status +#define HUD_GROUP_SCREEN_OVERLAYS 4 +/// Hotkey buttons +#define HUD_GROUP_HOTKEYS 5 +/// Open storages and items in them +#define HUD_GROUP_STORAGE 6 +/// Total amount of screen groups in use +#define SCREEN_GROUP_AMT 6 + +// Hud keys for accessing hud objects +#define HUD_MOB_TOGGLE_PALETTE "mob_toggle_palette" +#define HUD_MOB_PALETTE_UP "mob_palette_up" +#define HUD_MOB_PALETTE_DOWN "mob_palette_down" +#define HUD_MOB_SCREENTIP "mob_screentips" +#define HUD_MOB_HEALTH "mob_health" +#define HUD_MOB_LANGUAGE_MENU "mob_language" +#define HUD_MOB_NAVIGATE_MENU "mob_navigate" +#define HUD_MOB_INTENTS "mob_intents" +#define HUD_MOB_MOVE_INTENT "mob_move_intent" +#define HUD_MOB_ZONE_SELECTOR "mob_zonesel" +#define HUD_MOB_PULL "mob_pull" +#define HUD_MOB_DROP "mob_drop" +#define HUD_MOB_THROW "mob_throw" +#define HUD_MOB_HUNGER "mob_hunger" +#define HUD_MOB_STAMINA "mob_stamina" +#define HUD_MOB_SPACESUIT "mob_spacesuit" +#define HUD_MOB_COMBO "mob_combo" +#define HUD_MOB_RESIST "mob_resist" +#define HUD_MOB_REST "mob_rest" +#define HUD_MOB_SLEEP "mob_sleep" +#define HUD_MOB_AREA_CREATOR "mob_area_creator" +#define HUD_MOB_SWAPHAND_1 "mob_swaphand1" +#define HUD_MOB_SWAPHAND_2 "mob_swaphand2" +#define HUD_MOB_CRAFTING_MENU "mob_crafting" +#define HUD_MOB_FLOOR_CHANGER "mob_floor_changer" +#define HUD_MOB_BLOOD_LEVEL "mob_blood_level" +#define HUD_MOB_FOV_BLOCKER "mob_fov_blocker" +#define HUD_MOB_STYLE_METER "mob_style_meter" +#define HUD_MOB_MOOD "mob_mood" +#define HUD_MOB_HEALTHDOLL "mob_healthdoll" +#define HUD_MOB_MEMORIES "mob_memories" + +#define HUD_OOZE_NUTRITION_DISPLAY "ooze_nutrition_display" + +#define HUD_HUMAN_TOGGLE_INVENTORY "human_toggle_inventory" + +#define HUD_NEW_PLAYER_START_NOW "new_player_start_now" +#define HUD_NEW_PLAYER_SIGN_UP "newp_layer_sign_up" +#define HUD_KEY_NEW_PLAYER(slot) "newplayer_hud:[slot]" + +#define HUD_SILICON_TAKE_IMAGE "silicon_camera" +#define HUD_SILICON_TABLET "silicon_tablet" +#define HUD_SILICON_ALERTS "silicon_alerts" + +#define HUD_CYBORG_LAMP "cyborg_lamp" +#define HUD_CYBORG_HANDS "cyborg_module" +#define HUD_CYBORG_RADIO "cyborg_radio" +#define HUD_CYBORG_DEATH "cyborg_death" +#define HUD_KEY_CYBORG_MODULE(slot) "cyborg_module:[slot]" + +#define HUD_AI_FLOOR_INDICATOR "ai_floor_indicator" +#define HUD_AI_GO_UP "ai_go_up" +#define HUD_AI_GO_DOWN "ai_go_down" +#define HUD_AI_AICORE "ai_core" +#define HUD_AI_CAMERA_LIST "ai_camera_list" +#define HUD_AI_CAMERA_TRACK "ai_camera_track" +#define HUD_AI_CAMERA_LIGHT "ai_camera_light" +#define HUD_AI_CREW_MONITOR "ai_crew_monitor" +#define HUD_AI_CREW_MANIFEST "ai_crew_manifest" +#define HUD_AI_ANNOUNCEMENT "ai_announce" +#define HUD_AI_CALL_SHUTTLE "ai_shuttle" +#define HUD_AI_STATE_LAWS "ai_state_laws" +#define HUD_AI_TAKE_IMAGE "ai_take_image" +#define HUD_AI_IMAGE_VIEW "ai_view_image" +#define HUD_AI_SENSORS "ai_sensors" +#define HUD_AI_MULTICAM "ai_view_multicam" +#define HUD_AI_ADD_MULTICAM "ai_add_multicam" + +#define HUD_PAI_SOFTWARE "paisoftware" +#define HUD_PAI_SHELL "paishell" +#define HUD_PAI_CHASSIS "paichassis" +#define HUD_PAI_NEWSCASTER "painewscaster" +#define HUD_PAI_HOST_MONITOR "paimonitor" +#define HUD_PAI_GPS "paigps" + +#define HUD_GHOST_SPAWNERS "ghost_spawners" +#define HUD_GHOST_ORBIT "ghost_orbit" +#define HUD_GHOST_REENTER_CORPSE "ghost_corpse" +#define HUD_GHOST_TELEPORT "ghost_teleport" +#define HUD_GHOST_PAI "ghost_pai" +#define HUD_GHOST_MINIGAMES "ghost_minigames" +#define HUD_GHOST_DNR "ghost_dnr" +#define HUD_GHOST_SETTINGS "ghost_settings" +#define HUD_KEY_GHOST_HUDBOX(slot) "ghost_hudbox:[slot]" + +#define HUD_ALIEN_QUEEN_FINDER "alien_queen_finder" +#define HUD_ALIEN_PLASMA_DISPLAY "alien_plasma_display" +#define HUD_ALIEN_HUNTER_LEAP "alien_hunter_leap" + +#define HUD_BLOB_POWER_DISPLAY "blob_power_display" +#define HUD_BLOB_JUMP_TO_CORE "blob_jump_to_core" +#define HUD_BLOB_JUMP_TO_NODE "blob_jump_to_node" +#define HUD_BLOB_BLOBBERNAUT "blob_blobbernaut" +#define HUD_BLOB_RESOURCES "blob_resources" +#define HUD_BLOB_NODE "blob_node" +#define HUD_BLOB_FACTORY "blob_factory" +#define HUD_BLOB_READAPT "blob_readapt" +#define HUD_BLOB_RELOCATE "blob_relocate" + +#define HUD_BLOBBERNAUT_OVERMIND "blobbernaut_overmind" + +#define HUD_GUARDIAN_MANIFEST "guardian_manifest" +#define HUD_GUARDIAN_RECALL "guardian_recall" +#define HUD_GUARDIAN_LIGHT "guardian_light" +#define HUD_GUARDIAN_COMMUNICATE "guardian_communicate" +#define HUD_GUARDIAN_TOGGLE "guardian_toggle" + +#define HUD_VOIDWALKER_SPACE_CAMO "voidwalker_space_camo" +#define HUD_VOIDWALKER_VOID_JUMP "voidwalker_void_jump" + +#define HUD_CHANGELING_CHEMS "changeling_chems" +#define HUD_CHANGELING_STING "changeling_sting" + +#define HUD_CULTIST_ARROW "cultist_arrow" + +#define HUD_HERETIC_ARROW "heretic_arrow" +#define HUD_HERETIC_MOON_HEALTH "heretic_moon_health" + +#define HUD_WIZARD_COMPACT_PERKS "wizard_compact_perks" +#define HUD_WIZARD_PERK(slot) "wizard_perk:[slot]" + +/// Converts item slots to hud keys +#define HUD_KEY_ITEM_SLOT(slot) "item_slot:[slot]" +/// Converts item slots to hud keys as a compiler constant +#define HUD_KEY_ITEM_SLOT_CONST(slot) "item_slot:" + #slot +/// Hand2hudkey +#define HUD_KEY_HAND_SLOT(slot) "hand_slot:[slot]" + +#define HUD_MULTITOOL_ARROW "multitool_arrow" + +#define HUD_XENOBIO_CONSOLE "xenobio_console" + /* These defines specificy screen locations. For more information, see the byond documentation on the screen_loc var. @@ -63,7 +212,7 @@ #define ui_combo "CENTER+4:24,SOUTH+1:7" //combo meter for martial arts //Lower right, persistent menu -#define ui_rest "EAST-1:28,SOUTH+1:7" +#define ui_below_throw "EAST-1:28,SOUTH+1:7" #define ui_drop_throw "EAST-1:28,SOUTH+1:24" #define ui_above_throw "EAST-1:28,SOUTH+1:41" #define ui_above_movement "EAST-2:26,SOUTH+1:7" @@ -71,7 +220,6 @@ #define ui_above_intent "EAST-3:24, SOUTH+1:7" #define ui_movi "EAST-2:26,SOUTH:5" #define ui_acti "EAST-3:24,SOUTH:5" -#define ui_combat_toggle "EAST-3:24,SOUTH:5" #define ui_floor_change "BOTTOM+1:8,RIGHT-1:28" #define ui_zonesel "EAST-1:28,SOUTH:5" #define ui_acti_alt "EAST-1:28,SOUTH:5" //alternative intent switcher for when the interface is hidden (F12) @@ -123,7 +271,7 @@ #define ui_human_navigate "EAST-3:7,SOUTH+1:7" #define ui_human_language "EAST-3:7,SOUTH+1:24" #define ui_human_area "EAST-3:24,SOUTH+1:24" -#define ui_human_memories_area "EAST-4:22,SOUTH+1:7" +#define ui_human_memories_menu "EAST-4:22,SOUTH+1:7" //Drones #define ui_drone_drop "CENTER+1:18,SOUTH:5" @@ -158,6 +306,7 @@ #define ui_alien_navigate_menu "EAST-4:6,SOUTH:5" #define ui_alien_memories_menu "EAST-4:22,SOUTH:1:20" #define ui_alien_floor_change "EAST-3:24,SOUTH:20" +#define ui_alienplasmadisplay_human "EAST,CENTER-5:8" //AI #define ui_ai_core "BOTTOM:6,RIGHT-4" @@ -206,12 +355,12 @@ #define ui_ghost_spawners_menu "SOUTH:6,CENTER-3:24" #define ui_ghost_orbit "SOUTH:6,CENTER-2:24" #define ui_ghost_reenter_corpse "SOUTH:6,CENTER-1:24" -#define ui_dnr "SOUTH:6,CENTER:24" +#define ui_ghost_dnr "SOUTH:6,CENTER:24" #define ui_ghost_teleport "SOUTH:6,CENTER+1:24" -#define ui_ghost_settings "SOUTH: 6, CENTER+2:24" -#define ui_ghost_minigames "SOUTH: 6, CENTER+3:24" -#define ui_ghost_language_menu "SOUTH: 6, CENTER+4:22" -#define ui_ghost_floor_changer "SOUTH: 6, CENTER+4:7" +#define ui_ghost_settings "SOUTH:6,CENTER+2:24" +#define ui_ghost_minigames "SOUTH:6,CENTER+3:24" +#define ui_ghost_language_menu "SOUTH:6,CENTER+4:22" +#define ui_ghost_floor_changer "SOUTH:6,CENTER+4:7" //Voidwalker #define ui_voidwalker_left_of_hands "CENTER+-2:16,SOUTH+0:5" diff --git a/code/__DEFINES/sight.dm b/code/__DEFINES/sight.dm index 0a14db75ef9..ab88e6e2c30 100644 --- a/code/__DEFINES/sight.dm +++ b/code/__DEFINES/sight.dm @@ -76,4 +76,5 @@ #define INVISIBILITY_SOURCE_INVISIMIN "invisimin" #define INVISIBILITY_SOURCE_STEALTHMODE "stealthmode" +#define INVISIBILITY_SOURCE_SLEEP_HUD_BUTTON "sleep_hud_button" diff --git a/code/_onclick/hud/action_group.dm b/code/_onclick/hud/action_group.dm new file mode 100644 index 00000000000..a8766516b23 --- /dev/null +++ b/code/_onclick/hud/action_group.dm @@ -0,0 +1,209 @@ +/datum/action_group + /// The hud we're owned by + var/datum/hud/owner + /// The actions we're managing + var/list/atom/movable/screen/movable/action_button/actions + /// The initial vertical offset of our action buttons + var/north_offset = 0 + /// The pixel vertical offset of our action buttons + var/pixel_north_offset = 0 + /// Max amount of buttons we can have per row + /// Indexes at 1 + var/column_max = 0 + /// How far "ahead" of the first row we start. Lets us "scroll" our rows + /// Indexes at 1 + var/row_offset = 0 + /// How many rows of actions we can have at max before we just stop hiding + /// Indexes at 1 + var/max_rows = INFINITY + /// The screen location we go by + var/location + /// Our landing screen object + var/atom/movable/screen/action_landing/landing + +/datum/action_group/New(datum/hud/owner) + ..() + actions = list() + src.owner = owner + +/datum/action_group/Destroy() + owner = null + QDEL_NULL(landing) + QDEL_LIST(actions) + return ..() + +/datum/action_group/proc/insert_action(atom/movable/screen/action, index) + if(action in actions) + if(actions[index] == action) + return + actions -= action // Don't dupe, come on + if(!index) + index = length(actions) + 1 + index = min(length(actions) + 1, index) + actions.Insert(index, action) + refresh_actions() + +/datum/action_group/proc/remove_action(atom/movable/screen/action) + actions -= action + refresh_actions() + +/datum/action_group/proc/refresh_actions() + + // We don't use size() here because landings are not canon + var/total_rows = ROUND_UP(length(actions) / column_max) + total_rows -= max_rows // Lets get the amount of rows we're off from our max + row_offset = clamp(row_offset, 0, total_rows) // You're not allowed to offset so far that we have a row of blank space + + var/button_number = 0 + for(var/atom/movable/screen/button as anything in actions) + var/postion = ButtonNumberToScreenCoords(button_number ) + button.screen_loc = postion + button_number++ + + if(landing) + var/postion = ButtonNumberToScreenCoords(button_number, landing = TRUE) // Need a good way to count buttons off screen, but allow this to display in the right place if it's being placed with no concern for dropdown + landing.screen_loc = postion + button_number++ + +/// Accepts a number represeting our position in the group, indexes at 0 to make the math nicer +/datum/action_group/proc/ButtonNumberToScreenCoords(number, landing = FALSE) + var/row = round(number / column_max) + row -= row_offset // If you're less then 0, you don't get to render, this lets us "scroll" rows ya feel? + if(row < 0) + return null + + // Could use >= here, but I think it's worth noting that the two start at different places, since row is based on number here + if(row > max_rows - 1) + if(!landing) // If you're not a landing, go away please. thx + return null + // We always want to render landings, even if their action button can't be displayed. + // So we set a row equal to the max amount of rows + 1. Willing to overrun that max slightly to properly display the landing spot + row = max_rows // Remembering that max_rows indexes at 1, and row indexes at 0 + + // We're going to need to set our column to match the first item in the last row, so let's set number properly now + number = row * column_max + + var/visual_row = row + north_offset + var/coord_row = visual_row ? "-[visual_row]" : "+0" + + var/visual_column = number % column_max + var/coord_col = "+[visual_column]" + var/coord_col_offset = 4 + 2 * (visual_column + 1) + return "WEST[coord_col]:[coord_col_offset],NORTH[coord_row]:-[pixel_north_offset]" + +/datum/action_group/proc/check_against_view() + var/owner_view = owner?.mymob?.canon_client?.view + if(!owner_view) + return + // Unlikey as it is, we may have been changed. Want to start from our target position and fail down + column_max = initial(column_max) + // Convert our viewer's view var into a workable offset + var/list/view_size = view_to_pixels(owner_view) + + // We're primarially concerned about width here, if someone makes us 1x2000 I wish them a swift and watery death + var/furthest_screen_loc = ButtonNumberToScreenCoords(column_max - 1) + var/list/offsets = screen_loc_to_offset(furthest_screen_loc, owner_view) + if(offsets[1] > ICON_SIZE_X && offsets[1] < view_size[1] && offsets[2] > ICON_SIZE_Y && offsets[2] < view_size[2]) // We're all good + return + + for(column_max in column_max - 1 to 1 step -1) // Yes I could do this by unwrapping ButtonNumberToScreenCoords, but I don't feel like it + var/tested_screen_loc = ButtonNumberToScreenCoords(column_max) + offsets = screen_loc_to_offset(tested_screen_loc, owner_view) + // We've found a valid max length, pack it in + if(offsets[1] > ICON_SIZE_X && offsets[1] < view_size[1] && offsets[2] > ICON_SIZE_Y && offsets[2] < view_size[2]) + break + // Use our newly resized column max + refresh_actions() + +/// Returns the amount of objects we're storing at the moment +/datum/action_group/proc/size() + var/amount = length(actions) + if(landing) + amount += 1 + return amount + +/datum/action_group/proc/index_of(atom/movable/screen/get_location) + return actions.Find(get_location) + +/// Generates a landing object that can be dropped on to join this group +/datum/action_group/proc/generate_landing() + if(landing) + return + landing = new() + landing.set_owner(src) + refresh_actions() + +/// Clears any landing objects we may currently have +/datum/action_group/proc/clear_landing() + QDEL_NULL(landing) + +/datum/action_group/proc/update_landing() + if(!landing) + return + landing.refresh_owner() + +/datum/action_group/proc/scroll(amount) + row_offset += amount + refresh_actions() + +/datum/action_group/palette + north_offset = 2 + column_max = 3 + max_rows = 3 + location = SCRN_OBJ_IN_PALETTE + +/datum/action_group/palette/insert_action(atom/movable/screen/action, index) + . = ..() + var/atom/movable/screen/button_palette/palette = owner.screen_objects[HUD_MOB_TOGGLE_PALETTE] + palette.play_item_added() + +/datum/action_group/palette/remove_action(atom/movable/screen/action) + . = ..() + var/atom/movable/screen/button_palette/palette = owner.screen_objects[HUD_MOB_TOGGLE_PALETTE] + palette.play_item_removed() + if(!length(actions)) + palette.set_expanded(FALSE) + +/datum/action_group/palette/refresh_actions() + var/atom/movable/screen/button_palette/palette = owner.screen_objects[HUD_MOB_TOGGLE_PALETTE] + var/atom/movable/screen/palette_scroll/scroll_down = owner.screen_objects[HUD_MOB_PALETTE_DOWN] + var/atom/movable/screen/palette_scroll/scroll_up = owner.screen_objects[HUD_MOB_PALETTE_UP] + + var/actions_above = round((owner.listed_actions.size() - 1) / owner.listed_actions.column_max) + north_offset = initial(north_offset) + actions_above + + palette.screen_loc = ui_action_palette_offset(actions_above) + var/action_count = length(owner?.mymob?.actions) + var/our_row_count = round((length(actions) - 1) / column_max) + if(!action_count) + palette.screen_loc = null + + if(palette.expanded && action_count && our_row_count >= max_rows) + scroll_down.screen_loc = ui_palette_scroll_offset(actions_above) + scroll_up.screen_loc = ui_palette_scroll_offset(actions_above) + else + scroll_down.screen_loc = null + scroll_up.screen_loc = null + + return ..() + +/datum/action_group/palette/ButtonNumberToScreenCoords(number, landing) + var/atom/movable/screen/button_palette/palette = owner.screen_objects[HUD_MOB_TOGGLE_PALETTE] + if(palette.expanded) + return ..() + + if(!landing) + return null + + // We only render the landing in this case, so we force it to be the second item displayed (Second rather then first since it looks nicer) + // Remember the number var indexes at 0 + return ..(1 + (row_offset * column_max), landing) + +/datum/action_group/listed + pixel_north_offset = 6 + column_max = 10 + location = SCRN_OBJ_IN_LIST + +/datum/action_group/listed/refresh_actions() + . = ..() + owner?.palette_actions.refresh_actions() // We effect them, so we gotta refresh em diff --git a/code/_onclick/hud/ai.dm b/code/_onclick/hud/ai.dm index 728439e5fad..84e303a8894 100644 --- a/code/_onclick/hud/ai.dm +++ b/code/_onclick/hud/ai.dm @@ -1,345 +1,26 @@ -/atom/movable/screen/ai - icon = 'icons/hud/screen_ai.dmi' - mouse_over_pointer = MOUSE_HAND_POINTER - -/atom/movable/screen/ai/Click() - if(isobserver(usr) || usr.incapacitated) - return TRUE - -/atom/movable/screen/ai/aicore - name = "AI core" - icon_state = "ai_core" - -/atom/movable/screen/ai/aicore/Click() - if(isobserver(usr)) - return - var/mob/living/silicon/ai/AI = usr - AI.view_core() - -/atom/movable/screen/ai/camera_list - name = "Show Camera List" - icon_state = "camera" - -/atom/movable/screen/ai/camera_list/Click() - if(..()) - return - var/mob/living/silicon/ai/AI = usr - AI.show_camera_list() - -/atom/movable/screen/ai/camera_track - name = "Track With Camera" - icon_state = "track" - -/atom/movable/screen/ai/camera_track/Click() - . = ..() - if(.) - return - var/mob/living/silicon/ai/AI = usr - AI.ai_camera_track() - -/atom/movable/screen/ai/camera_light - name = "Toggle Camera Light" - icon_state = "camera_light" - -/atom/movable/screen/ai/camera_light/Click() - if(..()) - return - var/mob/living/silicon/ai/AI = usr - AI.toggle_camera_light() - -/atom/movable/screen/ai/modpc - name = "Messenger" - icon_state = "pda_send" - var/mob/living/silicon/ai/robot - -/atom/movable/screen/ai/modpc/Click() - . = ..() - if(.) - return - robot.modularInterface?.interact(robot) - -/atom/movable/screen/ai/crew_monitor - name = "Crew Monitoring Console" - icon_state = "crew_monitor" - -/atom/movable/screen/ai/crew_monitor/Click() - if(..()) - return - var/mob/living/silicon/ai/AI = usr - GLOB.crewmonitor.show(AI,AI) - -/atom/movable/screen/ai/crew_manifest - name = "Crew Manifest" - icon_state = "manifest" - -/atom/movable/screen/ai/crew_manifest/Click() - if(..()) - return - var/mob/living/silicon/ai/AI = usr - AI.ai_roster() - -/atom/movable/screen/ai/alerts - name = "Show Alerts" - icon_state = "alerts" - -/atom/movable/screen/ai/alerts/Click() - if(..()) - return - var/mob/living/silicon/ai/AI = usr - AI.alert_control.ui_interact(AI) - -/atom/movable/screen/ai/announcement - name = "Make Vox Announcement" - icon_state = "announcement" - -/atom/movable/screen/ai/announcement/Click() - if(..()) - return - var/mob/living/silicon/ai/AI = usr - AI.announcement() - -/atom/movable/screen/ai/call_shuttle - name = "Call Emergency Shuttle" - icon_state = "call_shuttle" - -/atom/movable/screen/ai/call_shuttle/Click() - if(..()) - return - var/mob/living/silicon/ai/AI = usr - AI.ai_call_shuttle() - -/atom/movable/screen/ai/state_laws - name = "State Laws" - icon_state = "state_laws" - -/atom/movable/screen/ai/state_laws/Click() - if(..()) - return - var/mob/living/silicon/ai/AI = usr - AI.checklaws() - -/atom/movable/screen/ai/image_take - name = "Take Image" - icon_state = "take_picture" - -/atom/movable/screen/ai/image_take/Click() - if(..()) - return - if(isAI(usr)) - var/mob/living/silicon/ai/AI = usr - AI.aicamera.toggle_camera_mode(usr) - else if(iscyborg(usr)) - var/mob/living/silicon/robot/R = usr - R.aicamera.toggle_camera_mode(usr) - -/atom/movable/screen/ai/image_view - name = "View Images" - icon_state = "view_images" - -/atom/movable/screen/ai/image_view/Click() - if(..()) - return - if(isAI(usr)) - var/mob/living/silicon/ai/AI = usr - AI.aicamera.viewpictures(usr) - -/atom/movable/screen/ai/sensors - name = "Sensor Augmentation" - icon_state = "ai_sensor" - -/atom/movable/screen/ai/sensors/Click() - if(..()) - return - var/mob/living/silicon/S = usr - S.toggle_sensors() - -/atom/movable/screen/ai/multicam - name = "Multicamera Mode" - icon_state = "multicam" - -/atom/movable/screen/ai/multicam/Click() - if(..()) - return - var/mob/living/silicon/ai/AI = usr - AI.toggle_multicam() - -/atom/movable/screen/ai/add_multicam - name = "New Camera" - icon_state = "new_cam" - -/atom/movable/screen/ai/add_multicam/Click() - if(..()) - return - var/mob/living/silicon/ai/AI = usr - AI.drop_new_multicam() - -/atom/movable/screen/ai/floor_indicator - icon_state = "zindicator" - screen_loc = ui_ai_floor_indicator - -/atom/movable/screen/ai/floor_indicator/Initialize(mapload, datum/hud/hud_owner) - . = ..() - if(istype(hud_owner)) - RegisterSignal(hud_owner, COMSIG_HUD_OFFSET_CHANGED, PROC_REF(update_z)) - update_z() - -/atom/movable/screen/ai/floor_indicator/proc/update_z(datum/hud/source) - SIGNAL_HANDLER - var/mob/living/silicon/ai/ai = get_mob() //if you use this for anyone else i will find you - if(isnull(ai)) - return - var/turf/locturf = isturf(ai.loc) ? get_turf(ai.eyeobj) : get_turf(ai) //must be a var cuz error - var/ai_z = locturf.z - var/text = "Level
[ai_z]" - if(SSmapping.level_trait(ai_z, ZTRAIT_STATION)) - text = "Floor
[ai_z - 1]" - else if (SSmapping.level_trait(ai_z, ZTRAIT_NOPHASE)) - text = "ERROR" - maptext = MAPTEXT_TINY_UNICODE("
[text]
") - -/atom/movable/screen/ai/go_up - name = "go up" - icon_state = "up" - screen_loc = ui_ai_godownup - -/atom/movable/screen/ai/go_up/Initialize(mapload) - . = ..() - register_context() - -/atom/movable/screen/ai/go_up/add_context(atom/source, list/context, obj/item/held_item, mob/user) - . = ..() - context[SCREENTIP_CONTEXT_LMB] = "Go up a floor" - return CONTEXTUAL_SCREENTIP_SET - -/atom/movable/screen/ai/go_up/Click(location,control,params) - var/mob/ai = get_mob() //the core - flick("uppressed",src) - if(!isturf(ai.loc) || usr != ai) //aicard and stuff - return - ai.up() - -/atom/movable/screen/ai/go_up/down - name = "go down" - icon_state = "down" - -/atom/movable/screen/ai/go_up/down/add_context(atom/source, list/context, obj/item/held_item, mob/user) - . = ..() - context[SCREENTIP_CONTEXT_LMB] = "Go down a floor" - return CONTEXTUAL_SCREENTIP_SET - -/atom/movable/screen/ai/go_up/down/Click(location,control,params) - var/mob/ai = get_mob() //the core - flick("downpressed",src) - if(!isturf(ai.loc) || usr != ai) //aicard and stuff - return - ai.down() - /datum/hud/ai ui_style = 'icons/hud/screen_ai.dmi' -/datum/hud/ai/New(mob/owner) - ..() - var/atom/movable/screen/using - var/mob/living/silicon/ai/myai = mymob - -// Language menu - using = new /atom/movable/screen/language_menu(null, src) - using.icon = ui_style - using.screen_loc = ui_ai_language_menu - static_inventory += using - -// Memories - using = new /atom/movable/screen/memories(null, src) - using.icon = ui_style - using.screen_loc = ui_ai_memories_menu - static_inventory += using - -// Z-level floor change - using = new /atom/movable/screen/ai/floor_indicator(null, src) //These come with their own predefined screen locs - static_inventory += using - using = new /atom/movable/screen/ai/go_up(null, src) - static_inventory += using - using = new /atom/movable/screen/ai/go_up/down(null, src) - static_inventory += using - -//AI core - using = new /atom/movable/screen/ai/aicore(null, src) - using.screen_loc = ui_ai_core - static_inventory += using - -//Camera list - using = new /atom/movable/screen/ai/camera_list(null, src) - using.screen_loc = ui_ai_camera_list - static_inventory += using - -//Track - using = new /atom/movable/screen/ai/camera_track(null, src) - using.screen_loc = ui_ai_track_with_camera - static_inventory += using - -//Camera light - using = new /atom/movable/screen/ai/camera_light(null, src) - using.screen_loc = ui_ai_camera_light - static_inventory += using - -//Crew Monitoring - using = new /atom/movable/screen/ai/crew_monitor(null, src) - using.screen_loc = ui_ai_crew_monitor - static_inventory += using - -//Crew Manifest - using = new /atom/movable/screen/ai/crew_manifest(null, src) - using.screen_loc = ui_ai_crew_manifest - static_inventory += using - -//Alerts - using = new /atom/movable/screen/ai/alerts(null, src) - using.screen_loc = ui_ai_alerts - static_inventory += using - -//Announcement - using = new /atom/movable/screen/ai/announcement(null, src) - using.screen_loc = ui_ai_announcement - static_inventory += using - -//Shuttle - using = new /atom/movable/screen/ai/call_shuttle(null, src) - using.screen_loc = ui_ai_shuttle - static_inventory += using - -//Laws - using = new /atom/movable/screen/ai/state_laws(null, src) - using.screen_loc = ui_ai_state_laws - static_inventory += using - -// Modular Interface - using = new /atom/movable/screen/ai/modpc(null, src) - using.screen_loc = ui_ai_mod_int - static_inventory += using - var/atom/movable/screen/ai/modpc/tabletbutton = using - tabletbutton.robot = myai - -//Take image - using = new /atom/movable/screen/ai/image_take(null, src) - using.screen_loc = ui_ai_take_picture - static_inventory += using - -//View images - using = new /atom/movable/screen/ai/image_view(null, src) - using.screen_loc = ui_ai_view_images - static_inventory += using - -//Medical/Security sensors - using = new /atom/movable/screen/ai/sensors(null, src) - using.screen_loc = ui_ai_sensor - static_inventory += using - -//Multicamera mode - using = new /atom/movable/screen/ai/multicam(null, src) - using.screen_loc = ui_ai_multicam - static_inventory += using - -//Add multicamera camera - using = new /atom/movable/screen/ai/add_multicam(null, src) - using.screen_loc = ui_ai_add_multicam - static_inventory += using +/datum/hud/ai/initialize_screen_objects() + . = ..() + add_screen_object(/atom/movable/screen/language_menu, HUD_MOB_LANGUAGE_MENU, HUD_GROUP_STATIC, ui_style, ui_ai_language_menu) + add_screen_object(/atom/movable/screen/memories, HUD_MOB_MEMORIES, HUD_GROUP_STATIC, ui_style, ui_ai_memories_menu) + add_screen_object(/atom/movable/screen/ai/floor_indicator, HUD_AI_FLOOR_INDICATOR) + add_screen_object(/atom/movable/screen/ai/go_up, HUD_AI_GO_UP) + add_screen_object(/atom/movable/screen/ai/go_up/down, HUD_AI_GO_DOWN) + add_screen_object(/atom/movable/screen/ai/aicore, HUD_AI_AICORE) + add_screen_object(/atom/movable/screen/ai/camera_list, HUD_AI_CAMERA_LIST) + add_screen_object(/atom/movable/screen/ai/camera_track, HUD_AI_CAMERA_TRACK) + add_screen_object(/atom/movable/screen/ai/camera_light, HUD_AI_CAMERA_LIGHT) + add_screen_object(/atom/movable/screen/ai/crew_monitor, HUD_AI_CREW_MONITOR) + add_screen_object(/atom/movable/screen/ai/crew_manifest, HUD_AI_CREW_MANIFEST) + add_screen_object(/atom/movable/screen/ai/alerts, HUD_SILICON_ALERTS) + add_screen_object(/atom/movable/screen/ai/announcement, HUD_AI_ANNOUNCEMENT) + add_screen_object(/atom/movable/screen/ai/call_shuttle, HUD_AI_CALL_SHUTTLE) + add_screen_object(/atom/movable/screen/ai/state_laws, HUD_AI_STATE_LAWS) + add_screen_object(/atom/movable/screen/ai/image_take, HUD_AI_TAKE_IMAGE) + add_screen_object(/atom/movable/screen/ai/image_view, HUD_AI_IMAGE_VIEW) + add_screen_object(/atom/movable/screen/ai/sensors, HUD_AI_SENSORS) + add_screen_object(/atom/movable/screen/ai/multicam, HUD_AI_MULTICAM) + add_screen_object(/atom/movable/screen/ai/add_multicam, HUD_AI_ADD_MULTICAM) + add_screen_object(/atom/movable/screen/ai/modpc, HUD_SILICON_TABLET) diff --git a/code/_onclick/hud/alien.dm b/code/_onclick/hud/alien.dm index 822fe712850..4ea86de55e7 100644 --- a/code/_onclick/hud/alien.dm +++ b/code/_onclick/hud/alien.dm @@ -1,136 +1,36 @@ -/atom/movable/screen/alien - icon = 'icons/hud/screen_alien.dmi' - -/atom/movable/screen/alien/leap - name = "toggle leap" - icon_state = "leap_off" - -/atom/movable/screen/alien/leap/Click() - if(isalienhunter(usr)) - var/mob/living/carbon/alien/adult/hunter/AH = usr - AH.toggle_leap() - -/atom/movable/screen/alien/plasma_display - name = "plasma stored" - icon_state = "power_display" - screen_loc = ui_alienplasmadisplay - -/atom/movable/screen/alien/alien_queen_finder - name = "queen sense" - desc = "Allows you to sense the general direction of your Queen." - icon_state = "queen_finder" - screen_loc = ui_alien_queen_finder - /datum/hud/alien ui_style = 'icons/hud/screen_alien.dmi' -/datum/hud/alien/New(mob/living/carbon/alien/adult/owner) - ..() - - var/atom/movable/screen/using - -//equippable shit - -//hands +/datum/hud/alien/initialize_screen_objects() + . = ..() build_hand_slots() -//begin buttons - - using = new /atom/movable/screen/swap_hand(null, src) - using.icon = ui_style + var/atom/movable/screen/using + using = add_screen_object(/atom/movable/screen/swap_hand, HUD_MOB_SWAPHAND_1, HUD_GROUP_STATIC, ui_style, ui_swaphand_position(mymob, 1)) using.icon_state = "swap_1" - using.screen_loc = ui_swaphand_position(owner, 1) - static_inventory += using - - using = new /atom/movable/screen/swap_hand(null, src) - using.icon = ui_style + using = add_screen_object(/atom/movable/screen/swap_hand, HUD_MOB_SWAPHAND_2, HUD_GROUP_STATIC, ui_style, ui_swaphand_position(mymob, 2)) using.icon_state = "swap_2" - using.screen_loc = ui_swaphand_position(owner, 2) - static_inventory += using - action_intent = new /atom/movable/screen/combattoggle/flashy(null, src) - action_intent.icon = ui_style - action_intent.screen_loc = ui_combat_toggle - static_inventory += action_intent + add_screen_object(/atom/movable/screen/combattoggle/flashy, HUD_MOB_INTENTS, HUD_GROUP_STATIC, ui_style) + add_screen_object(/atom/movable/screen/floor_changer, HUD_MOB_FLOOR_CHANGER, HUD_GROUP_STATIC, ui_style, ui_alien_floor_change) + add_screen_object(/atom/movable/screen/language_menu, HUD_MOB_LANGUAGE_MENU, HUD_GROUP_STATIC, ui_style, ui_alien_language_menu) + add_screen_object(/atom/movable/screen/navigate, HUD_MOB_NAVIGATE_MENU, HUD_GROUP_STATIC, ui_style, ui_alien_navigate_menu) + add_screen_object(/atom/movable/screen/zone_sel/alien, HUD_MOB_ZONE_SELECTOR) + add_screen_object(/atom/movable/screen/drop, HUD_MOB_DROP, HUD_GROUP_STATIC, ui_style) + add_screen_object(/atom/movable/screen/pull, HUD_MOB_PULL, HUD_GROUP_STATIC, ui_style, ui_above_movement) + add_screen_object(/atom/movable/screen/resist, HUD_MOB_RESIST, HUD_GROUP_HOTKEYS, ui_style) + add_screen_object(/atom/movable/screen/throw_catch, HUD_MOB_THROW, HUD_GROUP_HOTKEYS, ui_style) + add_screen_object(/atom/movable/screen/rest, HUD_MOB_REST, HUD_GROUP_HOTKEYS, ui_style) + add_screen_object(/atom/movable/screen/sleep, HUD_MOB_SLEEP, HUD_GROUP_HOTKEYS, ui_style) + add_screen_object(/atom/movable/screen/healths/alien, HUD_MOB_HEALTH, HUD_GROUP_INFO) + add_screen_object(/atom/movable/screen/alien/plasma_display, HUD_ALIEN_PLASMA_DISPLAY, HUD_GROUP_INFO) + add_screen_object(/atom/movable/screen/memories, HUD_MOB_MEMORIES, HUD_GROUP_STATIC, ui_style, ui_alien_memories_menu) if(isalienhunter(mymob)) - var/mob/living/carbon/alien/adult/hunter/H = mymob - H.leap_icon = new /atom/movable/screen/alien/leap() - H.leap_icon.screen_loc = ui_alien_storage_r - static_inventory += H.leap_icon - - floor_change = new /atom/movable/screen/floor_changer(null, src) - floor_change.icon = ui_style - floor_change.screen_loc = ui_alien_floor_change - static_inventory += floor_change - - using = new/atom/movable/screen/language_menu(null, src) - using.icon = ui_style - using.screen_loc = ui_alien_language_menu - static_inventory += using - - using = new /atom/movable/screen/navigate(null, src) - using.icon = ui_style - using.screen_loc = ui_alien_navigate_menu - static_inventory += using - - using = new /atom/movable/screen/memories(null, src) - using.icon = ui_style - using.screen_loc = ui_alien_memories_menu - static_inventory += using - - using = new /atom/movable/screen/drop(null, src) - using.icon = ui_style - using.screen_loc = ui_drop_throw - static_inventory += using - - resist_icon = new /atom/movable/screen/resist(null, src) - resist_icon.icon = ui_style - resist_icon.screen_loc = ui_above_movement - resist_icon.update_appearance() - hotkeybuttons += resist_icon - - throw_icon = new /atom/movable/screen/throw_catch(null, src) - throw_icon.icon = ui_style - throw_icon.screen_loc = ui_drop_throw - hotkeybuttons += throw_icon - - pull_icon = new /atom/movable/screen/pull(null, src) - pull_icon.icon = ui_style - pull_icon.update_appearance() - pull_icon.screen_loc = ui_above_movement - static_inventory += pull_icon - - rest_icon = new /atom/movable/screen/rest(null, src) - rest_icon.icon = ui_style - rest_icon.screen_loc = ui_rest - rest_icon.update_appearance() - static_inventory += rest_icon - - sleep_icon = new /atom/movable/screen/sleep(null, src) - sleep_icon.icon = ui_style - sleep_icon.screen_loc = ui_above_throw - -//begin indicators - - healths = new /atom/movable/screen/healths/alien(null, src) - infodisplay += healths - - alien_plasma_display = new /atom/movable/screen/alien/plasma_display(null, src) - infodisplay += alien_plasma_display + add_screen_object(/atom/movable/screen/alien/leap, HUD_ALIEN_HUNTER_LEAP, HUD_GROUP_STATIC, ui_style) if(!isalienqueen(mymob)) - 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(null, src) - zone_select.update_appearance() - static_inventory += zone_select - - for(var/atom/movable/screen/inventory/inv in (static_inventory + toggleable_inventory)) - if(inv.slot_id) - inv_slots[TOBITSHIFT(inv.slot_id) + 1] = inv - inv.update_appearance() + add_screen_object(/atom/movable/screen/alien/plasma_display, HUD_ALIEN_QUEEN_FINDER, HUD_GROUP_INFO) /datum/hud/alien/persistent_inventory_update() if(!mymob) diff --git a/code/_onclick/hud/alien_larva.dm b/code/_onclick/hud/alien_larva.dm index 3331ac8c790..25ae3ba34bb 100644 --- a/code/_onclick/hud/alien_larva.dm +++ b/code/_onclick/hud/alien_larva.dm @@ -1,54 +1,16 @@ /datum/hud/larva ui_style = 'icons/hud/screen_alien.dmi' -/datum/hud/larva/New(mob/owner) - ..() - var/atom/movable/screen/using - - action_intent = new /atom/movable/screen/combattoggle/flashy(null, src) - action_intent.icon = ui_style - action_intent.screen_loc = ui_combat_toggle - static_inventory += action_intent - - floor_change = new /atom/movable/screen/floor_changer(null, src) - floor_change.icon = ui_style - floor_change.screen_loc = ui_alien_floor_change - static_inventory += floor_change - - healths = new /atom/movable/screen/healths/alien(null, src) - infodisplay += healths - - alien_queen_finder = new /atom/movable/screen/alien/alien_queen_finder(null, src) - infodisplay += alien_queen_finder - - pull_icon = new /atom/movable/screen/pull(null, src) - pull_icon.icon = 'icons/hud/screen_alien.dmi' - pull_icon.update_appearance() - pull_icon.screen_loc = ui_above_movement - hotkeybuttons += pull_icon - - rest_icon = new /atom/movable/screen/rest(null, src) - rest_icon.icon = ui_style - rest_icon.screen_loc = ui_rest - rest_icon.update_appearance() - static_inventory += rest_icon - - sleep_icon = new /atom/movable/screen/sleep(null, src) - sleep_icon.icon = ui_style - sleep_icon.screen_loc = ui_drop_throw - - using = new/atom/movable/screen/language_menu(null, src) - using.screen_loc = ui_alien_language_menu - static_inventory += using - - using = new /atom/movable/screen/navigate(null, src) - using.screen_loc = ui_alien_navigate_menu - static_inventory += using - - using = new /atom/movable/screen/memories(null, src) - using.screen_loc = ui_alien_memories_menu - static_inventory += using - - zone_select = new /atom/movable/screen/zone_sel/alien(null, src) - zone_select.update_appearance() - static_inventory += zone_select +/datum/hud/larva/initialize_screen_objects() + . = ..() + add_screen_object(/atom/movable/screen/combattoggle/flashy, HUD_MOB_INTENTS, HUD_GROUP_STATIC, ui_style) + add_screen_object(/atom/movable/screen/floor_changer, HUD_MOB_FLOOR_CHANGER, HUD_GROUP_STATIC, ui_style, ui_alien_floor_change) + add_screen_object(/atom/movable/screen/pull, HUD_MOB_PULL, HUD_GROUP_STATIC, ui_style) + add_screen_object(/atom/movable/screen/rest, HUD_MOB_REST, HUD_GROUP_HOTKEYS, ui_style) + add_screen_object(/atom/movable/screen/sleep, HUD_MOB_SLEEP, HUD_GROUP_HOTKEYS, ui_style, ui_drop_throw) + add_screen_object(/atom/movable/screen/language_menu, HUD_MOB_LANGUAGE_MENU, ui_loc = ui_alien_language_menu) + add_screen_object(/atom/movable/screen/navigate, HUD_MOB_NAVIGATE_MENU, ui_loc = ui_alien_navigate_menu) + add_screen_object(/atom/movable/screen/zone_sel/alien, HUD_MOB_ZONE_SELECTOR) + add_screen_object(/atom/movable/screen/healths/alien, HUD_MOB_HEALTH, HUD_GROUP_INFO) + add_screen_object(/atom/movable/screen/alien/alien_queen_finder, HUD_ALIEN_QUEEN_FINDER, HUD_GROUP_INFO) + add_screen_object(/atom/movable/screen/memories, HUD_MOB_MEMORIES, HUD_GROUP_STATIC, ui_style, ui_alien_memories_menu) diff --git a/code/_onclick/hud/blob_overmind.dm b/code/_onclick/hud/blob_overmind.dm index 6b5213c027b..cf92ff67b47 100644 --- a/code/_onclick/hud/blob_overmind.dm +++ b/code/_onclick/hud/blob_overmind.dm @@ -1,198 +1,12 @@ - -/atom/movable/screen/blob - icon = 'icons/hud/blob.dmi' - mouse_over_pointer = MOUSE_HAND_POINTER - -/atom/movable/screen/blob/MouseEntered(location,control,params) +/datum/hud/blob_overmind/initialize_screen_objects() . = ..() - openToolTip(usr,src,params,title = name,content = desc, theme = "blob") - -/atom/movable/screen/blob/MouseExited() - closeToolTip(usr) - -/atom/movable/screen/blob/jump_to_node - icon_state = "ui_tonode" - name = "Jump to Node" - desc = "Moves your camera to a selected blob node." - -/atom/movable/screen/blob/jump_to_node/Click() - if(!isovermind(usr)) - return FALSE - var/mob/eye/blob/blob = usr - blob.jump_to_node() - -/atom/movable/screen/blob/jump_to_core - icon_state = "ui_tocore" - name = "Jump to Core" - desc = "Moves your camera to your blob core." - -/atom/movable/screen/blob/jump_to_core/MouseEntered(location,control,params) - if(hud?.mymob && isovermind(hud.mymob)) - var/mob/eye/blob/B = hud.mymob - if(!B.placed) - name = "Place Blob Core" - desc = "Attempt to place your blob core at this location." - else - name = initial(name) - desc = initial(desc) - return ..() - -/atom/movable/screen/blob/jump_to_core/Click() - if(!isovermind(usr)) - return FALSE - var/mob/eye/blob/blob = usr - if(!blob.placed) - blob.place_blob_core(BLOB_NORMAL_PLACEMENT) - blob.transport_core() - -/atom/movable/screen/blob/blobbernaut - icon_state = "ui_blobbernaut" - // Name and description get given their proper values on Initialize() - name = "Produce Blobbernaut (ERROR)" - desc = "Produces a strong, smart blobbernaut from a factory blob for (ERROR) resources.
The factory blob used will become fragile and unable to produce spores." - -/atom/movable/screen/blob/blobbernaut/Initialize(mapload, datum/hud/hud_owner) - . = ..() - name = "Produce Blobbernaut ([BLOBMOB_BLOBBERNAUT_RESOURCE_COST])" - desc = "Produces a strong, smart blobbernaut from a factory blob for [BLOBMOB_BLOBBERNAUT_RESOURCE_COST] resources.
The factory blob used will become fragile and unable to produce spores." - -/atom/movable/screen/blob/blobbernaut/Click() - if(!isovermind(usr)) - return FALSE - var/mob/eye/blob/blob = usr - blob.create_blobbernaut() - -/atom/movable/screen/blob/resource_blob - icon_state = "ui_resource" - // Name and description get given their proper values on Initialize() - name = "Produce Resource Blob (ERROR)" - desc = "Produces a resource blob for ERROR resources.
Resource blobs will give you resources every few seconds." - -/atom/movable/screen/blob/resource_blob/Initialize(mapload, datum/hud/hud_owner) - . = ..() - name = "Produce Resource Blob ([BLOB_STRUCTURE_RESOURCE_COST])" - desc = "Produces a resource blob for [BLOB_STRUCTURE_RESOURCE_COST] resources.
Resource blobs will give you resources every few seconds." - -/atom/movable/screen/blob/resource_blob/Click() - if(!isovermind(usr)) - return FALSE - var/mob/eye/blob/blob = usr - blob.create_special(BLOB_STRUCTURE_RESOURCE_COST, /obj/structure/blob/special/resource, BLOB_RESOURCE_MIN_DISTANCE, TRUE) - -/atom/movable/screen/blob/node_blob - icon_state = "ui_node" - // Name and description get given their proper values on Initialize() - name = "Produce Node Blob (ERROR)" - desc = "Produces a node blob for ERROR resources.
Node blobs will expand and activate nearby resource and factory blobs." - -/atom/movable/screen/blob/node_blob/Initialize(mapload, datum/hud/hud_owner) - . = ..() - name = "Produce Node Blob ([BLOB_STRUCTURE_NODE_COST])" - desc = "Produces a node blob for [BLOB_STRUCTURE_NODE_COST] resources.
Node blobs will expand and activate nearby resource and factory blobs." - -/atom/movable/screen/blob/node_blob/Click() - if(!isovermind(usr)) - return FALSE - var/mob/eye/blob/blob = usr - blob.create_special(BLOB_STRUCTURE_NODE_COST, /obj/structure/blob/special/node, BLOB_NODE_MIN_DISTANCE, FALSE) - -/atom/movable/screen/blob/factory_blob - icon_state = "ui_factory" - // Name and description get given their proper values on Initialize() - name = "Produce Factory Blob (ERROR)" - desc = "Produces a factory blob for ERROR resources.
Factory blobs will produce spores every few seconds." - -/atom/movable/screen/blob/factory_blob/Initialize(mapload, datum/hud/hud_owner) - . = ..() - name = "Produce Factory Blob ([BLOB_STRUCTURE_FACTORY_COST])" - desc = "Produces a factory blob for [BLOB_STRUCTURE_FACTORY_COST] resources.
Factory blobs will produce spores every few seconds." - -/atom/movable/screen/blob/factory_blob/Click() - if(!isovermind(usr)) - return FALSE - var/mob/eye/blob/blob = usr - blob.create_special(BLOB_STRUCTURE_FACTORY_COST, /obj/structure/blob/special/factory, BLOB_FACTORY_MIN_DISTANCE, TRUE) - -/atom/movable/screen/blob/readapt_strain - icon_state = "ui_chemswap" - // Description gets given its proper values on Initialize() - name = "Readapt Strain" - desc = "Allows you to choose a new strain from ERROR random choices for ERROR resources." - -/atom/movable/screen/blob/readapt_strain/MouseEntered(location,control,params) - if(hud?.mymob && isovermind(hud.mymob)) - var/mob/eye/blob/B = hud.mymob - if(B.free_strain_rerolls) - name = "[initial(name)] (FREE)" - desc = "Randomly rerolls your strain for free." - else - name = "[initial(name)] ([BLOB_POWER_REROLL_COST])" - desc = "Allows you to choose a new strain from [BLOB_POWER_REROLL_CHOICES] random choices for [BLOB_POWER_REROLL_COST] resources." - return ..() - -/atom/movable/screen/blob/readapt_strain/Click() - if(isovermind(usr)) - var/mob/eye/blob/B = usr - B.strain_reroll() - -/atom/movable/screen/blob/relocate_core - icon_state = "ui_swap" - // Name and description get given their proper values on Initialize() - name = "Relocate Core (ERROR)" - desc = "Swaps a node and your core for ERROR resources." - -/atom/movable/screen/blob/relocate_core/Initialize(mapload, datum/hud/hud_owner) - . = ..() - name = "Relocate Core ([BLOB_POWER_RELOCATE_COST])" - desc = "Swaps a node and your core for [BLOB_POWER_RELOCATE_COST] resources." - -/atom/movable/screen/blob/relocate_core/Click() - if(isovermind(usr)) - var/mob/eye/blob/B = usr - B.relocate_core() - -/atom/movable/screen/blob_power_display - name = "blob power" - icon_state = "block" - screen_loc = ui_health - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - plane = ABOVE_HUD_PLANE - -/datum/hud/blob_overmind/New(mob/owner) - ..() - var/atom/movable/screen/using - - healths = new /atom/movable/screen/healths/blob(null, src) - infodisplay += healths - - using = new /atom/movable/screen/blob/jump_to_node(null, src) - using.screen_loc = ui_inventory - static_inventory += using - - using = new /atom/movable/screen/blob/jump_to_core(null, src) - using.screen_loc = ui_zonesel - static_inventory += using - - using = new /atom/movable/screen/blob/blobbernaut(null, src) - using.screen_loc = ui_belt - static_inventory += using - - using = new /atom/movable/screen/blob/resource_blob(null, src) - using.screen_loc = ui_back - static_inventory += using - - using = new /atom/movable/screen/blob/node_blob(null, src) - using.screen_loc = ui_hand_position(RIGHT_HANDS) - static_inventory += using - - using = new /atom/movable/screen/blob/factory_blob(null, src) - using.screen_loc = ui_hand_position(LEFT_HANDS) - static_inventory += using - - using = new /atom/movable/screen/blob/readapt_strain(null, src) - using.screen_loc = ui_storage1 - static_inventory += using - - using = new /atom/movable/screen/blob/relocate_core(null, src) - using.screen_loc = ui_storage2 - static_inventory += using + add_screen_object(/atom/movable/screen/healths/blob, HUD_MOB_HEALTH, HUD_GROUP_INFO) + add_screen_object(/atom/movable/screen/blob/blob_power, HUD_BLOB_POWER_DISPLAY, HUD_GROUP_INFO) + add_screen_object(/atom/movable/screen/blob/jump_to_node, HUD_BLOB_JUMP_TO_NODE) + add_screen_object(/atom/movable/screen/blob/jump_to_core, HUD_BLOB_JUMP_TO_CORE) + add_screen_object(/atom/movable/screen/blob/blobbernaut, HUD_BLOB_BLOBBERNAUT) + add_screen_object(/atom/movable/screen/blob/resource_blob, HUD_BLOB_RESOURCES) + add_screen_object(/atom/movable/screen/blob/node_blob, HUD_BLOB_NODE, ui_loc = ui_hand_position(RIGHT_HANDS)) + add_screen_object(/atom/movable/screen/blob/factory_blob, HUD_BLOB_FACTORY, ui_loc = ui_hand_position(LEFT_HANDS)) + add_screen_object(/atom/movable/screen/blob/readapt_strain, HUD_BLOB_READAPT) + add_screen_object(/atom/movable/screen/blob/relocate_core, HUD_BLOB_RELOCATE) diff --git a/code/_onclick/hud/drones.dm b/code/_onclick/hud/drones.dm index ad3604a19e7..e7694d5d660 100644 --- a/code/_onclick/hud/drones.dm +++ b/code/_onclick/hud/drones.dm @@ -1,30 +1,5 @@ -/datum/hud/dextrous/drone/New(mob/owner) - ..() - var/atom/movable/screen/inventory/inv_box - - 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" -// inv_box.icon_full = "template" - inv_box.screen_loc = ui_drone_storage - inv_box.slot_id = ITEM_SLOT_DEX_STORAGE - static_inventory += inv_box - - inv_box = new /atom/movable/screen/inventory(null, src) - inv_box.name = "head/mask" - inv_box.icon = ui_style - inv_box.icon_state = "mask" -// inv_box.icon_full = "template" - inv_box.screen_loc = ui_drone_head - inv_box.slot_id = ITEM_SLOT_HEAD - static_inventory += inv_box - - for(var/atom/movable/screen/inventory/inv in (static_inventory + toggleable_inventory)) - if(inv.slot_id) - inv_slots[TOBITSHIFT(inv.slot_id) + 1] = inv - inv.update_appearance() - +/datum/hud/dextrous/drone + inventory_slots = /datum/inventory_slot/drone /datum/hud/dextrous/drone/persistent_inventory_update() if(!mymob) @@ -41,5 +16,19 @@ else drone.internal_storage?.screen_loc = null drone.head?.screen_loc = null - ..() + +/datum/inventory_slot/drone + abstract_type = /datum/inventory_slot/drone + +/datum/inventory_slot/drone/storage + name = "internal storage" + icon_state = "suit_storage" + slot_id = ITEM_SLOT_DEX_STORAGE + screen_loc = ui_drone_storage + +/datum/inventory_slot/drone/head + name = "head/mask" + icon_state = "mask" + slot_id = ITEM_SLOT_HEAD + screen_loc = ui_drone_head diff --git a/code/_onclick/hud/generic_dextrous.dm b/code/_onclick/hud/generic_dextrous.dm index b7f7f7af739..0799edc98ba 100644 --- a/code/_onclick/hud/generic_dextrous.dm +++ b/code/_onclick/hud/generic_dextrous.dm @@ -1,70 +1,36 @@ //Used for normal mobs that have hands. -/datum/hud/dextrous/New(mob/living/owner) - ..() +/datum/hud/dextrous/initialize_screen_objects() + . = ..() var/atom/movable/screen/using - - pull_icon = new /atom/movable/screen/pull(null, src) - pull_icon.icon = ui_style - pull_icon.update_appearance() - pull_icon.screen_loc = ui_drone_pull - static_inventory += pull_icon - - build_hand_slots() - - using = new /atom/movable/screen/drop(null, src) - using.icon = ui_style - using.screen_loc = ui_swaphand_position(owner, 1) - static_inventory += using - - using = new /atom/movable/screen/swap_hand(null, src) - using.icon = ui_style + add_screen_object(/atom/movable/screen/drop, HUD_MOB_DROP, HUD_GROUP_STATIC, ui_style, ui_swaphand_position(mymob, 1)) + using = add_screen_object(/atom/movable/screen/swap_hand, HUD_MOB_SWAPHAND_2, HUD_GROUP_STATIC, ui_style, ui_swaphand_position(mymob, 2)) using.icon_state = "act_swap" - using.screen_loc = ui_swaphand_position(owner, 2) - static_inventory += using - - action_intent = new /atom/movable/screen/combattoggle/flashy(null, src) - action_intent.icon = ui_style - action_intent.screen_loc = ui_movi - static_inventory += action_intent - - floor_change = new /atom/movable/screen/floor_changer(null, src) - floor_change.icon = 'icons/hud/screen_midnight.dmi' - static_inventory += floor_change - - if(HAS_TRAIT(owner, TRAIT_CAN_THROW_ITEMS)) - throw_icon = new /atom/movable/screen/throw_catch(null, src) - throw_icon.icon = ui_style - throw_icon.screen_loc = ui_drop_throw - static_inventory += throw_icon - - zone_select = new /atom/movable/screen/zone_sel(null, src) - zone_select.icon = ui_style - zone_select.update_appearance() - static_inventory += zone_select - - using = new /atom/movable/screen/area_creator(null, src) - using.icon = ui_style - static_inventory += using - - healthdoll = new /atom/movable/screen/healthdoll/living(null, src) - infodisplay += healthdoll mymob.canon_client?.clear_screen() - for(var/atom/movable/screen/inventory/inv in (static_inventory + toggleable_inventory)) - if(inv.slot_id) - inv_slots[TOBITSHIFT(inv.slot_id) + 1] = inv - inv.update_appearance() + build_hand_slots() + + add_screen_object(/atom/movable/screen/pull, HUD_MOB_PULL, HUD_GROUP_STATIC, ui_style, ui_below_throw) + add_screen_object(/atom/movable/screen/combattoggle/flashy, HUD_MOB_INTENTS, HUD_GROUP_STATIC, ui_style, ui_movi) + add_screen_object(/atom/movable/screen/floor_changer, HUD_MOB_FLOOR_CHANGER, HUD_GROUP_STATIC, ui_style, ui_above_movement) + add_screen_object(/atom/movable/screen/zone_sel, HUD_MOB_ZONE_SELECTOR, HUD_GROUP_STATIC, ui_style) + add_screen_object(/atom/movable/screen/area_creator, HUD_MOB_AREA_CREATOR, HUD_GROUP_STATIC, ui_style) + add_screen_object(/atom/movable/screen/memories, HUD_MOB_MEMORIES, HUD_GROUP_STATIC, ui_style) + add_screen_object(/atom/movable/screen/healthdoll/living, HUD_MOB_HEALTHDOLL, HUD_GROUP_INFO) + + if(HAS_TRAIT(mymob, TRAIT_CAN_THROW_ITEMS)) + add_screen_object(/atom/movable/screen/throw_catch, HUD_MOB_THROW, HUD_GROUP_HOTKEYS, ui_style, ui_drop_throw) /datum/hud/dextrous/persistent_inventory_update() if(!mymob) return - var/mob/living/D = mymob + var/mob/living/owner = mymob if(hud_version != HUD_STYLE_NOHUD) - for(var/obj/item/I in D.held_items) - I.screen_loc = ui_hand_position(D.get_held_index_of_item(I)) - D.client.screen += I - else - for(var/obj/item/I in D.held_items) - I.screen_loc = null - D.client.screen -= I + for(var/obj/item/held in owner.held_items) + held.screen_loc = ui_hand_position(owner.get_held_index_of_item(held)) + owner.client.screen += held + return + + for(var/obj/item/held in owner.held_items) + held.screen_loc = null + owner.client.screen -= held diff --git a/code/_onclick/hud/ghost.dm b/code/_onclick/hud/ghost.dm index 14b332d0c3c..b8f5e611e37 100644 --- a/code/_onclick/hud/ghost.dm +++ b/code/_onclick/hud/ghost.dm @@ -1,198 +1,22 @@ -/atom/movable/screen/ghost - icon = 'icons/hud/screen_ghost.dmi' - mouse_over_pointer = MOUSE_HAND_POINTER - -/atom/movable/screen/ghost/MouseEntered(location, control, params) - . = ..() - flick(icon_state + "_anim", src) - -/atom/movable/screen/ghost/spawners_menu - name = "Spawners menu" - icon_state = "spawners" - -/atom/movable/screen/ghost/spawners_menu/Click() - var/mob/dead/observer/observer = usr - observer.open_spawners_menu() - -/atom/movable/screen/ghost/orbit - name = "Orbit" - icon_state = "orbit" - -/atom/movable/screen/ghost/orbit/Click() - GLOB.orbit_menu.show(usr) - -/atom/movable/screen/ghost/reenter_corpse - name = "Reenter corpse" - icon_state = "reenter_corpse" - -/atom/movable/screen/ghost/reenter_corpse/Click() - var/mob/dead/observer/G = usr - G.reenter_corpse() - -/atom/movable/screen/ghost/dnr - name = "Do Not Resuscitate" - icon_state = "dnr" - -/atom/movable/screen/ghost/dnr/Click() - var/mob/dead/observer/dnring = usr - dnring.do_not_resuscitate() - -/atom/movable/screen/ghost/teleport - name = "Teleport" - icon_state = "teleport" - -/atom/movable/screen/ghost/teleport/Click() - var/mob/dead/observer/G = usr - G.dead_tele() - -/atom/movable/screen/ghost/settings - name = "Ghost Settings" - icon_state = "settings" - -/atom/movable/screen/ghost/settings/MouseEntered(location, control, params) - . = ..() - flick(icon_state + "_anim", src) - -/atom/movable/screen/ghost/settings/Click() - GLOB.ghost_menu.ui_interact(usr) - -/atom/movable/screen/ghost/minigames_menu - name ="Minigames" - icon_state = "minigames" - -/atom/movable/screen/ghost/minigames_menu/Click() - var/mob/dead/observer/observer = usr - observer.open_minigames_menu() - -/atom/movable/screen/ghost/hudbox - icon_state = "smallbox" - abstract_type = /atom/movable/screen/ghost/hudbox - /// Icon state used for the overlay representing this hudbox - var/hud_icon_state - /// The flag this hudbox toggles - var/relevant_flag - -/atom/movable/screen/ghost/hudbox/update_overlays() - . = ..() - . += hud_icon_state - -/atom/movable/screen/ghost/hudbox/update_icon_state() - . = ..() - var/mob/dead/observer/observer = hud?.mymob - if(!istype(observer)) - return - - icon_state = "smallbox[is_active(observer) ? "_active" : ""]" - -/atom/movable/screen/ghost/hudbox/proc/is_active(mob/dead/observer/observer) - return (observer.ghost_hud_flags & relevant_flag) - -/atom/movable/screen/ghost/hudbox/Click(location, control, params) - var/mob/dead/observer/observer = usr - switch(relevant_flag) - if(GHOST_DARKNESS_LEVEL) - observer.toggle_darkness() - if(GHOST_TRAY) - observer.tray_view() - else - observer.toggle_ghost_hud_flag(relevant_flag) - - update_appearance(UPDATE_ICON_STATE) - -/atom/movable/screen/ghost/hudbox/health_scanner - name = "Health Scanner" - desc = "Toggles your ability to health scan mobs on click." - hud_icon_state = "health_vision" - relevant_flag = GHOST_HEALTH - -/atom/movable/screen/ghost/hudbox/chem_scanner - name = "Chem Scanner" - desc = "Toggles your ability to chemical scan mobs on click." - hud_icon_state = "chem_vision" - relevant_flag = GHOST_CHEM - -/atom/movable/screen/ghost/hudbox/gas_scanner - name = "Gas Scanner" - desc = "Toggles your ability to gas scan objects on click." - hud_icon_state = "atmos_vision" - relevant_flag = GHOST_GAS - -/atom/movable/screen/ghost/hudbox/ghost - name = "Ghost Vision" - desc = "Toggles whether you can see other ghosts." - hud_icon_state = "ghost_vision" - relevant_flag = GHOST_VISION - -/atom/movable/screen/ghost/hudbox/data_huds - name = "Data HUDs" - desc = "Toggles the display of data HUDs (health, security, diagnostics, etc)." - hud_icon_state = "data_vision" - relevant_flag = GHOST_DATA_HUDS - -/atom/movable/screen/ghost/hudbox/tray_icon - name = "Tray View" - desc = "Shows the t-ray view of the area around your ghost." - hud_icon_state = "tray_vision" - relevant_flag = GHOST_TRAY - -/atom/movable/screen/ghost/hudbox/darkness_level - name = "Darkness Level" - desc = "Cycles through different darkness levels for ghost vision." - hud_icon_state = "darkness_vision" - relevant_flag = GHOST_DARKNESS_LEVEL /datum/hud/ghost ui_style = 'icons/hud/screen_ghost.dmi' -/datum/hud/ghost/New(mob/owner) - ..() - var/atom/movable/screen/using - - using = new /atom/movable/screen/ghost/spawners_menu(null, src) - using.screen_loc = ui_ghost_spawners_menu - static_inventory += using - - using = new /atom/movable/screen/ghost/orbit(null, src) - using.screen_loc = ui_ghost_orbit - static_inventory += using - - using = new /atom/movable/screen/ghost/reenter_corpse(null, src) - using.screen_loc = ui_ghost_reenter_corpse - static_inventory += using - - using = new /atom/movable/screen/ghost/dnr(null, src) - using.screen_loc = ui_dnr - static_inventory += using - - using = new /atom/movable/screen/ghost/teleport(null, src) - using.screen_loc = ui_ghost_teleport - static_inventory += using - - using = new /atom/movable/screen/ghost/settings(null, src) - using.screen_loc = ui_ghost_settings - static_inventory += using - - using = new /atom/movable/screen/ghost/minigames_menu(null, src) - using.screen_loc = ui_ghost_minigames - static_inventory += using - - using = new /atom/movable/screen/language_menu(null, src) - using.icon = ui_style - using.screen_loc = ui_ghost_language_menu - static_inventory += using - - floor_change = new /atom/movable/screen/floor_changer/vertical(null, src) - floor_change.icon = ui_style - floor_change.screen_loc = ui_ghost_floor_changer - static_inventory += floor_change +/datum/hud/ghost/initialize_screen_objects() + . = ..() + add_screen_object(/atom/movable/screen/ghost/spawners_menu, HUD_GHOST_SPAWNERS) + add_screen_object(/atom/movable/screen/ghost/orbit, HUD_GHOST_ORBIT) + add_screen_object(/atom/movable/screen/ghost/reenter_corpse, HUD_GHOST_REENTER_CORPSE) + add_screen_object(/atom/movable/screen/ghost/dnr, HUD_GHOST_DNR) + add_screen_object(/atom/movable/screen/ghost/teleport, HUD_GHOST_TELEPORT) + add_screen_object(/atom/movable/screen/ghost/settings, HUD_GHOST_SETTINGS) + add_screen_object(/atom/movable/screen/ghost/minigames_menu, HUD_GHOST_MINIGAMES) + add_screen_object(/atom/movable/screen/language_menu, HUD_MOB_LANGUAGE_MENU, HUD_GROUP_STATIC, ui_style, ui_ghost_language_menu) + add_screen_object(/atom/movable/screen/floor_changer/vertical, HUD_MOB_FLOOR_CHANGER, HUD_GROUP_STATIC, ui_style, ui_ghost_floor_changer) var/list/hudboxes = valid_subtypesof(/atom/movable/screen/ghost/hudbox) for(var/i in 1 to length(hudboxes)) - var/hudbox_type = hudboxes[i] - var/atom/movable/screen/ghost/hudbox/hudbox = new hudbox_type(null, src) - hudbox.screen_loc = position_hudbox(i - 1) - static_inventory += hudbox - hudbox.update_appearance() + add_screen_object(hudboxes[i], HUD_KEY_GHOST_HUDBOX(i), ui_loc = position_hudbox(i - 1)) /datum/hud/ghost/proc/position_hudbox(i) var/row = floor(i / 3) @@ -211,15 +35,15 @@ return var/mob/screenmob = viewmob || mymob if(screenmob.client.prefs.read_preference(/datum/preference/toggle/ghost_hud)) - screenmob.client.screen |= static_inventory - for(var/atom/movable/screen/ghost/hudbox/hud in static_inventory) + screenmob.client.screen |= screen_groups[HUD_GROUP_STATIC] + for(var/atom/movable/screen/ghost/hudbox/hud in screen_groups[HUD_GROUP_STATIC]) hud.update_appearance() else - screenmob.client.screen -= static_inventory + screenmob.client.screen -= screen_groups[HUD_GROUP_STATIC] //We should only see observed mob alerts. /datum/hud/ghost/reorganize_alerts(mob/viewmob) var/mob/dead/observer/O = mymob if (istype(O) && O.observetarget) return - . = ..() + return ..() diff --git a/code/_onclick/hud/guardian.dm b/code/_onclick/hud/guardian.dm index 68a480d47f8..cabe261b14e 100644 --- a/code/_onclick/hud/guardian.dm +++ b/code/_onclick/hud/guardian.dm @@ -1,169 +1,54 @@ /datum/hud/guardian ui_style = 'icons/hud/guardian.dmi' + inventory_slots = list(/datum/inventory_slot/guardian_storage) -/datum/hud/guardian/New(mob/living/basic/guardian/owner) - ..() - var/atom/movable/screen/using +/datum/hud/guardian/initialize_screen_objects() + . = ..() + add_screen_object(/atom/movable/screen/pull, HUD_MOB_PULL, HUD_GROUP_STATIC, ui_style) + add_screen_object(/atom/movable/screen/guardian/manifest, HUD_GUARDIAN_MANIFEST, ui_loc = ui_hand_position(RIGHT_HANDS)) + add_screen_object(/atom/movable/screen/guardian/recall, HUD_GUARDIAN_RECALL, ui_loc = ui_hand_position(LEFT_HANDS)) + add_screen_object(/atom/movable/screen/guardian/toggle_light, HUD_GUARDIAN_LIGHT) + add_screen_object(/atom/movable/screen/guardian/communicate, HUD_GUARDIAN_COMMUNICATE) - pull_icon = new /atom/movable/screen/pull(null, src) - pull_icon.icon = ui_style - pull_icon.update_appearance() - pull_icon.screen_loc = ui_living_pull - static_inventory += pull_icon + add_screen_object(/atom/movable/screen/healths/guardian, HUD_MOB_HEALTH, HUD_GROUP_INFO) - healths = new /atom/movable/screen/healths/guardian(null, src) - infodisplay += healths + var/mob/living/basic/guardian/owner = mymob + if (istype(owner)) + add_screen_object(owner.toggle_button_type, HUD_GUARDIAN_TOGGLE, ui_loc = ui_storage1) - using = new /atom/movable/screen/guardian/manifest(null, src) - using.screen_loc = ui_hand_position(RIGHT_HANDS) - static_inventory += using +/datum/hud/dextrous/guardian/initialize_screen_objects() + . = ..() + add_screen_object(/atom/movable/screen/pull, HUD_MOB_PULL, HUD_GROUP_STATIC, ui_style) + add_screen_object(/atom/movable/screen/guardian/communicate, HUD_GUARDIAN_COMMUNICATE, ui_loc = ui_sstore1) + add_screen_object(/atom/movable/screen/guardian/manifest, HUD_GUARDIAN_MANIFEST, ui_loc = ui_belt) + add_screen_object(/atom/movable/screen/guardian/recall, HUD_GUARDIAN_RECALL, ui_loc = ui_back) + add_screen_object(/atom/movable/screen/guardian/toggle_light, HUD_GUARDIAN_LIGHT) - using = new /atom/movable/screen/guardian/recall(null, src) - using.screen_loc = ui_hand_position(LEFT_HANDS) - static_inventory += using + add_screen_object(/atom/movable/screen/healths/guardian, HUD_MOB_HEALTH, HUD_GROUP_INFO) - using = new owner.toggle_button_type(null, src) - using.screen_loc = ui_storage1 - static_inventory += using - - using = new /atom/movable/screen/guardian/toggle_light(null, src) - using.screen_loc = ui_inventory - static_inventory += using - - using = new /atom/movable/screen/guardian/communicate(null, src) - using.screen_loc = ui_back - static_inventory += using - -/datum/hud/dextrous/guardian/New(mob/living/basic/guardian/owner) //for a dextrous guardian - ..() - var/atom/movable/screen/using - if(istype(owner, /mob/living/basic/guardian/dextrous)) - var/atom/movable/screen/inventory/inv_box - - 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" - inv_box.screen_loc = ui_id - inv_box.slot_id = ITEM_SLOT_DEX_STORAGE - static_inventory += inv_box - - 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(null, src) - using.screen_loc = ui_id - static_inventory += using - - pull_icon = new /atom/movable/screen/pull(null, src) - pull_icon.icon = ui_style - pull_icon.update_appearance() - pull_icon.screen_loc = ui_living_pull - static_inventory += pull_icon - - healths = new /atom/movable/screen/healths/guardian(null, src) - infodisplay += healths - - using = new /atom/movable/screen/guardian/manifest(null, src) - using.screen_loc = ui_belt - static_inventory += using - - using = new /atom/movable/screen/guardian/recall(null, src) - using.screen_loc = ui_back - static_inventory += using - - using = new owner.toggle_button_type(null, src) - using.screen_loc = ui_storage2 - static_inventory += using - - using = new /atom/movable/screen/guardian/toggle_light(null, src) - using.screen_loc = ui_inventory - static_inventory += using + var/mob/living/basic/guardian/owner = mymob + if (istype(owner)) + add_screen_object(owner.toggle_button_type, HUD_GUARDIAN_TOGGLE, ui_loc = ui_storage2) /datum/hud/dextrous/guardian/persistent_inventory_update() if(!mymob) return - if(istype(mymob, /mob/living/basic/guardian/dextrous)) - var/mob/living/basic/guardian/dextrous/dex_guardian = mymob - if(hud_shown) - if(dex_guardian.internal_storage) - dex_guardian.internal_storage.screen_loc = ui_id - dex_guardian.client.screen += dex_guardian.internal_storage - else - if(dex_guardian.internal_storage) - dex_guardian.internal_storage.screen_loc = null + if(!istype(mymob, /mob/living/basic/guardian/dextrous)) + return ..() - ..() + var/mob/living/basic/guardian/dextrous/dex_guardian = mymob + if(hud_shown) + if(dex_guardian.internal_storage) + dex_guardian.internal_storage.screen_loc = ui_id + dex_guardian.client.screen += dex_guardian.internal_storage + else + if(dex_guardian.internal_storage) + dex_guardian.internal_storage.screen_loc = null + return ..() -/atom/movable/screen/guardian - icon = 'icons/hud/guardian.dmi' - mouse_over_pointer = MOUSE_HAND_POINTER - -/atom/movable/screen/guardian/manifest - icon_state = "manifest" - name = "Manifest" - desc = "Spring forth into battle!" - -/atom/movable/screen/guardian/manifest/Click() - if(isguardian(usr)) - var/mob/living/basic/guardian/user = usr - user.manifest() - - -/atom/movable/screen/guardian/recall - icon_state = "recall" - name = "Recall" - desc = "Return to your user." - -/atom/movable/screen/guardian/recall/Click() - if(isguardian(usr)) - var/mob/living/basic/guardian/user = usr - user.recall() - -/atom/movable/screen/guardian/toggle_mode - icon_state = "toggle" - name = "Toggle Mode" - desc = "Switch between ability modes." - -/atom/movable/screen/guardian/toggle_mode/Click() - if(isguardian(usr)) - var/mob/living/basic/guardian/user = usr - user.toggle_modes() - -/atom/movable/screen/guardian/toggle_mode/inactive - icon_state = "notoggle" //greyed out so it doesn't look like it'll work - -/atom/movable/screen/guardian/toggle_mode/assassin - icon_state = "stealth" - name = "Toggle Stealth" - desc = "Enter or exit stealth." - -/atom/movable/screen/guardian/toggle_mode/gases - icon_state = "gases" - name = "Toggle Gas" - desc = "Switch between possible gases." - -/atom/movable/screen/guardian/communicate - icon_state = "communicate" - name = "Communicate" - desc = "Communicate telepathically with your user." - -/atom/movable/screen/guardian/communicate/Click() - if(isguardian(usr)) - var/mob/living/basic/guardian/user = usr - user.communicate() - - -/atom/movable/screen/guardian/toggle_light - icon_state = "light" - name = "Toggle Light" - desc = "Glow like star dust." - -/atom/movable/screen/guardian/toggle_light/Click() - if(isguardian(usr)) - var/mob/living/basic/guardian/user = usr - user.toggle_light() +/datum/inventory_slot/guardian_storage + name = "internal storage" + icon_state = "suit_storage" + slot_id = ITEM_SLOT_DEX_STORAGE + screen_loc = ui_id diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm index 0f722a1bc11..88eb2d5a6f1 100644 --- a/code/_onclick/hud/hud.dm +++ b/code/_onclick/hud/hud.dm @@ -22,34 +22,15 @@ GLOBAL_LIST_INIT(available_ui_styles, list( /datum/hud var/mob/mymob + /// Used for the HUD toggle (F12) + var/hud_shown = TRUE + /// Current displayed version of the HUD + var/hud_version = HUD_STYLE_STANDARD + /// Equipped item inventory + var/inventory_shown = FALSE + /// This is to hide the buttons that can be used via hotkeys. (hotkeybuttons list of buttons) + var/hotkey_ui_hidden = FALSE - var/hud_shown = TRUE //Used for the HUD toggle (F12) - var/hud_version = HUD_STYLE_STANDARD //Current displayed version of the HUD - var/inventory_shown = FALSE //Equipped item inventory - var/hotkey_ui_hidden = FALSE //This is to hide the buttons that can be used via hotkeys. (hotkeybuttons list of buttons) - - var/atom/movable/screen/alien_plasma_display - var/atom/movable/screen/alien_queen_finder - - var/atom/movable/screen/action_intent - var/atom/movable/screen/zone_select - var/atom/movable/screen/pull_icon - var/atom/movable/screen/rest_icon - var/atom/movable/screen/sleep_icon - var/atom/movable/screen/throw_icon - var/atom/movable/screen/resist_icon - var/atom/movable/screen/floor_change - - var/list/static_inventory = list() //the screen objects which are static - var/list/toggleable_inventory = list() //the screen objects which can be hidden - var/list/atom/movable/screen/hotkeybuttons = list() //the buttons that can be used via hotkeys - var/list/infodisplay = list() //the screen objects that display mob info (health, alien plasma, etc...) - /// Screen objects that never exit view. - var/list/always_visible_inventory = list() - var/list/inv_slots[SLOTS_AMT] // /atom/movable/screen/inventory objects, ordered by their slot ID. - var/list/hand_slots // /atom/movable/screen/inventory/hand objects, assoc list of "[held_index]" = object - /// storages (and its content) currently open by mob - var/list/open_containers = list() /// Assoc list of key => "plane master groups" /// This is normally just the main window, but it'll occasionally contain things like spyglasses windows var/list/datum/plane_master_group/master_groups = list() @@ -62,8 +43,9 @@ GLOBAL_LIST_INIT(available_ui_styles, list( /// Goes from 0 to the max (z level stack size - 1) var/current_plane_offset = 0 - ///UI for screentips that appear when you mouse over things - var/atom/movable/screen/screentip/screentip_text + /// UI for screentips that appear when you mouse over things + /// Stored directly as it is used in very hot MouseEntered code + var/atom/movable/screen/screentip/screentip_text = null /// Whether or not screentips are enabled. /// This is updated by the preference for cheaper reads than would be @@ -78,26 +60,27 @@ GLOBAL_LIST_INIT(available_ui_styles, list( /// The color to use for the screentips. /// This is updated by the preference for cheaper reads than would be - /// had with a proc call, especially on one of the hottest procs in the - /// game (MouseEntered). - var/screentip_color - - var/atom/movable/screen/button_palette/toggle_palette - var/atom/movable/screen/palette_scroll/down/palette_down - var/atom/movable/screen/palette_scroll/up/palette_up - - var/datum/action_group/palette/palette_actions - var/datum/action_group/listed/listed_actions - var/list/floating_actions - - var/atom/movable/screen/healths - var/atom/movable/screen/stamina - var/atom/movable/screen/healthdoll/healthdoll - var/atom/movable/screen/spacesuit/spacesuit_hud - var/atom/movable/screen/hunger/hunger + /// had with a proc call, especially on one of the hottest procs in the game (MouseEntered). + var/screentip_color = null + var/datum/action_group/palette/palette_actions = null + var/datum/action_group/listed/listed_actions = null + var/list/floating_actions = null /// Subtypes can override this to force a specific UI style - var/ui_style + var/ui_style = null + /// Assoc list of all screen objects we hold by their key + var/list/atom/movable/screen/screen_objects = list() + /// List of screen objects by their screen group + var/list/screen_groups[SCREEN_GROUP_AMT] + /// List of all inventory slot screen objects by their slot ID. Some slots are fake and will be missing from here! + var/list/inv_slots[SLOTS_AMT] + /// List of hand slot objects, kept separate from the rest of inventory as mobs can have varying amount of hands + var/list/atom/movable/screen/inventory/hand/hand_slots = null + + /// List of typepaths of /datum/inventory_slot which will be used to automatically create inventory slot UI elements + /// If assigned a typepath instead of a list, it will instead use all valid subtypes of said typepath + /// Safe to change in initialize_screen_objects() but not later + var/list/inventory_slots = null /// List of weakrefs to objects that we add to our screen that we don't expect to DO anything /// They typically use * in their render target. They exist solely so we can reuse them, @@ -111,12 +94,9 @@ GLOBAL_LIST_INIT(available_ui_styles, list( // will fall back to the default if any of these are null ui_style = ui_style2icon(owner.client?.prefs?.read_preference(/datum/preference/choiced/ui_style)) - toggle_palette = new() - toggle_palette.set_hud(src) - palette_down = new() - palette_down.set_hud(src) - palette_up = new() - palette_up.set_hud(src) + add_screen_object(/atom/movable/screen/button_palette, HUD_MOB_TOGGLE_PALETTE) + add_screen_object(/atom/movable/screen/palette_scroll/down, HUD_MOB_PALETTE_DOWN) + add_screen_object(/atom/movable/screen/palette_scroll/up, HUD_MOB_PALETTE_UP) hand_slots = list() @@ -127,8 +107,7 @@ GLOBAL_LIST_INIT(available_ui_styles, list( screentip_color = preferences?.read_preference(/datum/preference/color/screentip_color) screentips_enabled = preferences?.read_preference(/datum/preference/choiced/enable_screentips) screentip_images = preferences?.read_preference(/datum/preference/toggle/screentip_images) - screentip_text = new(null, src) - static_inventory += screentip_text + screentip_text = add_screen_object(/atom/movable/screen/screentip, HUD_MOB_SCREENTIP) for(var/mytype in subtypesof(/atom/movable/plane_master_controller)) var/atom/movable/plane_master_controller/controller_instance = new mytype(null,src) @@ -146,8 +125,73 @@ GLOBAL_LIST_INIT(available_ui_styles, list( RegisterSignal(mymob, COMSIG_MOB_LOGOUT, PROC_REF(clear_client)) RegisterSignal(mymob, COMSIG_MOB_SIGHT_CHANGE, PROC_REF(update_sightflags)) RegisterSignal(mymob, COMSIG_VIEWDATA_UPDATE, PROC_REF(on_viewdata_update)) + + initialize_screen_objects() + create_inventory_slots() + update_locked_slots() + update_sightflags(mymob, mymob.sight, NONE) +/datum/hud/Destroy() + if(mymob.hud_used == src) + mymob.hud_used = null + + QDEL_NULL(palette_actions) + QDEL_NULL(listed_actions) + QDEL_LIST(floating_actions) + screentip_text = null + screen_groups = null + inv_slots.Cut() + hand_slots.Cut() + QDEL_LIST_ASSOC_VAL(screen_objects) + QDEL_LIST_ASSOC_VAL(master_groups) + QDEL_LIST_ASSOC_VAL(plane_master_controllers) + mymob = null + + return ..() + +/// Creates and registers a managed screen object +/datum/hud/proc/add_screen_object(atom/movable/screen/new_object, hud_key, group_key = HUD_GROUP_STATIC, ui_icon, ui_loc, update_screen = FALSE) + if (ispath(new_object)) + new_object = new new_object(null, src) + + if (isnull(hud_key)) + hud_key = REF(new_object) + + if (!isnull(ui_icon)) + new_object.icon = ui_icon + + if (!isnull(ui_loc)) + new_object.screen_loc = ui_loc + + new_object.hud_key = hud_key + if (screen_objects[hud_key]) + CRASH("Attempted to add a new [new_object] screen object to the [src] hud while an object with the same key [hud_key] is already present!") + + screen_objects[hud_key] = new_object + + if (group_key) + LAZYADD(screen_groups[group_key], new_object) + new_object.hud_group_key = group_key + + if (update_screen) + show_hud(hud_version) + return new_object + +/// Removes a screen object and refreshes the hud. Can just be passed a key. +/datum/hud/proc/remove_screen_object(atom/movable/screen/to_remove, update = TRUE) + if (!istype(to_remove)) + to_remove = screen_objects[to_remove] + if (!to_remove) + return + qdel(to_remove) + if (update && !QDELETED(src)) + show_hud(hud_version) + +/// Proc for children to spawn their screen object in +/datum/hud/proc/initialize_screen_objects() + return + /datum/hud/proc/client_refresh(datum/source) SIGNAL_HANDLER var/client/client = mymob.canon_client @@ -212,53 +256,6 @@ GLOBAL_LIST_INIT(available_ui_styles, list( var/datum/plane_master_group/group = master_groups[group_key] group.build_planes_offset(src, new_offset) -/datum/hud/Destroy() - if(mymob.hud_used == src) - mymob.hud_used = null - - QDEL_NULL(toggle_palette) - QDEL_NULL(palette_down) - QDEL_NULL(palette_up) - QDEL_NULL(palette_actions) - QDEL_NULL(listed_actions) - QDEL_LIST(floating_actions) - - QDEL_LIST(static_inventory) - - // all already deleted by static inventory clear - inv_slots.Cut() - action_intent = null - zone_select = null - pull_icon = null - rest_icon = null - sleep_icon = null - floor_change = null - hand_slots.Cut() - - QDEL_LIST(toggleable_inventory) - QDEL_LIST(hotkeybuttons) - throw_icon = null - resist_icon = null - QDEL_LIST(infodisplay) - open_containers = null - - healths = null - stamina = null - healthdoll = null - spacesuit_hud = null - hunger = null - alien_plasma_display = null - alien_queen_finder = null - - QDEL_LIST_ASSOC_VAL(master_groups) - QDEL_LIST_ASSOC_VAL(plane_master_controllers) - QDEL_LIST(always_visible_inventory) - mymob = null - - QDEL_NULL(screentip_text) - - return ..() - /datum/hud/proc/on_plane_increase(datum/source, old_max_offset, new_max_offset) SIGNAL_HANDLER for(var/i in old_max_offset + 1 to new_max_offset) @@ -314,75 +311,73 @@ GLOBAL_LIST_INIT(available_ui_styles, list( * * viewmob - what mob to show the hud to. Can be this hud's mob, can be another mob, can be null (will use this hud's mob if so) */ /datum/hud/proc/show_hud(version = 0, mob/viewmob) - if(!ismob(mymob)) + if (!ismob(mymob)) return FALSE + var/mob/screenmob = viewmob || mymob - if(!screenmob.client) + if (!screenmob.client) return FALSE // This code is the absolute fucking worst, I want it to go die in a fire // Seriously, why + // I'm sorry screenmob.client.clear_screen() screenmob.client.apply_clickcatcher() var/display_hud_version = version - if(!display_hud_version) //If 0 or blank, display the next hud version + if (!display_hud_version) // If 0 or blank, display the next hud version display_hud_version = hud_version + 1 - if(display_hud_version > HUD_VERSIONS) //If the requested version number is greater than the available versions, reset back to the first version - display_hud_version = 1 - switch(display_hud_version) - if(HUD_STYLE_STANDARD) //Default HUD - hud_shown = TRUE //Governs behavior of other procs - if(static_inventory.len) - screenmob.client.screen += static_inventory - if(toggleable_inventory.len && screenmob.hud_used && screenmob.hud_used.inventory_shown) - screenmob.client.screen += toggleable_inventory - if(hotkeybuttons.len && !hotkey_ui_hidden) - screenmob.client.screen += hotkeybuttons - if(infodisplay.len) - screenmob.client.screen += infodisplay - if(always_visible_inventory.len) - screenmob.client.screen += always_visible_inventory - if(open_containers.len && screenmob == mymob) // Don't show open inventories to ghosts - list_clear_nulls(open_containers) - screenmob.client.screen += open_containers - screenmob.client.screen += toggle_palette + // If the requested version number is greater than the available versions, reset back to the first version + if (display_hud_version > HUD_VERSIONS) + display_hud_version = HUD_STYLE_STANDARD - if(HUD_STYLE_REDUCED) //Reduced HUD - hud_shown = FALSE //Governs behavior of other procs - if(static_inventory.len) - screenmob.client.screen -= static_inventory - if(toggleable_inventory.len) - screenmob.client.screen -= toggleable_inventory - if(hotkeybuttons.len) - screenmob.client.screen -= hotkeybuttons - if(infodisplay.len) - screenmob.client.screen += infodisplay - if(always_visible_inventory.len) - screenmob.client.screen += always_visible_inventory + var/list/group_static = screen_groups[HUD_GROUP_STATIC] + var/list/group_toggleable = screen_groups[HUD_GROUP_TOGGLEABLE_INVENTORY] + var/list/group_hotkeys = screen_groups[HUD_GROUP_HOTKEYS] + var/list/group_info = screen_groups[HUD_GROUP_INFO] + var/list/group_screen = screen_groups[HUD_GROUP_SCREEN_OVERLAYS] + var/list/group_storage = screen_groups[HUD_GROUP_STORAGE] + + // Screen overlays get added regardless of the HUD state + if (length(group_screen)) + screenmob.client.screen += group_screen + + var/atom/movable/screen/button_palette/palette = screen_objects[HUD_MOB_TOGGLE_PALETTE] + var/atom/movable/screen/action_intent = screen_objects[HUD_MOB_INTENTS] + + switch (display_hud_version) + if (HUD_STYLE_STANDARD) + hud_shown = TRUE + + if (length(group_static)) + screenmob.client.screen += group_static + if (length(group_toggleable) && screenmob.hud_used && screenmob.hud_used.inventory_shown) + screenmob.client.screen += group_toggleable + if (length(group_hotkeys) && !hotkey_ui_hidden) + screenmob.client.screen += group_hotkeys + if (length(group_info)) + screenmob.client.screen += group_info + if (length(group_storage)) + screenmob.client.screen += group_storage + + screenmob.client.screen += palette + + if (HUD_STYLE_REDUCED) + hud_shown = FALSE + + if (length(group_info)) + screenmob.client.screen += group_info + + // Hands are apart of the static group but still should be presetn in the reduced mode + for (var/atom/movable/screen/hand in hand_slots) + screenmob.client.screen += hand - //These ones are a part of 'static_inventory', 'toggleable_inventory' or 'hotkeybuttons' but we want them to stay - for(var/h in hand_slots) - var/atom/movable/screen/hand = hand_slots[h] - if(hand) - screenmob.client.screen += hand if(action_intent) - screenmob.client.screen += action_intent //we want the intent switcher visible - action_intent.screen_loc = ui_acti_alt //move this to the alternative position, where zone_select usually is. + screenmob.client.screen += action_intent - if(HUD_STYLE_NOHUD) //No HUD - hud_shown = FALSE //Governs behavior of other procs - if(static_inventory.len) - screenmob.client.screen -= static_inventory - if(toggleable_inventory.len) - screenmob.client.screen -= toggleable_inventory - if(hotkeybuttons.len) - screenmob.client.screen -= hotkeybuttons - if(infodisplay.len) - screenmob.client.screen -= infodisplay - if(always_visible_inventory.len) - screenmob.client.screen += always_visible_inventory + if (HUD_STYLE_NOHUD) + hud_shown = FALSE hud_version = display_hud_version persistent_inventory_update(screenmob) @@ -442,12 +437,13 @@ GLOBAL_LIST_INIT(available_ui_styles, list( if (initial(ui_style) || ui_style == new_ui_style) return - for(var/atom/item in static_inventory + toggleable_inventory + hotkeybuttons + infodisplay + always_visible_inventory + inv_slots) - if (item.icon == ui_style) + for(var/hud_key in screen_objects) + var/atom/item = screen_objects[hud_key] + if (item?.icon == ui_style) item.icon = new_ui_style ui_style = new_ui_style - build_hand_slots() + build_hand_slots(update_hud = TRUE) /datum/hud/proc/register_reuse(atom/movable/screen/reuse) asset_refs_for_reuse += WEAKREF(reuse) @@ -476,62 +472,80 @@ GLOBAL_LIST_INIT(available_ui_styles, list( else to_chat(usr, span_warning("This mob type does not use a HUD.")) +/// Rebuilds our mob's hand slot screen elements +/datum/hud/proc/build_hand_slots(update_hud = FALSE) + QDEL_LIST(hand_slots) + hand_slots = new /list(length(mymob.held_items)) -//(re)builds the hand ui slots, throwing away old ones -//not really worth jugglying existing ones so we just scrap+rebuild -//9/10 this is only called once per mob and only for 2 hands -/datum/hud/proc/build_hand_slots() - for(var/h in hand_slots) - var/atom/movable/screen/inventory/hand/H = hand_slots[h] - if(H) - static_inventory -= H - 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(null, src) + for(var/i in 1 to length(mymob.held_items)) + var/atom/movable/screen/inventory/hand/hand_box = add_screen_object(/atom/movable/screen/inventory/hand, HUD_KEY_HAND_SLOT(i), HUD_GROUP_STATIC, ui_style, ui_hand_position(i)) 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 - static_inventory += hand_box hand_box.update_appearance() + hand_slots[i] = hand_box var/num_of_swaps = 0 - for(var/atom/movable/screen/swap_hand/swap_hands in static_inventory) + for(var/atom/movable/screen/swap_hand/swap_hands in screen_groups[HUD_GROUP_STATIC]) num_of_swaps += 1 var/hand_num = 1 - for(var/atom/movable/screen/swap_hand/swap_hands in static_inventory) + for(var/atom/movable/screen/swap_hand/swap_hands in screen_groups[HUD_GROUP_STATIC]) var/hand_ind = RIGHT_HANDS if (num_of_swaps > 1) hand_ind = IS_RIGHT_INDEX(hand_num) ? LEFT_HANDS : RIGHT_HANDS swap_hands.screen_loc = ui_swaphand_position(mymob, hand_ind) hand_num += 1 + hand_num = 1 - for(var/atom/movable/screen/drop/swap_hands in static_inventory) + + for(var/atom/movable/screen/drop/swap_hands in screen_groups[HUD_GROUP_STATIC]) var/hand_ind = LEFT_HANDS if (num_of_swaps > 1) hand_ind = IS_LEFT_INDEX(hand_num) ? LEFT_HANDS : RIGHT_HANDS swap_hands.screen_loc = ui_swaphand_position(mymob, hand_ind) hand_num += 1 - if(ismob(mymob) && mymob.hud_used == src) + if(update_hud && mymob?.hud_used == src) show_hud(hud_version) /// Handles dimming inventory slots that a mob can't equip items to in their current state /datum/hud/proc/update_locked_slots() return +/// Creates inventory slot screen elements based on our assigned inventory_slots +/datum/hud/proc/create_inventory_slots() + var/list/created_paths = inventory_slots + if (ispath(inventory_slots)) + created_paths = valid_subtypesof(inventory_slots) + + for (var/datum/inventory_slot/slot_type as anything in created_paths) + var/datum/inventory_slot/inv_slot = GLOB.inventory_slot_datums[slot_type] + if (!inv_slot) + stack_trace("[src] attempted to use an invalid inventory slot: [slot_type]") + continue + inv_slot.create_element(src) + + update_inventory_slots() + +/// Updates all of our inventory slots +/// Avoid calling directly in favor of specific update procs +/datum/hud/proc/update_inventory_slots() + for(var/atom/movable/screen/inventory/inv in screen_groups[HUD_GROUP_STATIC] + screen_groups[HUD_GROUP_TOGGLEABLE_INVENTORY]) + if(inv.slot_id) + inv_slots[TOBITSHIFT(inv.slot_id) + 1] = inv + inv.update_appearance() + /datum/hud/proc/position_action(atom/movable/screen/movable/action_button/button, position) // This is kinda a hack, I'm sorry. // Basically, FLOATING is never a valid position to pass into this proc. It exists as a generic marker for manually positioned buttons // Not as a position to target if(position == SCRN_OBJ_FLOATING) return + if(button.location != SCRN_OBJ_DEFAULT) hide_action(button) + switch(position) if(SCRN_OBJ_DEFAULT) // Reset to the default button.dump_save() // Nuke any existing saves @@ -548,6 +562,7 @@ GLOBAL_LIST_INIT(available_ui_styles, list( floating_actions += button button.screen_loc = position position = SCRN_OBJ_FLOATING + var/atom/movable/screen/button_palette/toggle_palette = screen_objects[HUD_MOB_TOGGLE_PALETTE] toggle_palette.update_state() button.location = position @@ -555,18 +570,24 @@ GLOBAL_LIST_INIT(available_ui_styles, list( /datum/hud/proc/position_action_relative(atom/movable/screen/movable/action_button/button, atom/movable/screen/movable/action_button/relative_to) if(button.location != SCRN_OBJ_DEFAULT) hide_action(button) + switch(relative_to.location) if(SCRN_OBJ_IN_LIST) listed_actions.insert_action(button, listed_actions.index_of(relative_to)) + if(SCRN_OBJ_IN_PALETTE) palette_actions.insert_action(button, palette_actions.index_of(relative_to)) + if(SCRN_OBJ_FLOATING) // If we don't have it as a define, this is a screen_loc, and we should be floating floating_actions += button var/client/our_client = mymob.canon_client if(!our_client) position_action(button, button.linked_action.default_button_position) return - button.screen_loc = get_valid_screen_location(relative_to.screen_loc, ICON_SIZE_ALL, our_client.view_size.getView()) // Asks for a location adjacent to our button that won't overflow the map + + // Asks for a location adjacent to our button that won't overflow the map + button.screen_loc = get_valid_screen_location(relative_to.screen_loc, ICON_SIZE_ALL, our_client.view_size.getView()) + var/atom/movable/screen/button_palette/toggle_palette = screen_objects[HUD_MOB_TOGGLE_PALETTE] toggle_palette.update_state() button.location = relative_to.location @@ -576,32 +597,44 @@ GLOBAL_LIST_INIT(available_ui_styles, list( switch(button.location) if(SCRN_OBJ_DEFAULT) // Invalid CRASH("We just tried to hide an action buttion that somehow has the default position as its location, you done fucked up") + if(SCRN_OBJ_FLOATING) floating_actions -= button + var/atom/movable/screen/button_palette/toggle_palette = screen_objects[HUD_MOB_TOGGLE_PALETTE] toggle_palette.update_state() + if(SCRN_OBJ_IN_LIST) listed_actions.remove_action(button) + if(SCRN_OBJ_IN_PALETTE) palette_actions.remove_action(button) + button.screen_loc = null /// Generates visual landings for all groups that the button is not a memeber of /datum/hud/proc/generate_landings(atom/movable/screen/movable/action_button/button) listed_actions.generate_landing() palette_actions.generate_landing() + var/atom/movable/screen/button_palette/toggle_palette = screen_objects[HUD_MOB_TOGGLE_PALETTE] toggle_palette.activate_landing() /// Clears all currently visible landings /datum/hud/proc/hide_landings() listed_actions.clear_landing() palette_actions.clear_landing() + var/atom/movable/screen/button_palette/toggle_palette = screen_objects[HUD_MOB_TOGGLE_PALETTE] toggle_palette.disable_landing() // Updates any existing "owned" visuals, ensures they continue to be visible /datum/hud/proc/update_our_owner() + var/atom/movable/screen/button_palette/toggle_palette = screen_objects[HUD_MOB_TOGGLE_PALETTE] + var/atom/movable/screen/palette_scroll/palette_down = screen_objects[HUD_MOB_PALETTE_DOWN] + var/atom/movable/screen/palette_scroll/palette_up = screen_objects[HUD_MOB_PALETTE_UP] + toggle_palette.refresh_owner() palette_down.refresh_owner() palette_up.refresh_owner() + listed_actions.update_landing() palette_actions.update_landing() @@ -628,214 +661,3 @@ GLOBAL_LIST_INIT(available_ui_styles, list( action.ShowTo(mymob) else position_action(button, button.location) - -/datum/action_group - /// The hud we're owned by - var/datum/hud/owner - /// The actions we're managing - var/list/atom/movable/screen/movable/action_button/actions - /// The initial vertical offset of our action buttons - var/north_offset = 0 - /// The pixel vertical offset of our action buttons - var/pixel_north_offset = 0 - /// Max amount of buttons we can have per row - /// Indexes at 1 - var/column_max = 0 - /// How far "ahead" of the first row we start. Lets us "scroll" our rows - /// Indexes at 1 - var/row_offset = 0 - /// How many rows of actions we can have at max before we just stop hiding - /// Indexes at 1 - var/max_rows = INFINITY - /// The screen location we go by - var/location - /// Our landing screen object - var/atom/movable/screen/action_landing/landing - -/datum/action_group/New(datum/hud/owner) - ..() - actions = list() - src.owner = owner - -/datum/action_group/Destroy() - owner = null - QDEL_NULL(landing) - QDEL_LIST(actions) - return ..() - -/datum/action_group/proc/insert_action(atom/movable/screen/action, index) - if(action in actions) - if(actions[index] == action) - return - actions -= action // Don't dupe, come on - if(!index) - index = length(actions) + 1 - index = min(length(actions) + 1, index) - actions.Insert(index, action) - refresh_actions() - -/datum/action_group/proc/remove_action(atom/movable/screen/action) - actions -= action - refresh_actions() - -/datum/action_group/proc/refresh_actions() - - // We don't use size() here because landings are not canon - var/total_rows = ROUND_UP(length(actions) / column_max) - total_rows -= max_rows // Lets get the amount of rows we're off from our max - row_offset = clamp(row_offset, 0, total_rows) // You're not allowed to offset so far that we have a row of blank space - - var/button_number = 0 - for(var/atom/movable/screen/button as anything in actions) - var/postion = ButtonNumberToScreenCoords(button_number ) - button.screen_loc = postion - button_number++ - - if(landing) - var/postion = ButtonNumberToScreenCoords(button_number, landing = TRUE) // Need a good way to count buttons off screen, but allow this to display in the right place if it's being placed with no concern for dropdown - landing.screen_loc = postion - button_number++ - -/// Accepts a number represeting our position in the group, indexes at 0 to make the math nicer -/datum/action_group/proc/ButtonNumberToScreenCoords(number, landing = FALSE) - var/row = round(number / column_max) - row -= row_offset // If you're less then 0, you don't get to render, this lets us "scroll" rows ya feel? - if(row < 0) - return null - - // Could use >= here, but I think it's worth noting that the two start at different places, since row is based on number here - if(row > max_rows - 1) - if(!landing) // If you're not a landing, go away please. thx - return null - // We always want to render landings, even if their action button can't be displayed. - // So we set a row equal to the max amount of rows + 1. Willing to overrun that max slightly to properly display the landing spot - row = max_rows // Remembering that max_rows indexes at 1, and row indexes at 0 - - // We're going to need to set our column to match the first item in the last row, so let's set number properly now - number = row * column_max - - var/visual_row = row + north_offset - var/coord_row = visual_row ? "-[visual_row]" : "+0" - - var/visual_column = number % column_max - var/coord_col = "+[visual_column]" - var/coord_col_offset = 4 + 2 * (visual_column + 1) - return "WEST[coord_col]:[coord_col_offset],NORTH[coord_row]:-[pixel_north_offset]" - -/datum/action_group/proc/check_against_view() - var/owner_view = owner?.mymob?.canon_client?.view - if(!owner_view) - return - // Unlikey as it is, we may have been changed. Want to start from our target position and fail down - column_max = initial(column_max) - // Convert our viewer's view var into a workable offset - var/list/view_size = view_to_pixels(owner_view) - - // We're primarially concerned about width here, if someone makes us 1x2000 I wish them a swift and watery death - var/furthest_screen_loc = ButtonNumberToScreenCoords(column_max - 1) - var/list/offsets = screen_loc_to_offset(furthest_screen_loc, owner_view) - if(offsets[1] > ICON_SIZE_X && offsets[1] < view_size[1] && offsets[2] > ICON_SIZE_Y && offsets[2] < view_size[2]) // We're all good - return - - for(column_max in column_max - 1 to 1 step -1) // Yes I could do this by unwrapping ButtonNumberToScreenCoords, but I don't feel like it - var/tested_screen_loc = ButtonNumberToScreenCoords(column_max) - offsets = screen_loc_to_offset(tested_screen_loc, owner_view) - // We've found a valid max length, pack it in - if(offsets[1] > ICON_SIZE_X && offsets[1] < view_size[1] && offsets[2] > ICON_SIZE_Y && offsets[2] < view_size[2]) - break - // Use our newly resized column max - refresh_actions() - -/// Returns the amount of objects we're storing at the moment -/datum/action_group/proc/size() - var/amount = length(actions) - if(landing) - amount += 1 - return amount - -/datum/action_group/proc/index_of(atom/movable/screen/get_location) - return actions.Find(get_location) - -/// Generates a landing object that can be dropped on to join this group -/datum/action_group/proc/generate_landing() - if(landing) - return - landing = new() - landing.set_owner(src) - refresh_actions() - -/// Clears any landing objects we may currently have -/datum/action_group/proc/clear_landing() - QDEL_NULL(landing) - -/datum/action_group/proc/update_landing() - if(!landing) - return - landing.refresh_owner() - -/datum/action_group/proc/scroll(amount) - row_offset += amount - refresh_actions() - -/datum/action_group/palette - north_offset = 2 - column_max = 3 - max_rows = 3 - location = SCRN_OBJ_IN_PALETTE - -/datum/action_group/palette/insert_action(atom/movable/screen/action, index) - . = ..() - var/atom/movable/screen/button_palette/palette = owner.toggle_palette - palette.play_item_added() - -/datum/action_group/palette/remove_action(atom/movable/screen/action) - . = ..() - var/atom/movable/screen/button_palette/palette = owner.toggle_palette - palette.play_item_removed() - if(!length(actions)) - palette.set_expanded(FALSE) - -/datum/action_group/palette/refresh_actions() - var/atom/movable/screen/button_palette/palette = owner.toggle_palette - var/atom/movable/screen/palette_scroll/scroll_down = owner.palette_down - var/atom/movable/screen/palette_scroll/scroll_up = owner.palette_up - - var/actions_above = round((owner.listed_actions.size() - 1) / owner.listed_actions.column_max) - north_offset = initial(north_offset) + actions_above - - palette.screen_loc = ui_action_palette_offset(actions_above) - var/action_count = length(owner?.mymob?.actions) - var/our_row_count = round((length(actions) - 1) / column_max) - if(!action_count) - palette.screen_loc = null - - if(palette.expanded && action_count && our_row_count >= max_rows) - scroll_down.screen_loc = ui_palette_scroll_offset(actions_above) - scroll_up.screen_loc = ui_palette_scroll_offset(actions_above) - else - scroll_down.screen_loc = null - scroll_up.screen_loc = null - - return ..() - -/datum/action_group/palette/ButtonNumberToScreenCoords(number, landing) - var/atom/movable/screen/button_palette/palette = owner.toggle_palette - if(palette.expanded) - return ..() - - if(!landing) - return null - - // We only render the landing in this case, so we force it to be the second item displayed (Second rather then first since it looks nicer) - // Remember the number var indexes at 0 - return ..(1 + (row_offset * column_max), landing) - - -/datum/action_group/listed - pixel_north_offset = 6 - column_max = 10 - location = SCRN_OBJ_IN_LIST - -/datum/action_group/listed/refresh_actions() - . = ..() - owner?.palette_actions.refresh_actions() // We effect them, so we gotta refresh em diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm index 4e6ef6f0e2b..d8d55dccf16 100644 --- a/code/_onclick/hud/human.dm +++ b/code/_onclick/hud/human.dm @@ -1,328 +1,38 @@ -/atom/movable/screen/human - icon = 'icons/hud/screen_midnight.dmi' +/datum/hud/human + inventory_slots = /datum/inventory_slot/human -/atom/movable/screen/human/toggle - name = "toggle" - icon_state = "toggle" - base_icon_state = "toggle" - mouse_over_pointer = MOUSE_HAND_POINTER - -/atom/movable/screen/human/toggle/Click() - - var/mob/targetmob = usr - - if(isobserver(usr)) - if(ishuman(usr.client.eye) && (usr.client.eye != usr)) - var/mob/M = usr.client.eye - targetmob = M - - if(usr.hud_used.inventory_shown && targetmob.hud_used) - usr.hud_used.inventory_shown = FALSE - usr.client.screen -= targetmob.hud_used.toggleable_inventory - else - usr.hud_used.inventory_shown = TRUE - usr.client.screen += targetmob.hud_used.toggleable_inventory - - targetmob.hud_used.hidden_inventory_update(usr) - update_appearance() - -/atom/movable/screen/human/toggle/update_icon_state() - icon_state = "[base_icon_state][hud?.inventory_shown ? "_active" : ""]" - return ..() - -/atom/movable/screen/ling - icon = 'icons/hud/screen_changeling.dmi' - -/atom/movable/screen/ling/chems - name = "chemical storage" - icon_state = "power_display" - screen_loc = ui_lingchemdisplay - ///Boolean on whether a mouse is being hovered over us right now. - var/hovering = FALSE - -/atom/movable/screen/ling/chems/Click(location, control, params) +/datum/hud/human/initialize_screen_objects() . = ..() - to_chat(usr, span_notice("Shows you how many chemicals you have. While hovering over this, it will show the max amount of chemicals you can hold.")) - -/atom/movable/screen/ling/chems/MouseEntered(location,control,params) - if(usr != get_mob()) - return - var/datum/antagonist/changeling/antagonist_datum = IS_CHANGELING(hud.mymob) - if(!antagonist_datum) - return - . = ..() - hovering = TRUE - antagonist_datum.update_chemical_hud() - -/atom/movable/screen/ling/chems/MouseExited(location, control, params) - if(usr != get_mob()) - return - var/datum/antagonist/changeling/antagonist_datum = IS_CHANGELING(hud.mymob) - if(!antagonist_datum) - return - . = ..() - hovering = FALSE - antagonist_datum.update_chemical_hud(antagonist_datum.chem_charges) - -/atom/movable/screen/ling/sting - name = "current sting" - screen_loc = ui_lingstingdisplay - invisibility = INVISIBILITY_ABSTRACT - mouse_over_pointer = MOUSE_HAND_POINTER - -/atom/movable/screen/ling/sting/Click() - if(isobserver(usr)) - return - var/mob/living/carbon/carbon_user = usr - carbon_user.unset_sting() - -/datum/hud/human/New(mob/living/carbon/human/owner) - ..() - var/atom/movable/screen/using - var/atom/movable/screen/inventory/inv_box - - using = new /atom/movable/screen/language_menu(null, src) - using.icon = ui_style - using.screen_loc = ui_human_language - static_inventory += using - - using = new /atom/movable/screen/navigate(null, src) - using.icon = ui_style - using.screen_loc = ui_human_navigate - static_inventory += using - - using = new /atom/movable/screen/area_creator(null, src) - using.icon = ui_style - using.screen_loc = ui_human_area - static_inventory += using - - using = new /atom/movable/screen/memories(null, src) - using.icon = ui_style - using.screen_loc = ui_human_memories_area - static_inventory += using - - action_intent = new /atom/movable/screen/combattoggle/flashy(null, src) - action_intent.icon = ui_style - action_intent.screen_loc = ui_combat_toggle - static_inventory += action_intent - - floor_change = new /atom/movable/screen/floor_changer/vertical(null, src) - floor_change.icon = ui_style - floor_change.screen_loc = ui_human_floor_changer - static_inventory += floor_change - - using = new /atom/movable/screen/mov_intent(null, src) - using.icon = ui_style - using.icon_state = (owner.move_intent == MOVE_INTENT_RUN ? "running" : "walking") - using.screen_loc = ui_movi - static_inventory += using - - 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 - inv_box.icon_state = "uniform" - inv_box.icon_full = "template" - inv_box.screen_loc = ui_iclothing - toggleable_inventory += inv_box - - 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 - inv_box.icon_state = "suit" - inv_box.icon_full = "template" - inv_box.screen_loc = ui_oclothing - toggleable_inventory += inv_box - + // Static elements + add_screen_object(/atom/movable/screen/language_menu, HUD_MOB_LANGUAGE_MENU, HUD_GROUP_STATIC, ui_style, ui_human_language) + add_screen_object(/atom/movable/screen/navigate, HUD_MOB_NAVIGATE_MENU, HUD_GROUP_STATIC, ui_style, ui_human_navigate) + add_screen_object(/atom/movable/screen/area_creator, HUD_MOB_AREA_CREATOR, HUD_GROUP_STATIC, ui_style, ui_human_area) + add_screen_object(/atom/movable/screen/combattoggle/flashy, HUD_MOB_INTENTS, HUD_GROUP_STATIC, ui_style) + add_screen_object(/atom/movable/screen/floor_changer/vertical, HUD_MOB_FLOOR_CHANGER, HUD_GROUP_STATIC, ui_style, ui_human_floor_changer) + add_screen_object(/atom/movable/screen/mov_intent, HUD_MOB_MOVE_INTENT, HUD_GROUP_STATIC, ui_style) + add_screen_object(/atom/movable/screen/drop, HUD_MOB_DROP, HUD_GROUP_STATIC, ui_style, ui_swaphand_position(mymob, 1)) + add_screen_object(/atom/movable/screen/human/toggle, HUD_HUMAN_TOGGLE_INVENTORY, HUD_GROUP_STATIC, ui_style) + add_screen_object(/atom/movable/screen/rest, HUD_MOB_REST, HUD_GROUP_STATIC, ui_style) + add_screen_object(/atom/movable/screen/sleep, HUD_MOB_SLEEP, HUD_GROUP_HOTKEYS, ui_style, ui_above_throw) + add_screen_object(/atom/movable/screen/pull, HUD_MOB_PULL, HUD_GROUP_STATIC, ui_style, ui_above_movement_top) + add_screen_object(/atom/movable/screen/zone_sel, HUD_MOB_ZONE_SELECTOR, HUD_GROUP_STATIC, ui_style) + add_screen_object(/atom/movable/screen/memories, HUD_MOB_MEMORIES, HUD_GROUP_STATIC, ui_style, ui_human_memories_menu) build_hand_slots() - using = new /atom/movable/screen/drop(null, src) - using.icon = ui_style - using.screen_loc = ui_swaphand_position(owner, 1) - static_inventory += using - - using = new /atom/movable/screen/swap_hand(null, src) - using.icon = ui_style + using = add_screen_object(/atom/movable/screen/swap_hand, HUD_MOB_SWAPHAND_2, HUD_GROUP_STATIC, ui_style, ui_swaphand_position(mymob, 2)) using.icon_state = "act_swap" - using.screen_loc = ui_swaphand_position(owner, 2) - static_inventory += using - inv_box = new /atom/movable/screen/inventory(null, src) - inv_box.name = "id" - inv_box.icon = ui_style - inv_box.icon_state = "id" - inv_box.icon_full = "template_small" - inv_box.screen_loc = ui_id - inv_box.slot_id = ITEM_SLOT_ID - static_inventory += inv_box + // Hotkey buttons + add_screen_object(/atom/movable/screen/resist, HUD_MOB_RESIST, HUD_GROUP_HOTKEYS, ui_style) + add_screen_object(/atom/movable/screen/throw_catch, HUD_MOB_THROW, HUD_GROUP_HOTKEYS, ui_style) - inv_box = new /atom/movable/screen/inventory(null, src) - inv_box.name = "mask" - inv_box.icon = ui_style - inv_box.icon_state = "mask" - inv_box.icon_full = "template" - inv_box.screen_loc = ui_mask - inv_box.slot_id = ITEM_SLOT_MASK - toggleable_inventory += inv_box - - inv_box = new /atom/movable/screen/inventory(null, src) - inv_box.name = "neck" - inv_box.icon = ui_style - inv_box.icon_state = "neck" - inv_box.icon_full = "template" - inv_box.screen_loc = ui_neck - inv_box.slot_id = ITEM_SLOT_NECK - toggleable_inventory += inv_box - - inv_box = new /atom/movable/screen/inventory(null, src) - inv_box.name = "back" - inv_box.icon = ui_style - inv_box.icon_state = "back" - inv_box.icon_full = "template_small" - inv_box.screen_loc = ui_back - inv_box.slot_id = ITEM_SLOT_BACK - static_inventory += inv_box - - 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_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(null, src) - inv_box.name = "right pocket" - inv_box.icon = ui_style - inv_box.icon_state = "pocket" - 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(null, src) - inv_box.name = "suit storage" - inv_box.icon = ui_style - inv_box.icon_state = "suit_storage" - inv_box.icon_full = "template" - inv_box.screen_loc = ui_sstore1 - inv_box.slot_id = ITEM_SLOT_SUITSTORE - static_inventory += inv_box - - resist_icon = new /atom/movable/screen/resist(null, src) - resist_icon.icon = ui_style - resist_icon.screen_loc = ui_above_movement - hotkeybuttons += resist_icon - - using = new /atom/movable/screen/human/toggle(null, src) - using.icon = ui_style - using.screen_loc = ui_inventory - static_inventory += using - - inv_box = new /atom/movable/screen/inventory(null, src) - inv_box.name = "gloves" - inv_box.icon = ui_style - inv_box.icon_state = "gloves" - inv_box.icon_full = "template" - inv_box.screen_loc = ui_gloves - inv_box.slot_id = ITEM_SLOT_GLOVES - toggleable_inventory += inv_box - - inv_box = new /atom/movable/screen/inventory(null, src) - inv_box.name = "eyes" - inv_box.icon = ui_style - inv_box.icon_state = "glasses" - inv_box.icon_full = "template" - inv_box.screen_loc = ui_glasses - inv_box.slot_id = ITEM_SLOT_EYES - toggleable_inventory += inv_box - - inv_box = new /atom/movable/screen/inventory(null, src) - inv_box.name = "ears" - inv_box.icon = ui_style - inv_box.icon_state = "ears" - inv_box.icon_full = "template" - inv_box.screen_loc = ui_ears - inv_box.slot_id = ITEM_SLOT_EARS - toggleable_inventory += inv_box - - inv_box = new /atom/movable/screen/inventory(null, src) - inv_box.name = "head" - inv_box.icon = ui_style - inv_box.icon_state = "head" - inv_box.icon_full = "template" - inv_box.screen_loc = ui_head - inv_box.slot_id = ITEM_SLOT_HEAD - toggleable_inventory += inv_box - - inv_box = new /atom/movable/screen/inventory(null, src) - inv_box.name = "shoes" - inv_box.icon = ui_style - inv_box.icon_state = "shoes" - inv_box.icon_full = "template" - inv_box.screen_loc = ui_shoes - inv_box.slot_id = ITEM_SLOT_FEET - toggleable_inventory += inv_box - - inv_box = new /atom/movable/screen/inventory(null, src) - inv_box.name = "belt" - inv_box.icon = ui_style - inv_box.icon_state = "belt" - inv_box.icon_full = "template_small" - inv_box.screen_loc = ui_belt - inv_box.slot_id = ITEM_SLOT_BELT - static_inventory += inv_box - - throw_icon = new /atom/movable/screen/throw_catch(null, src) - throw_icon.icon = ui_style - throw_icon.screen_loc = ui_drop_throw - hotkeybuttons += throw_icon - - rest_icon = new /atom/movable/screen/rest(null, src) - rest_icon.icon = ui_style - rest_icon.screen_loc = ui_rest - rest_icon.update_appearance() - static_inventory += rest_icon - - sleep_icon = new /atom/movable/screen/sleep(null, src) - sleep_icon.icon = ui_style - sleep_icon.screen_loc = ui_above_throw - - spacesuit_hud = new /atom/movable/screen/spacesuit(null, src) - infodisplay += spacesuit_hud - - healths = new /atom/movable/screen/healths(null, src) - infodisplay += healths - - hunger = new /atom/movable/screen/hunger(null, src) - infodisplay += hunger - - healthdoll = new /atom/movable/screen/healthdoll/human(null, src) - infodisplay += healthdoll - - stamina = new /atom/movable/screen/stamina(null, src) - infodisplay += stamina - - pull_icon = new /atom/movable/screen/pull(null, src) - pull_icon.icon = ui_style - pull_icon.screen_loc = ui_above_movement_top - pull_icon.update_appearance() - static_inventory += pull_icon - - zone_select = new /atom/movable/screen/zone_sel(null, src) - zone_select.icon = ui_style - zone_select.update_appearance() - static_inventory += zone_select - - for(var/atom/movable/screen/inventory/inv in (static_inventory + toggleable_inventory)) - if(inv.slot_id) - inv_slots[TOBITSHIFT(inv.slot_id) + 1] = inv - inv.update_appearance() - - update_locked_slots() + // Info + add_screen_object(/atom/movable/screen/spacesuit, HUD_MOB_SPACESUIT, HUD_GROUP_INFO) + add_screen_object(/atom/movable/screen/healthdoll/human, HUD_MOB_HEALTHDOLL, HUD_GROUP_INFO) + add_screen_object(/atom/movable/screen/stamina, HUD_MOB_STAMINA, HUD_GROUP_INFO) + add_screen_object(/atom/movable/screen/healths, HUD_MOB_HEALTH, HUD_GROUP_INFO) + add_screen_object(/atom/movable/screen/hunger, HUD_MOB_HUNGER, HUD_GROUP_INFO) /datum/hud/human/update_locked_slots() if(!mymob) @@ -355,8 +65,9 @@ if(eyes?.no_glasses) blocked_slots |= ITEM_SLOT_EYES - for(var/atom/movable/screen/inventory/inv in (static_inventory + toggleable_inventory)) - if(!inv.slot_id) + for(var/slot_key in screen_objects) + var/atom/movable/screen/inventory/inv = screen_objects[slot_key] + if(!istype(inv) || !inv.slot_id) continue inv.alpha = (blocked_slots & inv.slot_id) ? 128 : initial(inv.alpha) @@ -415,8 +126,6 @@ if(H.head) screenmob.client.screen -= H.head - - /datum/hud/human/persistent_inventory_update(mob/viewer) if(!mymob) return @@ -468,15 +177,131 @@ I.screen_loc = null screenmob.client.screen -= I - /mob/living/carbon/human/verb/toggle_hotkey_verbs() set category = "OOC" set name = "Toggle hotkey buttons" set desc = "This disables or enables the user interface buttons which can be used with hotkeys." if(hud_used.hotkey_ui_hidden) - client.screen += hud_used.hotkeybuttons + client.screen += hud_used.screen_groups[HUD_GROUP_HOTKEYS] hud_used.hotkey_ui_hidden = FALSE else - client.screen -= hud_used.hotkeybuttons + client.screen -= hud_used.screen_groups[HUD_GROUP_HOTKEYS] hud_used.hotkey_ui_hidden = TRUE + +/datum/inventory_slot/human + abstract_type = /datum/inventory_slot/human + +/datum/inventory_slot/human/uniform + name = "uniform" + slot_id = ITEM_SLOT_ICLOTHING + icon_state = "uniform" + icon_full = "template" + screen_loc = ui_iclothing + screen_group = HUD_GROUP_TOGGLEABLE_INVENTORY + +/datum/inventory_slot/human/suit + name = "suit" + slot_id = ITEM_SLOT_OCLOTHING + icon_state = "suit" + icon_full = "template" + screen_loc = ui_oclothing + screen_group = HUD_GROUP_TOGGLEABLE_INVENTORY + +/datum/inventory_slot/human/id + name = "id" + icon_state = "id" + icon_full = "template_small" + screen_loc = ui_id + slot_id = ITEM_SLOT_ID + +/datum/inventory_slot/human/mask + name = "mask" + icon_state = "mask" + icon_full = "template" + screen_loc = ui_mask + slot_id = ITEM_SLOT_MASK + screen_group = HUD_GROUP_TOGGLEABLE_INVENTORY + +/datum/inventory_slot/human/neck + name = "neck" + icon_state = "neck" + icon_full = "template" + screen_loc = ui_neck + slot_id = ITEM_SLOT_NECK + screen_group = HUD_GROUP_TOGGLEABLE_INVENTORY + +/datum/inventory_slot/human/back + name = "back" + icon_state = "back" + icon_full = "template_small" + screen_loc = ui_back + slot_id = ITEM_SLOT_BACK + +/datum/inventory_slot/human/l_pocket + name = "left pocket" + icon_state = "pocket" + icon_full = "template_small" + screen_loc = ui_storage1 + slot_id = ITEM_SLOT_LPOCKET + +/datum/inventory_slot/human/r_pocket + name = "right pocket" + icon_state = "pocket" + icon_full = "template_small" + screen_loc = ui_storage2 + slot_id = ITEM_SLOT_RPOCKET + +/datum/inventory_slot/human/suit_storage + name = "suit storage" + icon_state = "suit_storage" + icon_full = "template" + screen_loc = ui_sstore1 + slot_id = ITEM_SLOT_SUITSTORE + +/datum/inventory_slot/human/gloves + name = "gloves" + icon_state = "gloves" + icon_full = "template" + screen_loc = ui_gloves + slot_id = ITEM_SLOT_GLOVES + screen_group = HUD_GROUP_TOGGLEABLE_INVENTORY + +/datum/inventory_slot/human/eyes + name = "eyes" + icon_state = "glasses" + icon_full = "template" + screen_loc = ui_glasses + slot_id = ITEM_SLOT_EYES + screen_group = HUD_GROUP_TOGGLEABLE_INVENTORY + +/datum/inventory_slot/human/ears + name = "ears" + icon_state = "ears" + icon_full = "template" + screen_loc = ui_ears + slot_id = ITEM_SLOT_EARS + screen_group = HUD_GROUP_TOGGLEABLE_INVENTORY + +/datum/inventory_slot/human/head + name = "head" + icon_state = "head" + icon_full = "template" + screen_loc = ui_head + slot_id = ITEM_SLOT_HEAD + screen_group = HUD_GROUP_TOGGLEABLE_INVENTORY + +/datum/inventory_slot/human/shoes + name = "shoes" + icon_state = "shoes" + icon_full = "template" + screen_loc = ui_shoes + slot_id = ITEM_SLOT_FEET + screen_group = HUD_GROUP_TOGGLEABLE_INVENTORY + +/datum/inventory_slot/human/belt + name = "belt" + icon_state = "belt" + icon_full = "template_small" + screen_loc = ui_belt + slot_id = ITEM_SLOT_BELT diff --git a/code/_onclick/hud/inventory_slot.dm b/code/_onclick/hud/inventory_slot.dm new file mode 100644 index 00000000000..af3307be551 --- /dev/null +++ b/code/_onclick/hud/inventory_slot.dm @@ -0,0 +1,35 @@ +GLOBAL_LIST_INIT(inventory_slot_datums, initialize_inventory_slots()) + +/proc/initialize_inventory_slots() + var/list/slot_types = list() + for (var/slot_type in valid_subtypesof(/datum/inventory_slot)) + slot_types[slot_type] = new slot_type() + return slot_types + +/// Inventory slot datum (singleton) which holds data about an inventory screen element +/datum/inventory_slot + abstract_type = /datum/inventory_slot + /// Name assigned to the screen element + var/name = "error" + /// Should the slot inherit HUD's ui_style? + var/inherit_style = TRUE + /// Slot ID of the element + var/slot_id = NONE + /// Icon state of the element with nothing in it/unassigned icon_full + var/icon_state = "template" + /// Icon state of the element when it has an item in it + var/icon_full = "template" + /// Location of the element + var/screen_loc = null + /// Screen group to which the element is assigned + var/screen_group = HUD_GROUP_STATIC + /// Typepath of the screen element + var/screen_type = /atom/movable/screen/inventory + +/datum/inventory_slot/proc/create_element(datum/hud/hud) + var/atom/movable/screen/inventory/inv_box = hud.add_screen_object(screen_type, HUD_KEY_ITEM_SLOT(slot_id), screen_group, inherit_style ? hud.ui_style : null, screen_loc) + inv_box.name = name + inv_box.icon_state = icon_state + inv_box.icon_full = icon_full + inv_box.slot_id = slot_id + return inv_box diff --git a/code/_onclick/hud/living.dm b/code/_onclick/hud/living.dm index e9237d6dbb5..cd1575908e0 100644 --- a/code/_onclick/hud/living.dm +++ b/code/_onclick/hud/living.dm @@ -1,37 +1,9 @@ -/datum/hud/living/New(mob/living/owner) - ..() - - pull_icon = new /atom/movable/screen/pull(null, src) - pull_icon.icon = ui_style - pull_icon.update_appearance() - pull_icon.screen_loc = ui_living_pull - static_inventory += pull_icon - - action_intent = new /atom/movable/screen/combattoggle/flashy(null, src) - action_intent.icon = ui_style - action_intent.screen_loc = ui_basic_combat_toggle - static_inventory += action_intent - - floor_change = new /atom/movable/screen/floor_changer(null, src) - floor_change.icon = ui_style - floor_change.screen_loc = ui_floor_change - static_inventory += floor_change - - var/atom/movable/screen/using - - using = new /atom/movable/screen/language_menu(null, src) - using.icon = ui_style - using.screen_loc = ui_basic_language_menu - static_inventory += using - - using = new /atom/movable/screen/memories(null, src) - using.icon = ui_style - using.screen_loc = ui_basic_memories_menu - static_inventory += using - - //mob health doll assumes whatever sprite the mob is - healthdoll = new /atom/movable/screen/healthdoll/living(null, src) - infodisplay += healthdoll - - stamina = new /atom/movable/screen/stamina(null, src) - infodisplay += stamina +/datum/hud/living/initialize_screen_objects() + . = ..() + add_screen_object(/atom/movable/screen/pull, HUD_MOB_PULL, HUD_GROUP_STATIC, ui_style, ui_living_pull) + add_screen_object(/atom/movable/screen/combattoggle/flashy, HUD_MOB_INTENTS, HUD_GROUP_STATIC, ui_style, ui_basic_combat_toggle) + add_screen_object(/atom/movable/screen/healthdoll/living, HUD_MOB_HEALTHDOLL, HUD_GROUP_INFO) + add_screen_object(/atom/movable/screen/stamina, HUD_MOB_STAMINA, HUD_GROUP_INFO) + add_screen_object(/atom/movable/screen/floor_changer, HUD_MOB_FLOOR_CHANGER, HUD_GROUP_STATIC, ui_style, ui_floor_change) + add_screen_object(/atom/movable/screen/language_menu, HUD_MOB_LANGUAGE_MENU, HUD_GROUP_STATIC, ui_style, ui_basic_language_menu) + add_screen_object(/atom/movable/screen/memories, HUD_MOB_MEMORIES, HUD_GROUP_STATIC, ui_style, ui_basic_memories_menu) diff --git a/code/_onclick/hud/new_player.dm b/code/_onclick/hud/new_player.dm index 0b247aaa7da..fa991657de7 100644 --- a/code/_onclick/hud/new_player.dm +++ b/code/_onclick/hud/new_player.dm @@ -1,5 +1,3 @@ -#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 #define TRAIT_BUTTON_Y_ORIGIN 397 @@ -18,13 +16,11 @@ if (!owner?.client || owner.client.interviewee) return - var/list/buttons = subtypesof(/atom/movable/screen/lobby) - for (var/atom/movable/screen/lobby/lobbyscreen as anything in buttons) + for (var/atom/movable/screen/lobby/lobbyscreen as anything in subtypesof(/atom/movable/screen/lobby)) if (!initial(lobbyscreen.always_available)) continue - lobbyscreen = new lobbyscreen(our_hud = src) + lobbyscreen = add_screen_object(lobbyscreen, HUD_KEY_NEW_PLAYER(lobbyscreen)) lobbyscreen.SlowInit() - 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)) @@ -32,9 +28,8 @@ if (!owner.client.is_localhost()) return - var/atom/movable/screen/lobby/button/start_now/start_button = new(our_hud = src) + var/atom/movable/screen/lobby/button/start_now/start_button = add_screen_object(/atom/movable/screen/lobby/button/start_now, HUD_NEW_PLAYER_START_NOW) 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)) @@ -52,9 +47,8 @@ continue if(LAZYACCESS(shown_station_trait_buttons, trait)) continue - var/atom/movable/screen/lobby/button/sign_up/sign_up_button = new(our_hud = src) + var/atom/movable/screen/lobby/button/sign_up/sign_up_button = add_screen_object(/atom/movable/screen/lobby/button/sign_up, HUD_NEW_PLAYER_SIGN_UP) trait.setup_lobby_button(sign_up_button) - static_inventory |= sign_up_button LAZYSET(shown_station_trait_buttons, trait, sign_up_button) RegisterSignal(trait, COMSIG_QDELETING, PROC_REF(remove_station_trait_button)) @@ -93,734 +87,9 @@ return LAZYREMOVE(shown_station_trait_buttons, trait) UnregisterSignal(trait, COMSIG_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 - -///Set the HUD in New, as lobby screens are made before Atoms are Initialized. -/atom/movable/screen/lobby/New(loc, datum/hud/our_hud, ...) - set_new_hud(our_hud) - return ..() - -///Run sleeping actions after initialize -/atom/movable/screen/lobby/proc/SlowInit() - return - -///Animates moving the button off-screen -/atom/movable/screen/lobby/proc/collapse_button() - SIGNAL_HANDLER - //wait for the shutter to come down - animate(src, transform = transform, time = SHUTTER_MOVEMENT_DURATION + SHUTTER_WAIT_DURATION) - //then pull the buttons up with the shutter - animate(transform = transform.Translate(x = 0, y = 146), time = SHUTTER_MOVEMENT_DURATION, easing = CUBIC_EASING|EASE_IN) - -///Animates moving the button back into place -/atom/movable/screen/lobby/proc/expand_button() - SIGNAL_HANDLER - //the buttons are off-screen, so we sync them up to come down with the shutter - animate(src, transform = matrix(), time = SHUTTER_MOVEMENT_DURATION, easing = CUBIC_EASING|EASE_OUT) - -/atom/movable/screen/lobby/background - icon = 'icons/hud/lobby/background.dmi' - icon_state = "background" - layer = LOBBY_BACKGROUND_LAYER - screen_loc = "TOP,CENTER:-61" - -/atom/movable/screen/lobby/button - mouse_over_pointer = MOUSE_HAND_POINTER - ///Is the button currently enabled? - VAR_PROTECTED/enabled = TRUE - ///Is the button currently being hovered over with the mouse? - var/highlighted = FALSE - ///Should this button play the select sound? - var/select_sound_play = TRUE - -/atom/movable/screen/lobby/button/Click(location, control, params) - if(usr != get_mob()) - return - - if(!usr.client || usr.client.interviewee) - return - - . = ..() - - 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(usr != get_mob()) - return - - if(!usr.client || usr.client.interviewee) - return - - . = ..() - highlighted = TRUE - update_appearance(UPDATE_ICON) - -/atom/movable/screen/lobby/button/MouseExited() - if(usr != get_mob()) - return - - if(!usr.client || usr.client.interviewee) - return - - . = ..() - highlighted = FALSE - update_appearance(UPDATE_ICON) - -/atom/movable/screen/lobby/button/update_icon(updates) - . = ..() - if(!enabled) - icon_state = "[base_icon_state]_disabled" - return - else if(highlighted) - icon_state = "[base_icon_state]_highlighted" - return - icon_state = base_icon_state - -///Updates the button's status: TRUE to enable interaction with the button, FALSE to disable -/atom/movable/screen/lobby/button/proc/set_button_status(status) - if(status == enabled) - return FALSE - enabled = status - update_appearance(UPDATE_ICON) - mouse_over_pointer = enabled ? MOUSE_HAND_POINTER : MOUSE_INACTIVE_POINTER - return TRUE - -///Prefs menu -/atom/movable/screen/lobby/button/character_setup - name = "View Character Setup" - screen_loc = "TOP:-70,CENTER:-54" - icon = 'icons/hud/lobby/character_setup.dmi' - icon_state = "character_setup_disabled" - base_icon_state = "character_setup" - enabled = FALSE - -/atom/movable/screen/lobby/button/character_setup/Initialize(mapload, datum/hud/hud_owner) - . = ..() - // We need IconForge and the assets to be ready before allowing the menu to open - if(SSearly_assets.initialized == INITIALIZATION_INNEW_REGULAR || SSatoms.initialized == INITIALIZATION_INNEW_REGULAR) - flick("[base_icon_state]_enabled", src) - set_button_status(TRUE) - else - set_button_status(FALSE) - RegisterSignal(SSearly_assets, COMSIG_SUBSYSTEM_POST_INITIALIZE, PROC_REF(enable_character_setup)) - RegisterSignal(SSatoms, COMSIG_SUBSYSTEM_POST_INITIALIZE, PROC_REF(enable_character_setup)) - -/atom/movable/screen/lobby/button/character_setup/Click(location, control, params) - . = ..() - if(!.) - return - - var/datum/preferences/preferences = hud.mymob.canon_client.prefs - preferences.current_window = PREFERENCE_TAB_CHARACTER_PREFERENCES - preferences.update_static_data(usr) - preferences.ui_interact(usr) - -/atom/movable/screen/lobby/button/character_setup/proc/enable_character_setup() - SIGNAL_HANDLER - flick("[base_icon_state]_enabled", src) - set_button_status(TRUE) - UnregisterSignal(SSearly_assets, COMSIG_SUBSYSTEM_POST_INITIALIZE) - UnregisterSignal(SSatoms, COMSIG_SUBSYSTEM_POST_INITIALIZE) - -///Button that appears before the game has started -/atom/movable/screen/lobby/button/ready - name = "Toggle Readiness" - screen_loc = "TOP:-8,CENTER:-65" - icon = 'icons/hud/lobby/ready.dmi' - icon_state = "not_ready" - base_icon_state = "not_ready" - -/atom/movable/screen/lobby/button/ready/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(hide_ready_button)) - if(GAME_STATE_SETTING_UP) - set_button_status(FALSE) - RegisterSignal(SSticker, COMSIG_TICKER_ERROR_SETTING_UP, PROC_REF(show_ready_button)) - else - set_button_status(FALSE) - -/atom/movable/screen/lobby/button/ready/proc/hide_ready_button() - SIGNAL_HANDLER - set_button_status(FALSE) - UnregisterSignal(SSticker, COMSIG_TICKER_ENTER_SETTING_UP) - RegisterSignal(SSticker, COMSIG_TICKER_ERROR_SETTING_UP, PROC_REF(show_ready_button)) - -/atom/movable/screen/lobby/button/ready/proc/show_ready_button() - SIGNAL_HANDLER - set_button_status(TRUE) - UnregisterSignal(SSticker, COMSIG_TICKER_ERROR_SETTING_UP) - RegisterSignal(SSticker, COMSIG_TICKER_ENTER_SETTING_UP, PROC_REF(hide_ready_button)) - -/atom/movable/screen/lobby/button/ready/Click(location, control, params) - . = ..() - if(!.) - return - var/mob/dead/new_player/new_player = hud.mymob - - // switch based on the user, if they aren't ready then we change them to ready, and vice versa - if(new_player.ready == PLAYER_NOT_READY) - new_player.auto_deadmin_on_ready_or_latejoin() - new_player.ready = PLAYER_READY_TO_PLAY - base_icon_state = "ready" - else - 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 - name = "Join Game" - screen_loc = "TOP:-13,CENTER:-58" - icon = 'icons/hud/lobby/join.dmi' - icon_state = "" //Default to not visible - base_icon_state = "join_game" - enabled = null // set in init - -/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) - RegisterSignal(SSticker, COMSIG_TICKER_ERROR_SETTING_UP, PROC_REF(hide_join_button)) - else - set_button_status(TRUE) - -/atom/movable/screen/lobby/button/join/Click(location, control, params) - . = ..() - if(!.) - return - - if(!SSticker?.IsRoundInProgress()) - to_chat(hud.mymob, span_boldwarning("The round is either not ready, or has already finished...")) - return - - //Determines Relevent Population Cap - var/relevant_cap - var/hard_popcap = CONFIG_GET(number/hard_popcap) - var/extreme_popcap = CONFIG_GET(number/extreme_popcap) - if(hard_popcap && extreme_popcap) - relevant_cap = min(hard_popcap, extreme_popcap) - else - relevant_cap = max(hard_popcap, extreme_popcap) - - var/mob/dead/new_player/new_player = hud.mymob - - if(SSticker.queued_players.len || (relevant_cap && living_player_count() >= relevant_cap && !(ckey(new_player.key) in GLOB.admin_datums))) - to_chat(new_player, span_danger("[CONFIG_GET(string/hard_popcap_message)]")) - - var/queue_position = SSticker.queued_players.Find(new_player) - if(queue_position == 1) - to_chat(new_player, span_notice("You are next in line to join the game. You will be notified when a slot opens up.")) - else if(queue_position) - to_chat(new_player, span_notice("There are [queue_position-1] players in front of you in the queue to join the game.")) - else - SSticker.queued_players += new_player - to_chat(new_player, span_notice("You have been added to the queue to join the game. Your position in queue is [SSticker.queued_players.len].")) - return - - new_player.auto_deadmin_on_ready_or_latejoin() - - if(!LAZYACCESS(params2list(params), CTRL_CLICK)) - GLOB.latejoin_menu.ui_interact(new_player) - else - to_chat(new_player, span_warning("Opening emergency fallback late join menu! If THIS doesn't show, ahelp immediately!")) - GLOB.latejoin_menu.fallback_ui(new_player) - - -/atom/movable/screen/lobby/button/join/proc/show_join_button() - SIGNAL_HANDLER - set_button_status(TRUE) - UnregisterSignal(SSticker, COMSIG_TICKER_ENTER_SETTING_UP) - RegisterSignal(SSticker, COMSIG_TICKER_ERROR_SETTING_UP, PROC_REF(hide_join_button)) - -/atom/movable/screen/lobby/button/join/proc/hide_join_button() - SIGNAL_HANDLER - set_button_status(FALSE) - UnregisterSignal(SSticker, COMSIG_TICKER_ERROR_SETTING_UP) - RegisterSignal(SSticker, COMSIG_TICKER_ENTER_SETTING_UP, PROC_REF(show_join_button)) - -/atom/movable/screen/lobby/button/observe - name = "Observe" - screen_loc = "TOP:-40,CENTER:-54" - icon = 'icons/hud/lobby/observe.dmi' - icon_state = "observe_disabled" - base_icon_state = "observe" - enabled = null // set in init - -/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) - . = ..() - if(!.) - return - var/mob/dead/new_player/new_player = hud.mymob - new_player.make_me_an_observer() - -/atom/movable/screen/lobby/button/observe/proc/enable_observing() - SIGNAL_HANDLER - flick("[base_icon_state]_enabled", src) - set_button_status(TRUE) - UnregisterSignal(SSticker, COMSIG_TICKER_ENTER_PREGAME) - -//Subtype the bottom buttons away so the collapse/expand shutter goes behind them -/atom/movable/screen/lobby/button/bottom - layer = LOBBY_BOTTOM_BUTTON_LAYER - icon = 'icons/hud/lobby/bottom_buttons.dmi' - -/atom/movable/screen/lobby/button/bottom/settings - name = "View Game Preferences" - icon_state = "settings_disabled" - base_icon_state = "settings" - screen_loc = "TOP:-122,CENTER:+29" - enabled = FALSE - -/atom/movable/screen/lobby/button/bottom/settings/Initialize(mapload, datum/hud/hud_owner) - . = ..() - // We need IconForge and the assets to be ready before allowing the menu to open - if(SSearly_assets.initialized == INITIALIZATION_INNEW_REGULAR || SSatoms.initialized == INITIALIZATION_INNEW_REGULAR) - set_button_status(TRUE) - else - set_button_status(FALSE) - RegisterSignal(SSearly_assets, COMSIG_SUBSYSTEM_POST_INITIALIZE, PROC_REF(enable_settings)) - RegisterSignal(SSatoms, COMSIG_SUBSYSTEM_POST_INITIALIZE, PROC_REF(enable_settings)) - -/atom/movable/screen/lobby/button/bottom/settings/Click(location, control, params) - . = ..() - if(!.) - return - - var/datum/preferences/preferences = hud.mymob.canon_client.prefs - preferences.current_window = PREFERENCE_TAB_GAME_PREFERENCES - preferences.update_static_data(usr) - preferences.ui_interact(usr) - -/atom/movable/screen/lobby/button/bottom/settings/proc/enable_settings() - SIGNAL_HANDLER - set_button_status(TRUE) - UnregisterSignal(SSearly_assets, COMSIG_SUBSYSTEM_POST_INITIALIZE) - UnregisterSignal(SSatoms, COMSIG_SUBSYSTEM_POST_INITIALIZE) - -/atom/movable/screen/lobby/button/bottom/changelog_button - name = "View Changelog" - icon_state = "changelog" - base_icon_state = "changelog" - screen_loc ="TOP:-122,CENTER:+57" - -/atom/movable/screen/lobby/button/bottom/changelog_button/Click(location, control, params) - . = ..() - usr.client?.changelog() - -/atom/movable/screen/lobby/button/bottom/crew_manifest - name = "View Crew Manifest" - icon_state = "crew_manifest" - base_icon_state = "crew_manifest" - screen_loc = "TOP:-122,CENTER:+2" - -/atom/movable/screen/lobby/button/bottom/crew_manifest/Click(location, control, params) - . = ..() - if(!.) - return - var/mob/dead/new_player/new_player = hud.mymob - new_player.ViewManifest() - -/atom/movable/screen/lobby/button/bottom/poll - name = "View Available Polls" - icon_state = "poll" - base_icon_state = "poll" - screen_loc = "TOP:-122,CENTER:-26" - ///Whether the button should have a New Poll notification overlay - var/new_poll = FALSE - -/atom/movable/screen/lobby/button/bottom/poll/SlowInit(mapload) - . = ..() - if(!usr) - return - var/mob/dead/new_player/new_player = usr - if(is_guest_key(new_player.key)) - set_button_status(FALSE) - return - if(!SSdbcore.Connect()) - set_button_status(FALSE) - return - var/isadmin = FALSE - if(new_player.client?.holder) - isadmin = TRUE - var/datum/db_query/query_get_new_polls = SSdbcore.NewQuery({" - SELECT id FROM [format_table_name("poll_question")] - WHERE (adminonly = 0 OR :isadmin = 1) - AND Now() BETWEEN starttime AND endtime - AND deleted = 0 - AND id NOT IN ( - SELECT pollid FROM [format_table_name("poll_vote")] - WHERE ckey = :ckey - AND deleted = 0 - ) - AND id NOT IN ( - SELECT pollid FROM [format_table_name("poll_textreply")] - WHERE ckey = :ckey - AND deleted = 0 - ) - "}, list("isadmin" = isadmin, "ckey" = new_player.ckey)) - if(!query_get_new_polls.Execute()) - qdel(query_get_new_polls) - set_button_status(FALSE) - return - if(query_get_new_polls.NextRow()) - new_poll = TRUE - else - new_poll = FALSE - update_appearance(UPDATE_OVERLAYS) - qdel(query_get_new_polls) - if(QDELETED(new_player)) - set_button_status(FALSE) - return - -/atom/movable/screen/lobby/button/bottom/poll/update_overlays() - . = ..() - if(new_poll) - . += mutable_appearance('icons/hud/lobby/poll_overlay.dmi', "new_poll") - -/atom/movable/screen/lobby/button/bottom/poll/Click(location, control, params) - . = ..() - if(!.) - return - 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' - icon_state = "collapse" - base_icon_state = "collapse" - layer = LOBBY_BELOW_MENU_LAYER - 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(!.) - return - - if(!istype(hud, /datum/hud/new_player)) - return - var/datum/hud/new_player/our_hud = hud - base_icon_state = our_hud.menu_hud_status ? "expand" : "collapse" - name = "[our_hud.menu_hud_status ? "Expand" : "Collapse"] Lobby Menu" - set_button_status(FALSE) - - //get the shutter object used by our hud - var/atom/movable/screen/lobby/shutter/menu_shutter = locate(/atom/movable/screen/lobby/shutter) in hud.static_inventory - - //animate the shutter - menu_shutter.setup_shutter_animation() - //animate bottom buttons' movement - if(our_hud.menu_hud_status) - collapse_menu() - else - expand_menu() - our_hud.menu_hud_status = !our_hud.menu_hud_status - - //re-enable clicking the button when the shutter animation finishes - //we use sleep here so it can work during game setup, as addtimer would not work until the game would finish setting up - 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.is_ready_to_play() ? "" : "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() - SEND_SIGNAL(hud, COMSIG_HUD_LOBBY_COLLAPSED) - //wait for the shutter to come down - 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' - icon_state = "shutter" - base_icon_state = "shutter" - screen_loc = "TOP:+143,CENTER:-73" //"home" position is off-screen - layer = LOBBY_SHUTTER_LAYER - always_shown = TRUE - -///Sets up the shutter pulling down and up. It's the same animation for both collapsing and expanding the menu. -/atom/movable/screen/lobby/shutter/proc/setup_shutter_animation() - //bring down the shutter - animate(src, transform = transform.Translate(x = 0, y = -143), time = SHUTTER_MOVEMENT_DURATION, easing = CUBIC_EASING|EASE_OUT) - - //wait a little bit before bringing the shutter up - animate(transform = transform, time = SHUTTER_WAIT_DURATION) - - //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/cartoon_sfx/cartoon_splat.ogg', volume = 50)) - SSticker.start_immediately = TRUE - if(SSticker.current_state == GAME_STATE_STARTUP) - to_chat(usr, span_admin("The server is still setting up, but the round will be started as soon as possible.")) - -#define OVERLAY_X_DIFF 12 -#define OVERLAY_Y_DIFF 5 - -///Lobby screen that appears before the game has started showing how many players there are and who is ready. -/atom/movable/screen/lobby/new_player_info - name = "New Player Info" - screen_loc = "EAST-3,CENTER:140" - icon = 'icons/hud/lobby/newplayer.dmi' - icon_state = null //we only show up when we get update appearance called, cause we need our overlay to not look bad. - base_icon_state = "newplayer" - maptext_height = 75 - maptext_width = 80 - maptext_x = OVERLAY_X_DIFF - maptext_y = OVERLAY_Y_DIFF - - ///Boolean on whether or not we should have our static overlay, so we 'turn' the TV off when collapsing. - var/show_static = TRUE - ///Static mutable appearance of a job icon we're displaying on the TV for overflow job. - var/static/mutable_appearance/job_overlay - -/atom/movable/screen/lobby/new_player_info/Initialize(mapload, datum/hud/hud_owner) - . = ..() - START_PROCESSING(SSnewplayer_info, src) - update_text() - - //only go if the station trait is selected, otherwise it'll show "Assistant" every round. - var/datum/station_trait/overflow_job_bureaucracy/overflow_job = locate() in SSstation.station_traits - if(overflow_job && isnull(job_overlay)) - var/icon/job_icon = get_job_hud_icon(SSjob.overflow_role) - if(isnull(job_icon)) - stack_trace("[SSjob.overflow_role::title] was selected as the Job Overflow but has no icon!") - else - job_icon.Scale(ICON_SIZE_X / 2, ICON_SIZE_X / 2) - job_overlay = mutable_appearance(job_icon, offset_spokesman = src, alpha = 120, layer = src.layer+0.02) - var/matrix/job_matrix = matrix() - job_matrix.Translate(6, 14) //this is completely arbitruary just what I thought looked good. - job_overlay.transform = job_matrix - - update_appearance(UPDATE_ICON) - -/atom/movable/screen/lobby/new_player_info/Destroy() - STOP_PROCESSING(SSnewplayer_info, src) - return ..() - -/atom/movable/screen/lobby/new_player_info/MouseEntered(location, control, params) - . = ..() - if(QDELETED(src) || isnull(job_overlay)) - return - openToolTip(usr, src, params, title = "[SSjob.overflow_role::title] overflow", content = "The overflow for the round has been set as [SSjob.overflow_role::title].") - -/atom/movable/screen/lobby/new_player_info/MouseExited() - closeToolTip(usr) - return ..() - -/atom/movable/screen/lobby/new_player_info/update_icon_state() - . = ..() - icon_state = base_icon_state - -/atom/movable/screen/lobby/new_player_info/update_overlays() - . = ..() - . += mutable_appearance(icon, "[base_icon_state]_overlay", layer = src.layer+0.01) - if(!show_static) - return . - if(job_overlay) - . += job_overlay - . += mutable_appearance(icon, "static_base", alpha = 20, layer = src.layer+0.03) - //we have this in a separate file because `generate_icon_alpha_mask` puts lighting even on non-existent pixels, - //giving the icon a weird background color. - var/mutable_appearance/scanline = mutable_appearance(generate_icon_alpha_mask('icons/hud/lobby/newplayer_scanline.dmi', "scanline"), alpha = 20, layer = src.layer+0.04) - scanline.pixel_y = OVERLAY_X_DIFF - scanline.pixel_x = OVERLAY_Y_DIFF - . += scanline - -/atom/movable/screen/lobby/new_player_info/process(seconds_per_tick) - update_text() - -/atom/movable/screen/lobby/new_player_info/collapse_button() - show_static = FALSE - update_text() - //to be in sync with parent, we'll turn the TV off in this time instead. - animate(src, appearance = update_appearance(UPDATE_ICON), time = SHUTTER_MOVEMENT_DURATION + SHUTTER_WAIT_DURATION) - //we go to the right, not up - animate(transform = transform.Translate(x = 146, y = 0), time = SHUTTER_MOVEMENT_DURATION, easing = CUBIC_EASING|EASE_IN) - -/atom/movable/screen/lobby/new_player_info/expand_button() - . = ..() - show_static = TRUE - update_appearance(UPDATE_ICON) - update_text() - -/atom/movable/screen/lobby/new_player_info/proc/update_text() - if(!hud || !show_static) - maptext = null - return - - var/round_started = SSticker.HasRoundStarted() - if(!MC_RUNNING()) - maptext = MAPTEXT("[(round_started ? null : "Starting in [time_remaining_str()]
")]Loading...
") - return - if(SSticker.IsPostgame()) - maptext = MAPTEXT("Game ended,
\ - restart soon
") - return - - var/new_maptext - if(round_started) - new_maptext = "[SSmapping.current_map.map_name]
\ - [LAZYLEN(GLOB.clients)] player\s online
\ - [ROUND_TIME()] in
" - new_maptext += "
" - else - - if(hud.mymob.client?.holder) - new_maptext = "Starting in [time_remaining_str()]
\ - [LAZYLEN(GLOB.clients)] player\s
\ - [SSticker.totalPlayersReady] players ready
\ - [SSticker.total_admins_ready] / [length(GLOB.admins)] admins ready
" - else - new_maptext = "[time_remaining_str()]
\ - [LAZYLEN(GLOB.clients)] player\s" - - maptext = MAPTEXT(new_maptext) - -/atom/movable/screen/lobby/new_player_info/proc/time_remaining_str() - var/time_remaining = SSticker.GetTimeLeft() - if(time_remaining > 0) - time_remaining = "[round(time_remaining/10)]s" - else if(time_remaining == -10) - time_remaining = "DELAYED" - else - time_remaining = "SOON" - - return time_remaining - -#undef OVERLAY_X_DIFF -#undef OVERLAY_Y_DIFF - -#undef SHUTTER_MOVEMENT_DURATION -#undef SHUTTER_WAIT_DURATION #undef MAX_STATION_TRAIT_BUTTONS_VERTICAL #undef TRAIT_BUTTON_Y_ORIGIN #undef TRAIT_BUTTON_X_ORIGIN diff --git a/code/_onclick/hud/ooze.dm b/code/_onclick/hud/ooze.dm index 0962b58126a..e796df33b4a 100644 --- a/code/_onclick/hud/ooze.dm +++ b/code/_onclick/hud/ooze.dm @@ -1,14 +1,8 @@ ///Hud type with targeting dol and a nutrition bar -/datum/hud/ooze/New(mob/living/owner) +/datum/hud/ooze/initialize_screen_objects() . = ..() - - zone_select = new /atom/movable/screen/zone_sel(null, src) - zone_select.icon = ui_style - zone_select.update_appearance() - static_inventory += zone_select - - alien_plasma_display = new /atom/movable/screen/ooze_nutrition_display(null, src) //Just going to use the alien plasma display because making new vars for each object is braindead. - infodisplay += alien_plasma_display + add_screen_object(/atom/movable/screen/zone_sel, HUD_MOB_ZONE_SELECTOR, HUD_GROUP_STATIC, ui_style) + add_screen_object(/atom/movable/screen/ooze_nutrition_display, HUD_OOZE_NUTRITION_DISPLAY) /atom/movable/screen/ooze_nutrition_display icon = 'icons/hud/screen_alien.dmi' diff --git a/code/_onclick/hud/pai.dm b/code/_onclick/hud/pai.dm new file mode 100644 index 00000000000..74da5962b37 --- /dev/null +++ b/code/_onclick/hud/pai.dm @@ -0,0 +1,33 @@ + +/datum/hud/pai + ui_style = 'icons/hud/screen_pai.dmi' + +/datum/hud/pai/initialize_screen_objects() + . = ..() + add_screen_object(/atom/movable/screen/language_menu, HUD_MOB_LANGUAGE_MENU, ui_style, ui_pai_language_menu) + add_screen_object(/atom/movable/screen/navigate, HUD_MOB_NAVIGATE_MENU, ui_style, ui_pai_navigate_menu) + add_screen_object(/atom/movable/screen/memories, HUD_MOB_MEMORIES, HUD_GROUP_STATIC, ui_style, ui_pai_memories_menu) + + add_screen_object(/atom/movable/screen/pai/software, HUD_PAI_SOFTWARE) + add_screen_object(/atom/movable/screen/pai/shell, HUD_PAI_SHELL) + add_screen_object(/atom/movable/screen/pai/chassis, HUD_PAI_CHASSIS) + add_screen_object(/atom/movable/screen/pai/rest, HUD_MOB_REST) + add_screen_object(/atom/movable/screen/pai/light, HUD_CYBORG_LAMP) + add_screen_object(/atom/movable/screen/pai/newscaster, HUD_PAI_NEWSCASTER) + add_screen_object(/atom/movable/screen/pai/host_monitor, HUD_PAI_HOST_MONITOR) + add_screen_object(/atom/movable/screen/pai/crew_manifest, HUD_AI_CREW_MANIFEST) + add_screen_object(/atom/movable/screen/pai/state_laws, HUD_AI_STATE_LAWS) + add_screen_object(/atom/movable/screen/pai/internal_gps, HUD_PAI_GPS) + add_screen_object(/atom/movable/screen/pai/image_take, HUD_AI_TAKE_IMAGE) + add_screen_object(/atom/movable/screen/pai/image_view, HUD_AI_IMAGE_VIEW) + add_screen_object(/atom/movable/screen/pai/radio, HUD_CYBORG_RADIO) + add_screen_object(/atom/movable/screen/pai/modpc, HUD_SILICON_TABLET) + + update_software_buttons() + +/datum/hud/pai/proc/update_software_buttons() + var/mob/living/silicon/pai/owner = mymob + for(var/button_key in screen_objects) + var/atom/movable/screen/pai/button = screen_objects[button_key] + if(istype(button) && button.required_software) + button.color = owner.installed_software.Find(button.required_software) ? null : COLOR_GRAY diff --git a/code/_onclick/hud/parallax/parallax.dm b/code/_onclick/hud/parallax/parallax.dm index 8a2227db588..c29e45dfde7 100644 --- a/code/_onclick/hud/parallax/parallax.dm +++ b/code/_onclick/hud/parallax/parallax.dm @@ -201,7 +201,6 @@ hud_used.set_parallax_movedir(areaobj.parallax_movedir, TRUE) // Root object for parallax, all parallax layers are drawn onto this and it manages them -INITIALIZE_IMMEDIATE(/atom/movable/screen/parallax_home) /atom/movable/screen/parallax_home icon = null blend_mode = BLEND_ADD @@ -293,7 +292,6 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen/parallax_home) QDEL_LIST(parallax_layers_cached) // We need parallax to always pass its args down into initialize, so we immediate init it -INITIALIZE_IMMEDIATE(/atom/movable/screen/parallax_layer) /atom/movable/screen/parallax_layer icon = 'icons/effects/parallax.dmi' var/speed = 1 diff --git a/code/_onclick/hud/perks.dm b/code/_onclick/hud/perks.dm deleted file mode 100644 index 22b08906b66..00000000000 --- a/code/_onclick/hud/perks.dm +++ /dev/null @@ -1,35 +0,0 @@ -/atom/movable/screen/perk - icon = 'icons/hud/perks.dmi' - name = "blank" - icon_state = "blank" - -/atom/movable/screen/perk/more - name = "more" - icon_state = "more" - // When compact we don't show our perk huds in ui. - var/compact = FALSE - // List of all perks that we see on hud. - var/list/perks_on_hud = list() - // List to remember all perks we hide when compact it. - var/list/perks_compacted = list() - -/atom/movable/screen/perk/more/Click(location, control, params) - . = ..() - if(!isliving(usr)) - return - var/mob/living/usr_is_living = usr - var/datum/antagonist/wizard/wizard_datum = usr_is_living.mind.has_antag_datum(/datum/antagonist/wizard) - if(!wizard_datum) - return - compact = !compact - var/datum/hud/user_hud = usr_is_living.hud_used - if(compact) - for(var/atom/movable/screen/perk/perk_on_hud as anything in perks_on_hud) - perks_compacted += perk_on_hud - user_hud.infodisplay -= perk_on_hud - user_hud.show_hud(user_hud.hud_version) - else - for(var/atom/movable/screen/perk/perk_compacted as anything in perks_compacted) - user_hud.infodisplay += perk_compacted - perks_compacted -= perk_compacted - user_hud.show_hud(user_hud.hud_version) diff --git a/code/_onclick/hud/rendering/plane_masters/_plane_master.dm b/code/_onclick/hud/rendering/plane_masters/_plane_master.dm index 02d1f0ca3b4..c1efa44f8a3 100644 --- a/code/_onclick/hud/rendering/plane_masters/_plane_master.dm +++ b/code/_onclick/hud/rendering/plane_masters/_plane_master.dm @@ -1,6 +1,3 @@ -// I hate this place -INITIALIZE_IMMEDIATE(/atom/movable/screen/plane_master) - /atom/movable/screen/plane_master screen_loc = "CENTER" icon_state = "blank" diff --git a/code/_onclick/hud/revenanthud.dm b/code/_onclick/hud/revenanthud.dm index c47ea4c2418..49d89fb159e 100644 --- a/code/_onclick/hud/revenanthud.dm +++ b/code/_onclick/hud/revenanthud.dm @@ -1,14 +1,7 @@ /datum/hud/revenant ui_style = 'icons/hud/screen_gen.dmi' -/datum/hud/revenant/New(mob/owner) - ..() - - pull_icon = new /atom/movable/screen/pull(null, src) - pull_icon.icon = ui_style - pull_icon.update_appearance() - pull_icon.screen_loc = ui_living_pull - static_inventory += pull_icon - - healths = new /atom/movable/screen/healths/revenant(null, src) - infodisplay += healths +/datum/hud/revenant/initialize_screen_objects() + . = ..() + add_screen_object(/atom/movable/screen/pull, HUD_MOB_PULL, HUD_GROUP_STATIC, ui_style, ui_living_pull) + add_screen_object(/atom/movable/screen/healths/revenant, HUD_MOB_HEALTH, HUD_GROUP_INFO) diff --git a/code/_onclick/hud/robot.dm b/code/_onclick/hud/robot.dm index 498d58dccb2..53b146b5b03 100644 --- a/code/_onclick/hud/robot.dm +++ b/code/_onclick/hud/robot.dm @@ -1,184 +1,38 @@ -/atom/movable/screen/robot - icon = 'icons/hud/screen_cyborg.dmi' - mouse_over_pointer = MOUSE_HAND_POINTER - -/atom/movable/screen/robot/module - name = "cyborg module" - icon_state = "nomod" - -/atom/movable/screen/robot/Click(location, control, params) - if(isobserver(usr)) - return TRUE - -/atom/movable/screen/robot/module/Click(location, control, params) - . = ..() - var/mob/living/silicon/robot/robot_owner = hud.mymob - if(robot_owner.model.type == /obj/item/robot_model) - if(.) - return - robot_owner.pick_model() - return - var/list/modifiers = params2list(params) - if(robot_owner.module_active && !LAZYACCESS(modifiers, RIGHT_CLICK) && !.) - robot_owner.uneq_active() - return - - //observers can look at borg's inventories, so we ignore parent return value here, unlike everywhere else. - if(usr.active_storage == robot_owner.model.atom_storage) - robot_owner.model.atom_storage.hide_contents(usr) - else - robot_owner.model.atom_storage.open_storage(usr) - return TRUE - -/atom/movable/screen/robot/module1 - name = "module1" - icon_state = "inv1" - -/atom/movable/screen/robot/module1/Click() - if(..()) - return - var/mob/living/silicon/robot/R = usr - R.toggle_module(1) - -/atom/movable/screen/robot/module2 - name = "module2" - icon_state = "inv2" - -/atom/movable/screen/robot/module2/Click() - if(..()) - return - var/mob/living/silicon/robot/R = usr - R.toggle_module(2) - -/atom/movable/screen/robot/module3 - name = "module3" - icon_state = "inv3" - -/atom/movable/screen/robot/module3/Click() - if(..()) - return - var/mob/living/silicon/robot/R = usr - R.toggle_module(3) - -/atom/movable/screen/robot/radio - name = "radio" - icon_state = "radio" - -/atom/movable/screen/robot/radio/Click() - if(..()) - return - var/mob/living/silicon/robot/R = usr - R.radio.interact(R) - /datum/hud/robot ui_style = 'icons/hud/screen_cyborg.dmi' -/datum/hud/robot/New(mob/owner) - ..() +/datum/hud/robot/initialize_screen_objects() + . = ..() // i, Robit var/mob/living/silicon/robot/robit = mymob - var/atom/movable/screen/using + add_screen_object(/atom/movable/screen/language_menu, HUD_MOB_LANGUAGE_MENU, HUD_GROUP_STATIC, ui_style, ui_borg_language_menu) + add_screen_object(/atom/movable/screen/navigate, HUD_MOB_NAVIGATE_MENU, HUD_GROUP_STATIC, ui_style, ui_borg_navigate_menu) + add_screen_object(/atom/movable/screen/memories, HUD_MOB_MEMORIES, HUD_GROUP_STATIC, ui_style, ui_borg_memories_menu) + add_screen_object(/atom/movable/screen/robot/radio, HUD_CYBORG_RADIO) -// Language - using = new/atom/movable/screen/language_menu(null, src) - using.icon = ui_style - using.screen_loc = ui_borg_language_menu - static_inventory += using + for (var/i in BORG_CHOOSE_MODULE_ONE to BORG_CHOOSE_MODULE_THREE) + var/atom/movable/screen/robot/module_slot/module = add_screen_object(/atom/movable/screen/robot/module_slot, HUD_KEY_CYBORG_MODULE(i)) + module.set_slot(i) -// Navigation - using = new /atom/movable/screen/navigate(null, src) - using.icon = ui_style - using.screen_loc = ui_borg_navigate_menu - static_inventory += using + add_screen_object(/atom/movable/screen/robot/lamp, HUD_CYBORG_LAMP) + add_screen_object(/atom/movable/screen/ai/image_take, HUD_SILICON_TAKE_IMAGE, ui_loc = ui_borg_camera) -// Memories - using = new /atom/movable/screen/memories(null, src) - using.icon = ui_style - using.screen_loc = ui_borg_memories_menu - static_inventory += using - -//Radio - using = new /atom/movable/screen/robot/radio(null, src) - using.screen_loc = ui_borg_radio - static_inventory += using - -//Module select - if(!robit.inv1) - robit.inv1 = new /atom/movable/screen/robot/module1(null, src) - robit.inv1.screen_loc = ui_inv1 - static_inventory += robit.inv1 - - if(!robit.inv2) - robit.inv2 = new /atom/movable/screen/robot/module2(null, src) - robit.inv2.screen_loc = ui_inv2 - static_inventory += robit.inv2 - - if(!robit.inv3) - robit.inv3 = new /atom/movable/screen/robot/module3(null, src) - robit.inv3.screen_loc = ui_inv3 - static_inventory += robit.inv3 - -//End of module select - using = new /atom/movable/screen/robot/lamp(null, src) - using.screen_loc = ui_borg_lamp - 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(null, src) - using.screen_loc = ui_borg_camera - static_inventory += using - -//Borg Integrated Tablet - using = new /atom/movable/screen/robot/modpc(null, src) - using.screen_loc = ui_borg_tablet - static_inventory += using - robit.interfaceButton = using + var/atom/movable/screen/robot/modpc/tablet = add_screen_object(/atom/movable/screen/robot/modpc, HUD_SILICON_TABLET, HUD_GROUP_STATIC) if(robit.modularInterface) // Just trust me robit.modularInterface.vis_flags |= VIS_INHERIT_PLANE - using.vis_contents += robit.modularInterface - var/atom/movable/screen/robot/modpc/tabletbutton = using - tabletbutton.robot = robit + tablet.vis_contents += robit.modularInterface -//Alerts - using = new /atom/movable/screen/robot/alerts(null, src) - using.screen_loc = ui_borg_alerts - static_inventory += using + add_screen_object(/atom/movable/screen/robot/alerts, HUD_SILICON_ALERTS) + add_screen_object(/atom/movable/screen/combattoggle/robot, HUD_MOB_INTENTS) + add_screen_object(/atom/movable/screen/floor_changer, HUD_MOB_FLOOR_CHANGER, HUD_GROUP_STATIC, ui_style, ui_borg_floor_changer) + add_screen_object(/atom/movable/screen/zone_sel/robot, HUD_MOB_ZONE_SELECTOR) + var/atom/movable/screen/robot/module/module = add_screen_object(/atom/movable/screen/robot/module, HUD_CYBORG_HANDS, ui_loc = ui_borg_module) + module.icon_state = robit.model ? robit.model.model_select_icon : "nomod" - //Combat Mode - action_intent = new /atom/movable/screen/combattoggle/robot(null, src) - action_intent.icon = ui_style - action_intent.screen_loc = ui_borg_intents - static_inventory += action_intent + add_screen_object(/atom/movable/screen/healths/robot, HUD_MOB_HEALTH, HUD_GROUP_INFO) - floor_change = new /atom/movable/screen/floor_changer(null, src) - floor_change.icon = ui_style - floor_change.screen_loc = ui_borg_floor_changer - static_inventory += floor_change - -//Health - healths = new /atom/movable/screen/healths/robot(null, src) - infodisplay += healths - -//Installed Module - robit.hands = new /atom/movable/screen/robot/module(null, src) - robit.hands.icon_state = robit.model ? robit.model.model_select_icon : "nomod" - robit.hands.screen_loc = ui_borg_module - static_inventory += robit.hands - - pull_icon = new /atom/movable/screen/pull(null, src) - pull_icon.icon = 'icons/hud/screen_cyborg.dmi' - pull_icon.screen_loc = ui_borg_pull - pull_icon.update_appearance() - hotkeybuttons += pull_icon - - - zone_select = new /atom/movable/screen/zone_sel/robot(null, src) - zone_select.update_appearance() - static_inventory += zone_select + add_screen_object(/atom/movable/screen/pull, HUD_MOB_PULL, HUD_GROUP_HOTKEYS, ui_style, ui_borg_pull) /datum/hud/robot/persistent_inventory_update(mob/viewer) if(!mymob) @@ -186,74 +40,18 @@ var/mob/living/silicon/robot/R = mymob var/mob/screenmob = viewer || R - - if(screenmob.hud_used) - if(screenmob.hud_used.hud_shown) - for(var/i in 1 to R.held_items.len) - var/obj/item/I = R.held_items[i] - if(I) - switch(i) - if(BORG_CHOOSE_MODULE_ONE) - I.screen_loc = ui_inv1 - if(BORG_CHOOSE_MODULE_TWO) - I.screen_loc = ui_inv2 - if(BORG_CHOOSE_MODULE_THREE) - I.screen_loc = ui_inv3 - else - return - screenmob.client.screen += I - else - for(var/obj/item/I in R.held_items) - screenmob.client.screen -= I - -/atom/movable/screen/robot/lamp - name = "headlamp" - icon_state = "lamp_off" - base_icon_state = "lamp" - var/mob/living/silicon/robot/robot - -/atom/movable/screen/robot/lamp/Click() - . = ..() - if(.) + if(!screenmob.hud_used) return - robot?.toggle_headlamp() - update_appearance() -/atom/movable/screen/robot/lamp/update_icon_state() - icon_state = "[base_icon_state]_[robot?.lamp_enabled ? "on" : "off"]" - return ..() - -/atom/movable/screen/robot/lamp/Destroy() - if(robot) - robot.lampButton = null - robot = null - return ..() - -/atom/movable/screen/robot/modpc - name = "Modular Interface" - icon_state = "template" - var/mob/living/silicon/robot/robot - -/atom/movable/screen/robot/modpc/Click() - . = ..() - if(.) + if(!screenmob.hud_used.hud_shown) + for(var/obj/item/I in R.held_items) + screenmob.client.screen -= I return - robot.modularInterface?.interact(robot) -/atom/movable/screen/robot/modpc/Destroy() - if(robot) - robot.interfaceButton = null - robot = null - return ..() - -/atom/movable/screen/robot/alerts - name = "Alert Panel" - icon = 'icons/hud/screen_ai.dmi' - icon_state = "alerts" - -/atom/movable/screen/robot/alerts/Click() - . = ..() - if(.) - return - var/mob/living/silicon/robot/borgo = usr - borgo.alert_control.ui_interact(borgo) + for(var/i in 1 to length(R.held_items)) + var/obj/item/I = R.held_items[i] + if(!I) + continue + var/atom/movable/screen/robot/module_slot/slot = screen_objects[HUD_KEY_CYBORG_MODULE(i)] + I.screen_loc = slot.screen_loc + screenmob.client.screen += I diff --git a/code/_onclick/hud/action_button.dm b/code/_onclick/hud/screen_objects/action_button.dm similarity index 97% rename from code/_onclick/hud/action_button.dm rename to code/_onclick/hud/screen_objects/action_button.dm index 88508c11e47..0782aabd5c0 100644 --- a/code/_onclick/hud/action_button.dm +++ b/code/_onclick/hud/screen_objects/action_button.dm @@ -31,10 +31,13 @@ viewer?.client?.screen -= src linked_action.viewers -= our_hud viewer.update_action_buttons() + our_hud.screen_objects -= hud_key + our_hud.screen_groups?[hud_group_key] -= src our_hud = null linked_action = null return ..() + /atom/movable/screen/movable/action_button/proc/can_use(mob/user) if(isobserver(user)) var/mob/dead/observer/dead_mob = user @@ -278,15 +281,17 @@ var/color_timer_id /atom/movable/screen/button_palette/Destroy() - if(our_hud) + if (our_hud) our_hud.mymob?.canon_client?.screen -= src - our_hud.toggle_palette = null + our_hud.screen_objects -= hud_key + our_hud.screen_groups?[hud_group_key] -= src our_hud = null return ..() /atom/movable/screen/button_palette/Initialize(mapload, datum/hud/hud_owner) . = ..() update_appearance() + set_hud(hud_owner) /atom/movable/screen/button_palette/proc/set_hud(datum/hud/our_hud) src.our_hud = our_hud @@ -419,6 +424,18 @@ GLOBAL_LIST_INIT(palette_removed_matrix, list(1.4,0,0,0, 0.7,0.4,0,0, 0.4,0,0.6, var/scroll_direction = 0 var/datum/hud/our_hud +/atom/movable/screen/palette_scroll/Initialize(mapload, datum/hud/hud_owner) + . = ..() + set_hud(hud_owner) + +/atom/movable/screen/palette_scroll/Destroy() + if (our_hud) + our_hud.mymob?.canon_client?.screen -= src + our_hud.screen_objects -= hud_key + our_hud.screen_groups?[hud_group_key] -= src + our_hud = null + return ..() + /atom/movable/screen/palette_scroll/proc/can_use(mob/user) if (isobserver(user)) var/mob/dead/observer/O = user @@ -458,26 +475,12 @@ GLOBAL_LIST_INIT(palette_removed_matrix, list(1.4,0,0,0, 0.7,0.4,0,0, 0.4,0,0.6, icon_state = "scroll_down" scroll_direction = 1 -/atom/movable/screen/palette_scroll/down/Destroy() - if(our_hud) - our_hud.mymob?.canon_client?.screen -= src - our_hud.palette_down = null - our_hud = null - return ..() - /atom/movable/screen/palette_scroll/up name = "Scroll Up" desc = "Click on this to scroll the actions above up" icon_state = "scroll_up" scroll_direction = -1 -/atom/movable/screen/palette_scroll/up/Destroy() - if(our_hud) - our_hud.mymob?.canon_client?.screen -= src - our_hud.palette_up = null - our_hud = null - return ..() - /// Exists so you have a place to put your buttons when you move them around /atom/movable/screen/action_landing name = "Button Space" diff --git a/code/_onclick/hud/screen_objects/ai.dm b/code/_onclick/hud/screen_objects/ai.dm new file mode 100644 index 00000000000..ffa18a01e68 --- /dev/null +++ b/code/_onclick/hud/screen_objects/ai.dm @@ -0,0 +1,250 @@ +/atom/movable/screen/ai + icon = 'icons/hud/screen_ai.dmi' + mouse_over_pointer = MOUSE_HAND_POINTER + +/atom/movable/screen/ai/Click() + if(isobserver(usr) || usr.incapacitated) + return TRUE + +/atom/movable/screen/ai/aicore + name = "AI core" + icon_state = "ai_core" + screen_loc = ui_ai_core + +/atom/movable/screen/ai/aicore/Click() + if(!isAI(usr)) + return + + var/mob/living/silicon/ai/AI = usr + AI.view_core() + +/atom/movable/screen/ai/camera_list + name = "Show Camera List" + icon_state = "camera" + screen_loc = ui_ai_camera_list + +/atom/movable/screen/ai/camera_list/Click() + if(..()) + return + var/mob/living/silicon/ai/AI = usr + AI.show_camera_list() + +/atom/movable/screen/ai/camera_track + name = "Track With Camera" + icon_state = "track" + screen_loc = ui_ai_track_with_camera + +/atom/movable/screen/ai/camera_track/Click() + if(..()) + return + var/mob/living/silicon/ai/AI = usr + AI.ai_camera_track() + +/atom/movable/screen/ai/camera_light + name = "Toggle Camera Light" + icon_state = "camera_light" + screen_loc = ui_ai_camera_light + +/atom/movable/screen/ai/camera_light/Click() + if(..()) + return + var/mob/living/silicon/ai/AI = usr + AI.toggle_camera_light() + +/atom/movable/screen/ai/modpc + name = "Messenger" + icon_state = "pda_send" + screen_loc = ui_ai_mod_int + +/atom/movable/screen/ai/modpc/Click() + if(..()) + return + var/mob/living/silicon/ai/AI = usr + AI.modularInterface?.interact(AI) + +/atom/movable/screen/ai/crew_monitor + name = "Crew Monitoring Console" + icon_state = "crew_monitor" + screen_loc = ui_ai_crew_monitor + +/atom/movable/screen/ai/crew_monitor/Click() + if(..()) + return + var/mob/living/silicon/ai/AI = usr + GLOB.crewmonitor.show(AI,AI) + +/atom/movable/screen/ai/crew_manifest + name = "Crew Manifest" + icon_state = "manifest" + screen_loc = ui_ai_crew_manifest + +/atom/movable/screen/ai/crew_manifest/Click() + if(..()) + return + var/mob/living/silicon/ai/AI = usr + AI.ai_roster() + +/atom/movable/screen/ai/alerts + name = "Show Alerts" + icon_state = "alerts" + screen_loc = ui_ai_alerts + +/atom/movable/screen/ai/alerts/Click() + if(..()) + return + var/mob/living/silicon/ai/AI = usr + AI.alert_control.ui_interact(AI) + +/atom/movable/screen/ai/announcement + name = "Make Vox Announcement" + icon_state = "announcement" + screen_loc = ui_ai_announcement + +/atom/movable/screen/ai/announcement/Click() + if(..()) + return + var/mob/living/silicon/ai/AI = usr + AI.announcement() + +/atom/movable/screen/ai/call_shuttle + name = "Call Emergency Shuttle" + icon_state = "call_shuttle" + screen_loc = ui_ai_shuttle + +/atom/movable/screen/ai/call_shuttle/Click() + if(..()) + return + var/mob/living/silicon/ai/AI = usr + AI.ai_call_shuttle() + +/atom/movable/screen/ai/state_laws + name = "State Laws" + icon_state = "state_laws" + screen_loc = ui_ai_state_laws + +/atom/movable/screen/ai/state_laws/Click() + if(..()) + return + var/mob/living/silicon/ai/AI = usr + AI.checklaws() + +/atom/movable/screen/ai/image_take + name = "Take Image" + icon_state = "take_picture" + screen_loc = ui_ai_take_picture + +/atom/movable/screen/ai/image_take/Click() + if(..()) + return + if(isAI(usr)) + var/mob/living/silicon/ai/AI = usr + AI.aicamera.toggle_camera_mode(usr) + else if(iscyborg(usr)) + var/mob/living/silicon/robot/R = usr + R.aicamera.toggle_camera_mode(usr) + +/atom/movable/screen/ai/image_view + name = "View Images" + icon_state = "view_images" + screen_loc = ui_ai_view_images + +/atom/movable/screen/ai/image_view/Click() + if(..()) + return + if(isAI(usr)) + var/mob/living/silicon/ai/AI = usr + AI.aicamera.viewpictures(usr) + +/atom/movable/screen/ai/sensors + name = "Sensor Augmentation" + icon_state = "ai_sensor" + screen_loc = ui_ai_sensor + +/atom/movable/screen/ai/sensors/Click() + if(..()) + return + var/mob/living/silicon/S = usr + S.toggle_sensors() + +/atom/movable/screen/ai/multicam + name = "Multicamera Mode" + icon_state = "multicam" + screen_loc = ui_ai_multicam + +/atom/movable/screen/ai/multicam/Click() + if(..()) + return + var/mob/living/silicon/ai/AI = usr + AI.toggle_multicam() + +/atom/movable/screen/ai/add_multicam + name = "New Camera" + icon_state = "new_cam" + screen_loc = ui_ai_add_multicam + +/atom/movable/screen/ai/add_multicam/Click() + if(..()) + return + var/mob/living/silicon/ai/AI = usr + AI.drop_new_multicam() + +/atom/movable/screen/ai/floor_indicator + icon_state = "zindicator" + screen_loc = ui_ai_floor_indicator + +/atom/movable/screen/ai/floor_indicator/Initialize(mapload, datum/hud/hud_owner) + . = ..() + if(istype(hud_owner)) + RegisterSignal(hud_owner, COMSIG_HUD_OFFSET_CHANGED, PROC_REF(update_z)) + update_z() + +/atom/movable/screen/ai/floor_indicator/proc/update_z(datum/hud/source) + SIGNAL_HANDLER + var/mob/living/silicon/ai/ai = get_mob() //if you use this for anyone else i will find you + if(isnull(ai)) + return + var/turf/locturf = isturf(ai.loc) ? get_turf(ai.eyeobj) : get_turf(ai) //must be a var cuz error + var/ai_z = locturf.z + var/text = "Level
[ai_z]" + if(SSmapping.level_trait(ai_z, ZTRAIT_STATION)) + text = "Floor
[ai_z - 1]" + else if (SSmapping.level_trait(ai_z, ZTRAIT_NOPHASE)) + text = "ERROR" + maptext = MAPTEXT_TINY_UNICODE("
[text]
") + +/atom/movable/screen/ai/go_up + name = "go up" + icon_state = "up" + screen_loc = ui_ai_godownup + +/atom/movable/screen/ai/go_up/Initialize(mapload) + . = ..() + register_context() + +/atom/movable/screen/ai/go_up/add_context(atom/source, list/context, obj/item/held_item, mob/user) + . = ..() + context[SCREENTIP_CONTEXT_LMB] = "Go up a floor" + return CONTEXTUAL_SCREENTIP_SET + +/atom/movable/screen/ai/go_up/Click(location,control,params) + var/mob/ai = get_mob() //the core + flick("uppressed",src) + if(!isturf(ai.loc) || usr != ai) //aicard and stuff + return + ai.up() + +/atom/movable/screen/ai/go_up/down + name = "go down" + icon_state = "down" + +/atom/movable/screen/ai/go_up/down/add_context(atom/source, list/context, obj/item/held_item, mob/user) + . = ..() + context[SCREENTIP_CONTEXT_LMB] = "Go down a floor" + return CONTEXTUAL_SCREENTIP_SET + +/atom/movable/screen/ai/go_up/down/Click(location,control,params) + var/mob/ai = get_mob() //the core + flick("downpressed",src) + if(!isturf(ai.loc) || usr != ai) //aicard and stuff + return + ai.down() diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/screen_objects/alert.dm similarity index 100% rename from code/_onclick/hud/alert.dm rename to code/_onclick/hud/screen_objects/alert.dm diff --git a/code/_onclick/hud/screen_objects/alien.dm b/code/_onclick/hud/screen_objects/alien.dm new file mode 100644 index 00000000000..d99cdc55b35 --- /dev/null +++ b/code/_onclick/hud/screen_objects/alien.dm @@ -0,0 +1,24 @@ +/atom/movable/screen/alien + icon = 'icons/hud/screen_alien.dmi' + +/atom/movable/screen/alien/leap + name = "toggle leap" + icon_state = "leap_off" + screen_loc = ui_alien_storage_r + +/atom/movable/screen/alien/leap/Click() + if(!isalienhunter(usr)) + return + var/mob/living/carbon/alien/adult/hunter/AH = usr + AH.toggle_leap() + +/atom/movable/screen/alien/plasma_display + name = "plasma stored" + icon_state = "power_display" + screen_loc = ui_alienplasmadisplay + +/atom/movable/screen/alien/alien_queen_finder + name = "queen sense" + desc = "Allows you to sense the general direction of your Queen." + icon_state = "queen_finder" + screen_loc = ui_alien_queen_finder diff --git a/code/_onclick/hud/screen_objects/blob.dm b/code/_onclick/hud/screen_objects/blob.dm new file mode 100644 index 00000000000..3f78d94854f --- /dev/null +++ b/code/_onclick/hud/screen_objects/blob.dm @@ -0,0 +1,164 @@ +/atom/movable/screen/blob + icon = 'icons/hud/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") + +/atom/movable/screen/blob/MouseExited() + closeToolTip(usr) + +/atom/movable/screen/blob/jump_to_node + name = "Jump to Node" + desc = "Moves your camera to a selected blob node." + icon_state = "ui_tonode" + screen_loc = ui_inventory + +/atom/movable/screen/blob/jump_to_node/Click() + if(!isovermind(usr)) + return FALSE + var/mob/eye/blob/blob = usr + blob.jump_to_node() + +/atom/movable/screen/blob/jump_to_core + name = "Jump to Core" + desc = "Moves your camera to your blob core." + icon_state = "ui_tocore" + screen_loc = ui_zonesel + +/atom/movable/screen/blob/jump_to_core/MouseEntered(location,control,params) + if(hud?.mymob && isovermind(hud.mymob)) + var/mob/eye/blob/B = hud.mymob + if(!B.placed) + name = "Place Blob Core" + desc = "Attempt to place your blob core at this location." + else + name = initial(name) + desc = initial(desc) + return ..() + +/atom/movable/screen/blob/jump_to_core/Click() + if(!isovermind(usr)) + return FALSE + var/mob/eye/blob/blob = usr + if(!blob.placed) + blob.place_blob_core(BLOB_NORMAL_PLACEMENT) + blob.transport_core() + +/atom/movable/screen/blob/blobbernaut + // Name and description get given their proper values on Initialize() + name = "Produce Blobbernaut (ERROR)" + desc = "Produces a strong, smart blobbernaut from a factory blob for (ERROR) resources.
The factory blob used will become fragile and unable to produce spores." + icon_state = "ui_blobbernaut" + screen_loc = ui_belt + +/atom/movable/screen/blob/blobbernaut/Initialize(mapload, datum/hud/hud_owner) + . = ..() + name = "Produce Blobbernaut ([BLOBMOB_BLOBBERNAUT_RESOURCE_COST])" + desc = "Produces a strong, smart blobbernaut from a factory blob for [BLOBMOB_BLOBBERNAUT_RESOURCE_COST] resources.
The factory blob used will become fragile and unable to produce spores." + +/atom/movable/screen/blob/blobbernaut/Click() + if(!isovermind(usr)) + return FALSE + var/mob/eye/blob/blob = usr + blob.create_blobbernaut() + +/atom/movable/screen/blob/resource_blob + // Name and description get given their proper values on Initialize() + name = "Produce Resource Blob (ERROR)" + desc = "Produces a resource blob for ERROR resources.
Resource blobs will give you resources every few seconds." + icon_state = "ui_resource" + screen_loc = ui_back + +/atom/movable/screen/blob/resource_blob/Initialize(mapload, datum/hud/hud_owner) + . = ..() + name = "Produce Resource Blob ([BLOB_STRUCTURE_RESOURCE_COST])" + desc = "Produces a resource blob for [BLOB_STRUCTURE_RESOURCE_COST] resources.
Resource blobs will give you resources every few seconds." + +/atom/movable/screen/blob/resource_blob/Click() + if(!isovermind(usr)) + return FALSE + var/mob/eye/blob/blob = usr + blob.create_special(BLOB_STRUCTURE_RESOURCE_COST, /obj/structure/blob/special/resource, BLOB_RESOURCE_MIN_DISTANCE, TRUE) + +/atom/movable/screen/blob/node_blob + // Name and description get given their proper values on Initialize() + name = "Produce Node Blob (ERROR)" + desc = "Produces a node blob for ERROR resources.
Node blobs will expand and activate nearby resource and factory blobs." + icon_state = "ui_node" + +/atom/movable/screen/blob/node_blob/Initialize(mapload, datum/hud/hud_owner) + . = ..() + name = "Produce Node Blob ([BLOB_STRUCTURE_NODE_COST])" + desc = "Produces a node blob for [BLOB_STRUCTURE_NODE_COST] resources.
Node blobs will expand and activate nearby resource and factory blobs." + +/atom/movable/screen/blob/node_blob/Click() + if(!isovermind(usr)) + return FALSE + var/mob/eye/blob/blob = usr + blob.create_special(BLOB_STRUCTURE_NODE_COST, /obj/structure/blob/special/node, BLOB_NODE_MIN_DISTANCE, FALSE) + +/atom/movable/screen/blob/factory_blob + // Name and description get given their proper values on Initialize() + name = "Produce Factory Blob (ERROR)" + desc = "Produces a factory blob for ERROR resources.
Factory blobs will produce spores every few seconds." + icon_state = "ui_factory" + +/atom/movable/screen/blob/factory_blob/Initialize(mapload, datum/hud/hud_owner) + . = ..() + name = "Produce Factory Blob ([BLOB_STRUCTURE_FACTORY_COST])" + desc = "Produces a factory blob for [BLOB_STRUCTURE_FACTORY_COST] resources.
Factory blobs will produce spores every few seconds." + +/atom/movable/screen/blob/factory_blob/Click() + if(!isovermind(usr)) + return FALSE + var/mob/eye/blob/blob = usr + blob.create_special(BLOB_STRUCTURE_FACTORY_COST, /obj/structure/blob/special/factory, BLOB_FACTORY_MIN_DISTANCE, TRUE) + +/atom/movable/screen/blob/readapt_strain + // Description gets given its proper values on Initialize() + name = "Readapt Strain" + desc = "Allows you to choose a new strain from ERROR random choices for ERROR resources." + icon_state = "ui_chemswap" + screen_loc = ui_storage1 + +/atom/movable/screen/blob/readapt_strain/MouseEntered(location,control,params) + if(hud?.mymob && isovermind(hud.mymob)) + var/mob/eye/blob/B = hud.mymob + if(B.free_strain_rerolls) + name = "[initial(name)] (FREE)" + desc = "Randomly rerolls your strain for free." + else + name = "[initial(name)] ([BLOB_POWER_REROLL_COST])" + desc = "Allows you to choose a new strain from [BLOB_POWER_REROLL_CHOICES] random choices for [BLOB_POWER_REROLL_COST] resources." + return ..() + +/atom/movable/screen/blob/readapt_strain/Click() + if(isovermind(usr)) + var/mob/eye/blob/B = usr + B.strain_reroll() + +/atom/movable/screen/blob/relocate_core + // Name and description get given their proper values on Initialize() + name = "Relocate Core (ERROR)" + desc = "Swaps a node and your core for ERROR resources." + icon_state = "ui_swap" + screen_loc = ui_storage2 + +/atom/movable/screen/blob/relocate_core/Initialize(mapload, datum/hud/hud_owner) + . = ..() + name = "Relocate Core ([BLOB_POWER_RELOCATE_COST])" + desc = "Swaps a node and your core for [BLOB_POWER_RELOCATE_COST] resources." + +/atom/movable/screen/blob/relocate_core/Click() + if(isovermind(usr)) + var/mob/eye/blob/B = usr + B.relocate_core() + +/atom/movable/screen/blob/blob_power + name = "blob power" + icon_state = "block" + screen_loc = ui_health + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + plane = ABOVE_HUD_PLANE diff --git a/code/_onclick/hud/credits.dm b/code/_onclick/hud/screen_objects/credits.dm similarity index 100% rename from code/_onclick/hud/credits.dm rename to code/_onclick/hud/screen_objects/credits.dm diff --git a/code/_onclick/hud/fullscreen.dm b/code/_onclick/hud/screen_objects/fullscreen.dm similarity index 100% rename from code/_onclick/hud/fullscreen.dm rename to code/_onclick/hud/screen_objects/fullscreen.dm diff --git a/code/_onclick/hud/screen_objects/ghost.dm b/code/_onclick/hud/screen_objects/ghost.dm new file mode 100644 index 00000000000..532817e558a --- /dev/null +++ b/code/_onclick/hud/screen_objects/ghost.dm @@ -0,0 +1,149 @@ +/atom/movable/screen/ghost + icon = 'icons/hud/screen_ghost.dmi' + mouse_over_pointer = MOUSE_HAND_POINTER + +/atom/movable/screen/ghost/MouseEntered(location, control, params) + . = ..() + flick(icon_state + "_anim", src) + +/atom/movable/screen/ghost/spawners_menu + name = "Spawners menu" + icon_state = "spawners" + screen_loc = ui_ghost_spawners_menu + +/atom/movable/screen/ghost/spawners_menu/Click() + var/mob/dead/observer/observer = usr + observer.open_spawners_menu() + +/atom/movable/screen/ghost/orbit + name = "Orbit" + icon_state = "orbit" + screen_loc = ui_ghost_orbit + +/atom/movable/screen/ghost/orbit/Click() + GLOB.orbit_menu.show(usr) + +/atom/movable/screen/ghost/reenter_corpse + name = "Reenter corpse" + icon_state = "reenter_corpse" + screen_loc = ui_ghost_reenter_corpse + +/atom/movable/screen/ghost/reenter_corpse/Click() + var/mob/dead/observer/G = usr + G.reenter_corpse() + +/atom/movable/screen/ghost/dnr + name = "Do Not Resuscitate" + icon_state = "dnr" + screen_loc = ui_ghost_dnr + +/atom/movable/screen/ghost/dnr/Click() + var/mob/dead/observer/dnring = usr + dnring.do_not_resuscitate() + +/atom/movable/screen/ghost/teleport + name = "Teleport" + icon_state = "teleport" + screen_loc = ui_ghost_teleport + +/atom/movable/screen/ghost/teleport/Click() + var/mob/dead/observer/G = usr + G.dead_tele() + +/atom/movable/screen/ghost/settings + name = "Ghost Settings" + icon_state = "settings" + screen_loc = ui_ghost_settings + +/atom/movable/screen/ghost/settings/MouseEntered(location, control, params) + . = ..() + flick(icon_state + "_anim", src) + +/atom/movable/screen/ghost/settings/Click() + GLOB.ghost_menu.ui_interact(usr) + +/atom/movable/screen/ghost/minigames_menu + name ="Minigames" + icon_state = "minigames" + screen_loc = ui_ghost_minigames + +/atom/movable/screen/ghost/minigames_menu/Click() + var/mob/dead/observer/observer = usr + observer.open_minigames_menu() + +/atom/movable/screen/ghost/hudbox + icon_state = "smallbox" + abstract_type = /atom/movable/screen/ghost/hudbox + /// Icon state used for the overlay representing this hudbox + var/hud_icon_state + /// The flag this hudbox toggles + var/relevant_flag + +/atom/movable/screen/ghost/hudbox/update_overlays() + . = ..() + . += hud_icon_state + +/atom/movable/screen/ghost/hudbox/update_icon_state() + . = ..() + var/mob/dead/observer/observer = hud?.mymob + if(!istype(observer)) + return + + icon_state = "smallbox[is_active(observer) ? "_active" : ""]" + +/atom/movable/screen/ghost/hudbox/proc/is_active(mob/dead/observer/observer) + return (observer.ghost_hud_flags & relevant_flag) + +/atom/movable/screen/ghost/hudbox/Click(location, control, params) + var/mob/dead/observer/observer = usr + switch(relevant_flag) + if(GHOST_DARKNESS_LEVEL) + observer.toggle_darkness() + if(GHOST_TRAY) + observer.tray_view() + else + observer.toggle_ghost_hud_flag(relevant_flag) + + update_appearance(UPDATE_ICON) + +/atom/movable/screen/ghost/hudbox/health_scanner + name = "Health Scanner" + desc = "Toggles your ability to health scan mobs on click." + hud_icon_state = "health_vision" + relevant_flag = GHOST_HEALTH + +/atom/movable/screen/ghost/hudbox/chem_scanner + name = "Chem Scanner" + desc = "Toggles your ability to chemical scan mobs on click." + hud_icon_state = "chem_vision" + relevant_flag = GHOST_CHEM + +/atom/movable/screen/ghost/hudbox/gas_scanner + name = "Gas Scanner" + desc = "Toggles your ability to gas scan objects on click." + hud_icon_state = "atmos_vision" + relevant_flag = GHOST_GAS + +/atom/movable/screen/ghost/hudbox/ghost + name = "Ghost Vision" + desc = "Toggles whether you can see other ghosts." + hud_icon_state = "ghost_vision" + relevant_flag = GHOST_VISION + +/atom/movable/screen/ghost/hudbox/data_huds + name = "Data HUDs" + desc = "Toggles the display of data HUDs (health, security, diagnostics, etc)." + hud_icon_state = "data_vision" + relevant_flag = GHOST_DATA_HUDS + +/atom/movable/screen/ghost/hudbox/tray_icon + name = "Tray View" + desc = "Shows the t-ray view of the area around your ghost." + hud_icon_state = "tray_vision" + relevant_flag = GHOST_TRAY + +/atom/movable/screen/ghost/hudbox/darkness_level + name = "Darkness Level" + desc = "Cycles through different darkness levels for ghost vision." + hud_icon_state = "darkness_vision" + relevant_flag = GHOST_DARKNESS_LEVEL diff --git a/code/_onclick/hud/screen_objects/guardian.dm b/code/_onclick/hud/screen_objects/guardian.dm new file mode 100644 index 00000000000..41282bc45ed --- /dev/null +++ b/code/_onclick/hud/screen_objects/guardian.dm @@ -0,0 +1,68 @@ +/atom/movable/screen/guardian + icon = 'icons/hud/guardian.dmi' + mouse_over_pointer = MOUSE_HAND_POINTER + +/atom/movable/screen/guardian/manifest + name = "Manifest" + desc = "Spring forth into battle!" + icon_state = "manifest" + +/atom/movable/screen/guardian/manifest/Click() + if(isguardian(usr)) + var/mob/living/basic/guardian/user = usr + user.manifest() + +/atom/movable/screen/guardian/recall + name = "Recall" + desc = "Return to your user." + icon_state = "recall" + +/atom/movable/screen/guardian/recall/Click() + if(isguardian(usr)) + var/mob/living/basic/guardian/user = usr + user.recall() + +/atom/movable/screen/guardian/toggle_mode + name = "Toggle Mode" + desc = "Switch between ability modes." + icon_state = "toggle" + +/atom/movable/screen/guardian/toggle_mode/Click() + if(isguardian(usr)) + var/mob/living/basic/guardian/user = usr + user.toggle_modes() + +/atom/movable/screen/guardian/toggle_mode/inactive + icon_state = "notoggle" //greyed out so it doesn't look like it'll work + +/atom/movable/screen/guardian/toggle_mode/assassin + name = "Toggle Stealth" + desc = "Enter or exit stealth." + icon_state = "stealth" + +/atom/movable/screen/guardian/toggle_mode/gases + name = "Toggle Gas" + desc = "Switch between possible gases." + icon_state = "gases" + +/atom/movable/screen/guardian/communicate + name = "Communicate" + desc = "Communicate telepathically with your user." + icon_state = "communicate" + screen_loc = ui_back + +/atom/movable/screen/guardian/communicate/Click() + if(isguardian(usr)) + var/mob/living/basic/guardian/user = usr + user.communicate() + +/atom/movable/screen/guardian/toggle_light + name = "Toggle Light" + desc = "Glow like star dust." + icon_state = "light" + screen_loc = ui_inventory + +/atom/movable/screen/guardian/toggle_light/Click() + if(isguardian(usr)) + var/mob/living/basic/guardian/user = usr + user.toggle_light() diff --git a/code/_onclick/hud/screen_objects/human.dm b/code/_onclick/hud/screen_objects/human.dm new file mode 100644 index 00000000000..b69ceb2143e --- /dev/null +++ b/code/_onclick/hud/screen_objects/human.dm @@ -0,0 +1,77 @@ +/atom/movable/screen/human + icon = 'icons/hud/screen_midnight.dmi' + +/atom/movable/screen/human/toggle + name = "toggle" + icon_state = "toggle" + base_icon_state = "toggle" + mouse_over_pointer = MOUSE_HAND_POINTER + screen_loc = ui_inventory + +/atom/movable/screen/human/toggle/Click() + var/mob/targetmob = usr + + if(isobserver(usr)) + if(ishuman(usr.client.eye) && (usr.client.eye != usr)) + var/mob/M = usr.client.eye + targetmob = M + + if(usr.hud_used.inventory_shown && targetmob.hud_used) + usr.hud_used.inventory_shown = FALSE + usr.client.screen -= targetmob.hud_used.screen_groups[HUD_GROUP_TOGGLEABLE_INVENTORY] + else + usr.hud_used.inventory_shown = TRUE + usr.client.screen += targetmob.hud_used.screen_groups[HUD_GROUP_TOGGLEABLE_INVENTORY] + + targetmob.hud_used.hidden_inventory_update(usr) + update_appearance() + +/atom/movable/screen/human/toggle/update_icon_state() + icon_state = "[base_icon_state][hud?.inventory_shown ? "_active" : ""]" + return ..() + +/atom/movable/screen/ling + icon = 'icons/hud/screen_changeling.dmi' + +/atom/movable/screen/ling/chems + name = "chemical storage" + icon_state = "power_display" + screen_loc = ui_lingchemdisplay + ///Boolean on whether a mouse is being hovered over us right now. + var/hovering = FALSE + +/atom/movable/screen/ling/chems/Click(location, control, params) + . = ..() + to_chat(usr, span_notice("Shows you how many chemicals you have. While hovering over this, it will show the max amount of chemicals you can hold.")) + +/atom/movable/screen/ling/chems/MouseEntered(location,control,params) + if(usr != get_mob()) + return + var/datum/antagonist/changeling/antagonist_datum = IS_CHANGELING(hud.mymob) + if(!antagonist_datum) + return + . = ..() + hovering = TRUE + antagonist_datum.update_chemical_hud() + +/atom/movable/screen/ling/chems/MouseExited(location, control, params) + if(usr != get_mob()) + return + var/datum/antagonist/changeling/antagonist_datum = IS_CHANGELING(hud.mymob) + if(!antagonist_datum) + return + . = ..() + hovering = FALSE + antagonist_datum.update_chemical_hud(antagonist_datum.chem_charges) + +/atom/movable/screen/ling/sting + name = "current sting" + screen_loc = ui_lingstingdisplay + invisibility = INVISIBILITY_ABSTRACT + mouse_over_pointer = MOUSE_HAND_POINTER + +/atom/movable/screen/ling/sting/Click() + if(isobserver(usr)) + return + var/mob/living/carbon/carbon_user = usr + carbon_user.unset_sting() diff --git a/code/_onclick/hud/map_popups.dm b/code/_onclick/hud/screen_objects/map_popups.dm similarity index 100% rename from code/_onclick/hud/map_popups.dm rename to code/_onclick/hud/screen_objects/map_popups.dm diff --git a/code/_onclick/hud/map_view.dm b/code/_onclick/hud/screen_objects/map_view.dm similarity index 100% rename from code/_onclick/hud/map_view.dm rename to code/_onclick/hud/screen_objects/map_view.dm diff --git a/code/_onclick/hud/movable_screen_objects.dm b/code/_onclick/hud/screen_objects/movable_screen_objects.dm similarity index 100% rename from code/_onclick/hud/movable_screen_objects.dm rename to code/_onclick/hud/screen_objects/movable_screen_objects.dm diff --git a/code/_onclick/hud/screen_objects/new_player.dm b/code/_onclick/hud/screen_objects/new_player.dm new file mode 100644 index 00000000000..5a17abfc5d9 --- /dev/null +++ b/code/_onclick/hud/screen_objects/new_player.dm @@ -0,0 +1,724 @@ +#define SHUTTER_MOVEMENT_DURATION 0.4 SECONDS +#define SHUTTER_WAIT_DURATION 0.2 SECONDS + +/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 + +///Set the HUD in New, as lobby screens are made before Atoms are Initialized. +/atom/movable/screen/lobby/New(loc, datum/hud/our_hud, ...) + set_new_hud(our_hud) + return ..() + +///Run sleeping actions after initialize +/atom/movable/screen/lobby/proc/SlowInit() + return + +///Animates moving the button off-screen +/atom/movable/screen/lobby/proc/collapse_button() + SIGNAL_HANDLER + //wait for the shutter to come down + animate(src, transform = transform, time = SHUTTER_MOVEMENT_DURATION + SHUTTER_WAIT_DURATION) + //then pull the buttons up with the shutter + animate(transform = transform.Translate(x = 0, y = 146), time = SHUTTER_MOVEMENT_DURATION, easing = CUBIC_EASING|EASE_IN) + +///Animates moving the button back into place +/atom/movable/screen/lobby/proc/expand_button() + SIGNAL_HANDLER + //the buttons are off-screen, so we sync them up to come down with the shutter + animate(src, transform = matrix(), time = SHUTTER_MOVEMENT_DURATION, easing = CUBIC_EASING|EASE_OUT) + +/atom/movable/screen/lobby/background + icon = 'icons/hud/lobby/background.dmi' + icon_state = "background" + layer = LOBBY_BACKGROUND_LAYER + screen_loc = "TOP,CENTER:-61" + +/atom/movable/screen/lobby/button + mouse_over_pointer = MOUSE_HAND_POINTER + ///Is the button currently enabled? + VAR_PROTECTED/enabled = TRUE + ///Is the button currently being hovered over with the mouse? + var/highlighted = FALSE + ///Should this button play the select sound? + var/select_sound_play = TRUE + +/atom/movable/screen/lobby/button/Click(location, control, params) + if(usr != get_mob()) + return + + if(!usr.client || usr.client.interviewee) + return + + . = ..() + + 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(usr != get_mob()) + return + + if(!usr.client || usr.client.interviewee) + return + + . = ..() + highlighted = TRUE + update_appearance(UPDATE_ICON) + +/atom/movable/screen/lobby/button/MouseExited() + if(usr != get_mob()) + return + + if(!usr.client || usr.client.interviewee) + return + + . = ..() + highlighted = FALSE + update_appearance(UPDATE_ICON) + +/atom/movable/screen/lobby/button/update_icon(updates) + . = ..() + if(!enabled) + icon_state = "[base_icon_state]_disabled" + return + if(highlighted) + icon_state = "[base_icon_state]_highlighted" + return + icon_state = base_icon_state + +///Updates the button's status: TRUE to enable interaction with the button, FALSE to disable +/atom/movable/screen/lobby/button/proc/set_button_status(status) + if(status == enabled) + return FALSE + enabled = status + update_appearance(UPDATE_ICON) + mouse_over_pointer = enabled ? MOUSE_HAND_POINTER : MOUSE_INACTIVE_POINTER + return TRUE + +///Prefs menu +/atom/movable/screen/lobby/button/character_setup + name = "View Character Setup" + screen_loc = "TOP:-70,CENTER:-54" + icon = 'icons/hud/lobby/character_setup.dmi' + icon_state = "character_setup_disabled" + base_icon_state = "character_setup" + enabled = FALSE + +/atom/movable/screen/lobby/button/character_setup/Initialize(mapload, datum/hud/hud_owner) + . = ..() + // We need IconForge and the assets to be ready before allowing the menu to open + if(SSearly_assets.initialized == INITIALIZATION_INNEW_REGULAR || SSatoms.initialized == INITIALIZATION_INNEW_REGULAR) + flick("[base_icon_state]_enabled", src) + set_button_status(TRUE) + else + set_button_status(FALSE) + RegisterSignal(SSearly_assets, COMSIG_SUBSYSTEM_POST_INITIALIZE, PROC_REF(enable_character_setup)) + RegisterSignal(SSatoms, COMSIG_SUBSYSTEM_POST_INITIALIZE, PROC_REF(enable_character_setup)) + +/atom/movable/screen/lobby/button/character_setup/Click(location, control, params) + . = ..() + if(!.) + return + + var/datum/preferences/preferences = hud.mymob.canon_client.prefs + preferences.current_window = PREFERENCE_TAB_CHARACTER_PREFERENCES + preferences.update_static_data(usr) + preferences.ui_interact(usr) + +/atom/movable/screen/lobby/button/character_setup/proc/enable_character_setup() + SIGNAL_HANDLER + flick("[base_icon_state]_enabled", src) + set_button_status(TRUE) + UnregisterSignal(SSearly_assets, COMSIG_SUBSYSTEM_POST_INITIALIZE) + UnregisterSignal(SSatoms, COMSIG_SUBSYSTEM_POST_INITIALIZE) + +///Button that appears before the game has started +/atom/movable/screen/lobby/button/ready + name = "Toggle Readiness" + screen_loc = "TOP:-8,CENTER:-65" + icon = 'icons/hud/lobby/ready.dmi' + icon_state = "not_ready" + base_icon_state = "not_ready" + +/atom/movable/screen/lobby/button/ready/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(hide_ready_button)) + if(GAME_STATE_SETTING_UP) + set_button_status(FALSE) + RegisterSignal(SSticker, COMSIG_TICKER_ERROR_SETTING_UP, PROC_REF(show_ready_button)) + else + set_button_status(FALSE) + +/atom/movable/screen/lobby/button/ready/proc/hide_ready_button() + SIGNAL_HANDLER + set_button_status(FALSE) + UnregisterSignal(SSticker, COMSIG_TICKER_ENTER_SETTING_UP) + RegisterSignal(SSticker, COMSIG_TICKER_ERROR_SETTING_UP, PROC_REF(show_ready_button)) + +/atom/movable/screen/lobby/button/ready/proc/show_ready_button() + SIGNAL_HANDLER + set_button_status(TRUE) + UnregisterSignal(SSticker, COMSIG_TICKER_ERROR_SETTING_UP) + RegisterSignal(SSticker, COMSIG_TICKER_ENTER_SETTING_UP, PROC_REF(hide_ready_button)) + +/atom/movable/screen/lobby/button/ready/Click(location, control, params) + . = ..() + if(!.) + return + var/mob/dead/new_player/new_player = hud.mymob + + // switch based on the user, if they aren't ready then we change them to ready, and vice versa + if(new_player.ready == PLAYER_NOT_READY) + new_player.auto_deadmin_on_ready_or_latejoin() + new_player.ready = PLAYER_READY_TO_PLAY + base_icon_state = "ready" + else + 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 + name = "Join Game" + screen_loc = "TOP:-13,CENTER:-58" + icon = 'icons/hud/lobby/join.dmi' + icon_state = "" //Default to not visible + base_icon_state = "join_game" + enabled = null // set in init + +/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) + RegisterSignal(SSticker, COMSIG_TICKER_ERROR_SETTING_UP, PROC_REF(hide_join_button)) + else + set_button_status(TRUE) + +/atom/movable/screen/lobby/button/join/Click(location, control, params) + . = ..() + if(!.) + return + + if(!SSticker?.IsRoundInProgress()) + to_chat(hud.mymob, span_boldwarning("The round is either not ready, or has already finished...")) + return + + //Determines Relevent Population Cap + var/relevant_cap + var/hard_popcap = CONFIG_GET(number/hard_popcap) + var/extreme_popcap = CONFIG_GET(number/extreme_popcap) + if(hard_popcap && extreme_popcap) + relevant_cap = min(hard_popcap, extreme_popcap) + else + relevant_cap = max(hard_popcap, extreme_popcap) + + var/mob/dead/new_player/new_player = hud.mymob + + if(SSticker.queued_players.len || (relevant_cap && living_player_count() >= relevant_cap && !(ckey(new_player.key) in GLOB.admin_datums))) + to_chat(new_player, span_danger("[CONFIG_GET(string/hard_popcap_message)]")) + + var/queue_position = SSticker.queued_players.Find(new_player) + if(queue_position == 1) + to_chat(new_player, span_notice("You are next in line to join the game. You will be notified when a slot opens up.")) + else if(queue_position) + to_chat(new_player, span_notice("There are [queue_position-1] players in front of you in the queue to join the game.")) + else + SSticker.queued_players += new_player + to_chat(new_player, span_notice("You have been added to the queue to join the game. Your position in queue is [SSticker.queued_players.len].")) + return + + new_player.auto_deadmin_on_ready_or_latejoin() + + if(!LAZYACCESS(params2list(params), CTRL_CLICK)) + GLOB.latejoin_menu.ui_interact(new_player) + else + to_chat(new_player, span_warning("Opening emergency fallback late join menu! If THIS doesn't show, ahelp immediately!")) + GLOB.latejoin_menu.fallback_ui(new_player) + + +/atom/movable/screen/lobby/button/join/proc/show_join_button() + SIGNAL_HANDLER + set_button_status(TRUE) + UnregisterSignal(SSticker, COMSIG_TICKER_ENTER_SETTING_UP) + RegisterSignal(SSticker, COMSIG_TICKER_ERROR_SETTING_UP, PROC_REF(hide_join_button)) + +/atom/movable/screen/lobby/button/join/proc/hide_join_button() + SIGNAL_HANDLER + set_button_status(FALSE) + UnregisterSignal(SSticker, COMSIG_TICKER_ERROR_SETTING_UP) + RegisterSignal(SSticker, COMSIG_TICKER_ENTER_SETTING_UP, PROC_REF(show_join_button)) + +/atom/movable/screen/lobby/button/observe + name = "Observe" + screen_loc = "TOP:-40,CENTER:-54" + icon = 'icons/hud/lobby/observe.dmi' + icon_state = "observe_disabled" + base_icon_state = "observe" + enabled = null // set in init + +/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) + . = ..() + if(!.) + return + var/mob/dead/new_player/new_player = hud.mymob + new_player.make_me_an_observer() + +/atom/movable/screen/lobby/button/observe/proc/enable_observing() + SIGNAL_HANDLER + flick("[base_icon_state]_enabled", src) + set_button_status(TRUE) + UnregisterSignal(SSticker, COMSIG_TICKER_ENTER_PREGAME) + +//Subtype the bottom buttons away so the collapse/expand shutter goes behind them +/atom/movable/screen/lobby/button/bottom + layer = LOBBY_BOTTOM_BUTTON_LAYER + icon = 'icons/hud/lobby/bottom_buttons.dmi' + +/atom/movable/screen/lobby/button/bottom/settings + name = "View Game Preferences" + icon_state = "settings_disabled" + base_icon_state = "settings" + screen_loc = "TOP:-122,CENTER:+29" + enabled = FALSE + +/atom/movable/screen/lobby/button/bottom/settings/Initialize(mapload, datum/hud/hud_owner) + . = ..() + // We need IconForge and the assets to be ready before allowing the menu to open + if(SSearly_assets.initialized == INITIALIZATION_INNEW_REGULAR || SSatoms.initialized == INITIALIZATION_INNEW_REGULAR) + set_button_status(TRUE) + else + set_button_status(FALSE) + RegisterSignal(SSearly_assets, COMSIG_SUBSYSTEM_POST_INITIALIZE, PROC_REF(enable_settings)) + RegisterSignal(SSatoms, COMSIG_SUBSYSTEM_POST_INITIALIZE, PROC_REF(enable_settings)) + +/atom/movable/screen/lobby/button/bottom/settings/Click(location, control, params) + . = ..() + if(!.) + return + + var/datum/preferences/preferences = hud.mymob.canon_client.prefs + preferences.current_window = PREFERENCE_TAB_GAME_PREFERENCES + preferences.update_static_data(usr) + preferences.ui_interact(usr) + +/atom/movable/screen/lobby/button/bottom/settings/proc/enable_settings() + SIGNAL_HANDLER + set_button_status(TRUE) + UnregisterSignal(SSearly_assets, COMSIG_SUBSYSTEM_POST_INITIALIZE) + UnregisterSignal(SSatoms, COMSIG_SUBSYSTEM_POST_INITIALIZE) + +/atom/movable/screen/lobby/button/bottom/changelog_button + name = "View Changelog" + icon_state = "changelog" + base_icon_state = "changelog" + screen_loc ="TOP:-122,CENTER:+57" + +/atom/movable/screen/lobby/button/bottom/changelog_button/Click(location, control, params) + . = ..() + usr.client?.changelog() + +/atom/movable/screen/lobby/button/bottom/crew_manifest + name = "View Crew Manifest" + icon_state = "crew_manifest" + base_icon_state = "crew_manifest" + screen_loc = "TOP:-122,CENTER:+2" + +/atom/movable/screen/lobby/button/bottom/crew_manifest/Click(location, control, params) + . = ..() + if(!.) + return + var/mob/dead/new_player/new_player = hud.mymob + new_player.ViewManifest() + +/atom/movable/screen/lobby/button/bottom/poll + name = "View Available Polls" + icon_state = "poll" + base_icon_state = "poll" + screen_loc = "TOP:-122,CENTER:-26" + ///Whether the button should have a New Poll notification overlay + var/new_poll = FALSE + +/atom/movable/screen/lobby/button/bottom/poll/SlowInit(mapload) + . = ..() + if(!usr) + return + var/mob/dead/new_player/new_player = usr + if(is_guest_key(new_player.key)) + set_button_status(FALSE) + return + if(!SSdbcore.Connect()) + set_button_status(FALSE) + return + var/isadmin = FALSE + if(new_player.client?.holder) + isadmin = TRUE + var/datum/db_query/query_get_new_polls = SSdbcore.NewQuery({" + SELECT id FROM [format_table_name("poll_question")] + WHERE (adminonly = 0 OR :isadmin = 1) + AND Now() BETWEEN starttime AND endtime + AND deleted = 0 + AND id NOT IN ( + SELECT pollid FROM [format_table_name("poll_vote")] + WHERE ckey = :ckey + AND deleted = 0 + ) + AND id NOT IN ( + SELECT pollid FROM [format_table_name("poll_textreply")] + WHERE ckey = :ckey + AND deleted = 0 + ) + "}, list("isadmin" = isadmin, "ckey" = new_player.ckey)) + if(!query_get_new_polls.Execute()) + qdel(query_get_new_polls) + set_button_status(FALSE) + return + if(query_get_new_polls.NextRow()) + new_poll = TRUE + else + new_poll = FALSE + update_appearance(UPDATE_OVERLAYS) + qdel(query_get_new_polls) + if(QDELETED(new_player)) + set_button_status(FALSE) + return + +/atom/movable/screen/lobby/button/bottom/poll/update_overlays() + . = ..() + if(new_poll) + . += mutable_appearance('icons/hud/lobby/poll_overlay.dmi', "new_poll") + +/atom/movable/screen/lobby/button/bottom/poll/Click(location, control, params) + . = ..() + if(!.) + return + 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' + icon_state = "collapse" + base_icon_state = "collapse" + layer = LOBBY_BELOW_MENU_LAYER + 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(!.) + return + + if(!istype(hud, /datum/hud/new_player)) + return + var/datum/hud/new_player/our_hud = hud + base_icon_state = our_hud.menu_hud_status ? "expand" : "collapse" + name = "[our_hud.menu_hud_status ? "Expand" : "Collapse"] Lobby Menu" + set_button_status(FALSE) + + //get the shutter object used by our hud + var/atom/movable/screen/lobby/shutter/menu_shutter = locate(/atom/movable/screen/lobby/shutter) in hud.screen_groups[HUD_GROUP_STATIC] + + //animate the shutter + menu_shutter.setup_shutter_animation() + //animate bottom buttons' movement + if(our_hud.menu_hud_status) + collapse_menu() + else + expand_menu() + our_hud.menu_hud_status = !our_hud.menu_hud_status + + //re-enable clicking the button when the shutter animation finishes + //we use sleep here so it can work during game setup, as addtimer would not work until the game would finish setting up + 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.is_ready_to_play() ? "" : "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() + SEND_SIGNAL(hud, COMSIG_HUD_LOBBY_COLLAPSED) + //wait for the shutter to come down + 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' + icon_state = "shutter" + base_icon_state = "shutter" + screen_loc = "TOP:+143,CENTER:-73" //"home" position is off-screen + layer = LOBBY_SHUTTER_LAYER + always_shown = TRUE + +///Sets up the shutter pulling down and up. It's the same animation for both collapsing and expanding the menu. +/atom/movable/screen/lobby/shutter/proc/setup_shutter_animation() + //bring down the shutter + animate(src, transform = transform.Translate(x = 0, y = -143), time = SHUTTER_MOVEMENT_DURATION, easing = CUBIC_EASING|EASE_OUT) + + //wait a little bit before bringing the shutter up + animate(transform = transform, time = SHUTTER_WAIT_DURATION) + + //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/cartoon_sfx/cartoon_splat.ogg', volume = 50)) + SSticker.start_immediately = TRUE + if(SSticker.current_state == GAME_STATE_STARTUP) + to_chat(usr, span_admin("The server is still setting up, but the round will be started as soon as possible.")) + +#define OVERLAY_X_DIFF 12 +#define OVERLAY_Y_DIFF 5 + +///Lobby screen that appears before the game has started showing how many players there are and who is ready. +/atom/movable/screen/lobby/new_player_info + name = "New Player Info" + screen_loc = "EAST-3,CENTER:140" + icon = 'icons/hud/lobby/newplayer.dmi' + icon_state = null //we only show up when we get update appearance called, cause we need our overlay to not look bad. + base_icon_state = "newplayer" + maptext_height = 75 + maptext_width = 80 + maptext_x = OVERLAY_X_DIFF + maptext_y = OVERLAY_Y_DIFF + + ///Boolean on whether or not we should have our static overlay, so we 'turn' the TV off when collapsing. + var/show_static = TRUE + ///Static mutable appearance of a job icon we're displaying on the TV for overflow job. + var/static/mutable_appearance/job_overlay + +/atom/movable/screen/lobby/new_player_info/Initialize(mapload, datum/hud/hud_owner) + . = ..() + START_PROCESSING(SSnewplayer_info, src) + update_text() + + //only go if the station trait is selected, otherwise it'll show "Assistant" every round. + var/datum/station_trait/overflow_job_bureaucracy/overflow_job = locate() in SSstation.station_traits + if(overflow_job && isnull(job_overlay)) + var/icon/job_icon = get_job_hud_icon(SSjob.overflow_role) + if(isnull(job_icon)) + stack_trace("[SSjob.overflow_role::title] was selected as the Job Overflow but has no icon!") + else + job_icon.Scale(ICON_SIZE_X / 2, ICON_SIZE_X / 2) + job_overlay = mutable_appearance(job_icon, offset_spokesman = src, alpha = 120, layer = src.layer+0.02) + var/matrix/job_matrix = matrix() + job_matrix.Translate(6, 14) //this is completely arbitruary just what I thought looked good. + job_overlay.transform = job_matrix + + update_appearance(UPDATE_ICON) + +/atom/movable/screen/lobby/new_player_info/Destroy() + STOP_PROCESSING(SSnewplayer_info, src) + return ..() + +/atom/movable/screen/lobby/new_player_info/MouseEntered(location, control, params) + . = ..() + if(QDELETED(src) || isnull(job_overlay)) + return + openToolTip(usr, src, params, title = "[SSjob.overflow_role::title] overflow", content = "The overflow for the round has been set as [SSjob.overflow_role::title].") + +/atom/movable/screen/lobby/new_player_info/MouseExited() + closeToolTip(usr) + return ..() + +/atom/movable/screen/lobby/new_player_info/update_icon_state() + . = ..() + icon_state = base_icon_state + +/atom/movable/screen/lobby/new_player_info/update_overlays() + . = ..() + . += mutable_appearance(icon, "[base_icon_state]_overlay", layer = src.layer+0.01) + if(!show_static) + return . + if(job_overlay) + . += job_overlay + . += mutable_appearance(icon, "static_base", alpha = 20, layer = src.layer+0.03) + //we have this in a separate file because `generate_icon_alpha_mask` puts lighting even on non-existent pixels, + //giving the icon a weird background color. + var/mutable_appearance/scanline = mutable_appearance(generate_icon_alpha_mask('icons/hud/lobby/newplayer_scanline.dmi', "scanline"), alpha = 20, layer = src.layer+0.04) + scanline.pixel_y = OVERLAY_X_DIFF + scanline.pixel_x = OVERLAY_Y_DIFF + . += scanline + +/atom/movable/screen/lobby/new_player_info/process(seconds_per_tick) + update_text() + +/atom/movable/screen/lobby/new_player_info/collapse_button() + show_static = FALSE + update_text() + //to be in sync with parent, we'll turn the TV off in this time instead. + animate(src, appearance = update_appearance(UPDATE_ICON), time = SHUTTER_MOVEMENT_DURATION + SHUTTER_WAIT_DURATION) + //we go to the right, not up + animate(transform = transform.Translate(x = 146, y = 0), time = SHUTTER_MOVEMENT_DURATION, easing = CUBIC_EASING|EASE_IN) + +/atom/movable/screen/lobby/new_player_info/expand_button() + . = ..() + show_static = TRUE + update_appearance(UPDATE_ICON) + update_text() + +/atom/movable/screen/lobby/new_player_info/proc/update_text() + if(!hud || !show_static) + maptext = null + return + + var/round_started = SSticker.HasRoundStarted() + if(!MC_RUNNING()) + maptext = MAPTEXT("[(round_started ? null : "Starting in [time_remaining_str()]
")]Loading...
") + return + + if(SSticker.IsPostgame()) + maptext = MAPTEXT("Game ended,
\ + restart soon
") + return + + var/new_maptext + if(round_started) + new_maptext = "[SSmapping.current_map.map_name]
\ + [LAZYLEN(GLOB.clients)] player\s online
\ + [ROUND_TIME()] in
" + new_maptext += "
" + else + if(hud.mymob.client?.holder) + new_maptext = "Starting in [time_remaining_str()]
\ + [LAZYLEN(GLOB.clients)] player\s
\ + [SSticker.totalPlayersReady] players ready
\ + [SSticker.total_admins_ready] / [length(GLOB.admins)] admins ready
" + else + new_maptext = "[time_remaining_str()]
\ + [LAZYLEN(GLOB.clients)] player\s" + + maptext = MAPTEXT(new_maptext) + +/atom/movable/screen/lobby/new_player_info/proc/time_remaining_str() + var/time_remaining = SSticker.GetTimeLeft() + if(time_remaining > 0) + return "[round(time_remaining/10)]s" + if(time_remaining == -10) + return "DELAYED" + return "SOON" + +#undef OVERLAY_X_DIFF +#undef OVERLAY_Y_DIFF + +#undef SHUTTER_MOVEMENT_DURATION +#undef SHUTTER_WAIT_DURATION diff --git a/code/modules/pai/hud.dm b/code/_onclick/hud/screen_objects/pai.dm similarity index 57% rename from code/modules/pai/hud.dm rename to code/_onclick/hud/screen_objects/pai.dm index fb1fd483116..0965787ef42 100644 --- a/code/modules/pai/hud.dm +++ b/code/_onclick/hud/screen_objects/pai.dm @@ -17,6 +17,7 @@ /atom/movable/screen/pai/software name = "Software Interface" icon_state = "pai" + screen_loc = ui_pai_software /atom/movable/screen/pai/software/Click() if(!..()) @@ -27,6 +28,7 @@ /atom/movable/screen/pai/shell name = "Toggle Holoform" icon_state = "pai_holoform" + screen_loc = ui_pai_shell /atom/movable/screen/pai/shell/Click() if(!..()) @@ -40,6 +42,7 @@ /atom/movable/screen/pai/chassis name = "Holochassis Appearance Composite" icon_state = "pai_chassis" + screen_loc = ui_pai_chassis /atom/movable/screen/pai/chassis/Click() if(!..()) @@ -50,6 +53,7 @@ /atom/movable/screen/pai/rest name = "Rest" icon_state = "pai_rest" + screen_loc = ui_pai_rest /atom/movable/screen/pai/rest/Click() if(!..()) @@ -60,6 +64,7 @@ /atom/movable/screen/pai/light name = "Toggle Integrated Lights" icon_state = "light" + screen_loc = ui_pai_light /atom/movable/screen/pai/light/Click() if(!..()) @@ -70,6 +75,7 @@ /atom/movable/screen/pai/newscaster name = "pAI Newscaster" icon_state = "newscaster" + screen_loc = ui_pai_newscaster required_software = "Newscaster" /atom/movable/screen/pai/newscaster/Click() @@ -81,6 +87,7 @@ /atom/movable/screen/pai/host_monitor name = "Host Health Scan" icon_state = "host_monitor" + screen_loc = ui_pai_host_monitor required_software = "Host Scan" /atom/movable/screen/pai/host_monitor/Click(location, control, params) @@ -99,6 +106,7 @@ /atom/movable/screen/pai/crew_manifest name = "Crew Manifest" icon_state = "manifest" + screen_loc = ui_pai_crew_manifest required_software = "Crew Manifest" /atom/movable/screen/pai/crew_manifest/Click() @@ -110,6 +118,7 @@ /atom/movable/screen/pai/state_laws name = "State Laws" icon_state = "state_laws" + screen_loc = ui_pai_state_laws /atom/movable/screen/pai/state_laws/Click() if(!..()) @@ -120,18 +129,21 @@ /atom/movable/screen/pai/modpc name = "Messenger" icon_state = "pda_send" + screen_loc = ui_pai_mod_int required_software = "Digital Messenger" - var/mob/living/silicon/pai/pAI /atom/movable/screen/pai/modpc/Click() . = ..() if(!.) // this works for some reason. return - pAI.modularInterface?.interact(pAI) + var/mob/living/silicon/pai/pAI = usr + if (istype(pAI)) + pAI.modularInterface?.interact(pAI) /atom/movable/screen/pai/internal_gps name = "Internal GPS" icon_state = "internal_gps" + screen_loc = ui_pai_internal_gps required_software = "Internal GPS" /atom/movable/screen/pai/internal_gps/Click() @@ -146,6 +158,7 @@ /atom/movable/screen/pai/image_take name = "Take Image" icon_state = "take_picture" + screen_loc = ui_pai_take_picture required_software = "Photography Module" /atom/movable/screen/pai/image_take/Click() @@ -158,6 +171,7 @@ /atom/movable/screen/pai/image_view name = "View Images" icon_state = "view_images" + screen_loc = ui_pai_view_images required_software = "Photography Module" /atom/movable/screen/pai/image_view/Click() @@ -170,6 +184,7 @@ name = "radio" icon = 'icons/hud/screen_cyborg.dmi' icon_state = "radio" + screen_loc = ui_pai_radio /atom/movable/screen/pai/radio/Click() if(!..()) @@ -177,109 +192,4 @@ var/mob/living/silicon/pai/pAI = usr pAI.radio.interact(usr) -/datum/hud/pai - ui_style = 'icons/hud/screen_pai.dmi' - -/datum/hud/pai/New(mob/living/silicon/pai/owner) - ..() - var/atom/movable/screen/using - -// Software menu - using = new /atom/movable/screen/pai/software(null, src) - using.screen_loc = ui_pai_software - static_inventory += using - -// Holoform - using = new /atom/movable/screen/pai/shell(null, src) - using.screen_loc = ui_pai_shell - static_inventory += using - -// Chassis Select Menu - using = new /atom/movable/screen/pai/chassis(null, src) - using.screen_loc = ui_pai_chassis - static_inventory += using - -// Rest - using = new /atom/movable/screen/pai/rest(null, src) - using.screen_loc = ui_pai_rest - static_inventory += using - -// Integrated Light - using = new /atom/movable/screen/pai/light(null, src) - using.screen_loc = ui_pai_light - static_inventory += using - -// Newscaster - using = new /atom/movable/screen/pai/newscaster(null, src) - using.screen_loc = ui_pai_newscaster - static_inventory += using - -// Language menu - using = new /atom/movable/screen/language_menu(null, src) - using.icon = ui_style - using.screen_loc = ui_pai_language_menu - static_inventory += using - -// Memories - using = new /atom/movable/screen/memories(null, src) - using.icon = ui_style - using.screen_loc = ui_pai_memories_menu - static_inventory += using - -// Navigation - using = new /atom/movable/screen/navigate(null, src) - using.icon = ui_style - using.screen_loc = ui_pai_navigate_menu - static_inventory += using - -// Host Monitor - using = new /atom/movable/screen/pai/host_monitor(null, src) - using.screen_loc = ui_pai_host_monitor - static_inventory += using - -// Crew Manifest - using = new /atom/movable/screen/pai/crew_manifest(null, src) - using.screen_loc = ui_pai_crew_manifest - static_inventory += using - -// Laws - using = new /atom/movable/screen/pai/state_laws(null, src) - using.screen_loc = ui_pai_state_laws - static_inventory += using - -// Modular Interface - using = new /atom/movable/screen/pai/modpc(null, src) - using.screen_loc = ui_pai_mod_int - static_inventory += using - var/atom/movable/screen/pai/modpc/tablet_button = using - tablet_button.pAI = mymob - -// Internal GPS - using = new /atom/movable/screen/pai/internal_gps(null, src) - using.screen_loc = ui_pai_internal_gps - static_inventory += using - -// Take image - using = new /atom/movable/screen/pai/image_take(null, src) - using.screen_loc = ui_pai_take_picture - static_inventory += using - -// View images - using = new /atom/movable/screen/pai/image_view(null, src) - using.screen_loc = ui_pai_view_images - static_inventory += using - -// Radio - using = new /atom/movable/screen/pai/radio(null, src) - using.screen_loc = ui_pai_radio - static_inventory += using - - update_software_buttons() - -/datum/hud/pai/proc/update_software_buttons() - var/mob/living/silicon/pai/owner = mymob - for(var/atom/movable/screen/pai/button in static_inventory) - if(button.required_software) - button.color = owner.installed_software.Find(button.required_software) ? null : COLOR_GRAY - #undef PAI_MISSING_SOFTWARE_MESSAGE diff --git a/code/_onclick/hud/screen_objects/perks.dm b/code/_onclick/hud/screen_objects/perks.dm new file mode 100644 index 00000000000..5d6be963b02 --- /dev/null +++ b/code/_onclick/hud/screen_objects/perks.dm @@ -0,0 +1,29 @@ +/atom/movable/screen/perk + icon = 'icons/hud/perks.dmi' + name = "blank" + icon_state = "blank" + +/atom/movable/screen/perk/more + name = "more" + icon_state = "more" + // When compact we don't show our perk huds in ui. + var/compact = FALSE + +/atom/movable/screen/perk/more/Click(location, control, params) + . = ..() + if(!isliving(usr)) + return + var/mob/living/usr_is_living = usr + var/datum/antagonist/wizard/wizard_datum = usr_is_living.mind.has_antag_datum(/datum/antagonist/wizard) + if(!wizard_datum) + return + compact = !compact + var/datum/hud/user_hud = usr_is_living.hud_used + for (var/perk_id in 1 to length(wizard_datum.perks)) + var/atom/movable/screen/perk/perk = user_hud.screen_objects[HUD_WIZARD_PERK(perk_id)] + if (!perk) // ?? + continue + if (compact) + perk.SetInvisibility(INVISIBILITY_ABSTRACT, type) + else + perk.RemoveInvisibility(type) diff --git a/code/_onclick/hud/picture_in_picture.dm b/code/_onclick/hud/screen_objects/picture_in_picture.dm similarity index 100% rename from code/_onclick/hud/picture_in_picture.dm rename to code/_onclick/hud/screen_objects/picture_in_picture.dm diff --git a/code/_onclick/hud/radial.dm b/code/_onclick/hud/screen_objects/radial.dm similarity index 100% rename from code/_onclick/hud/radial.dm rename to code/_onclick/hud/screen_objects/radial.dm diff --git a/code/_onclick/hud/radial_persistent.dm b/code/_onclick/hud/screen_objects/radial_persistent.dm similarity index 100% rename from code/_onclick/hud/radial_persistent.dm rename to code/_onclick/hud/screen_objects/radial_persistent.dm diff --git a/code/_onclick/hud/screen_objects/robot.dm b/code/_onclick/hud/screen_objects/robot.dm new file mode 100644 index 00000000000..9dd39e8d4d6 --- /dev/null +++ b/code/_onclick/hud/screen_objects/robot.dm @@ -0,0 +1,113 @@ +/atom/movable/screen/robot + icon = 'icons/hud/screen_cyborg.dmi' + mouse_over_pointer = MOUSE_HAND_POINTER + +/atom/movable/screen/robot/module + name = "cyborg module" + icon_state = "nomod" + +/atom/movable/screen/robot/Click(location, control, params) + if(isobserver(usr)) + return TRUE + +/atom/movable/screen/robot/module/Click(location, control, params) + . = ..() + var/mob/living/silicon/robot/robot_owner = hud.mymob + if(robot_owner.model.type == /obj/item/robot_model) + if(.) + return + robot_owner.pick_model() + return + + var/list/modifiers = params2list(params) + if(robot_owner.module_active && !LAZYACCESS(modifiers, RIGHT_CLICK) && !.) + robot_owner.uneq_active() + return + + // Observers can look at borg's inventories, so we ignore parent return value here, unlike everywhere else. + if(usr.active_storage == robot_owner.model.atom_storage) + robot_owner.model.atom_storage.hide_contents(usr) + else + robot_owner.model.atom_storage.open_storage(usr) + return TRUE + +/atom/movable/screen/robot/module_slot + name = "module" + icon_state = "inv1" + base_icon_state = "inv1" + /// Slot number of the module + var/slot_num = 1 + +/atom/movable/screen/robot/module_slot/proc/set_slot(slot_num) + src.slot_num = slot_num + name = "module[slot_num]" + base_icon_state = "inv[slot_num]" + icon_state = base_icon_state + + switch(slot_num) + if(BORG_CHOOSE_MODULE_ONE) + screen_loc = ui_inv1 + if(BORG_CHOOSE_MODULE_TWO) + screen_loc = ui_inv2 + if(BORG_CHOOSE_MODULE_THREE) + screen_loc = ui_inv3 + +/atom/movable/screen/robot/module_slot/Click() + if(..()) + return + var/mob/living/silicon/robot/R = usr + R.toggle_module(slot_num) + +/atom/movable/screen/robot/radio + name = "radio" + icon_state = "radio" + screen_loc = ui_borg_radio + +/atom/movable/screen/robot/radio/Click() + if(..()) + return + var/mob/living/silicon/robot/R = usr + R.radio.interact(R) + +/atom/movable/screen/robot/lamp + name = "headlamp" + icon_state = "lamp_off" + base_icon_state = "lamp" + screen_loc = ui_borg_lamp + +/atom/movable/screen/robot/lamp/Click() + . = ..() + if(.) + return + var/mob/living/silicon/robot/user = usr + user.toggle_headlamp() + update_appearance() + +/atom/movable/screen/robot/lamp/update_icon_state() + icon_state = "[base_icon_state]_[astype(hud?.mymob, /mob/living/silicon/robot)?.lamp_enabled ? "on" : "off"]" + return ..() + +/atom/movable/screen/robot/modpc + name = "Modular Interface" + icon_state = "template" + screen_loc = ui_borg_tablet + +/atom/movable/screen/robot/modpc/Click() + . = ..() + if(.) + return + var/mob/living/silicon/robot/user = usr + user.modularInterface?.interact(user) + +/atom/movable/screen/robot/alerts + name = "Alert Panel" + icon = 'icons/hud/screen_ai.dmi' + icon_state = "alerts" + screen_loc = ui_borg_alerts + +/atom/movable/screen/robot/alerts/Click() + . = ..() + if(.) + return + var/mob/living/silicon/robot/borgo = usr + borgo.alert_control.ui_interact(borgo) diff --git a/code/_onclick/hud/screen_object_holder.dm b/code/_onclick/hud/screen_objects/screen_object_holder.dm similarity index 100% rename from code/_onclick/hud/screen_object_holder.dm rename to code/_onclick/hud/screen_objects/screen_object_holder.dm diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects/screen_objects.dm similarity index 96% rename from code/_onclick/hud/screen_objects.dm rename to code/_onclick/hud/screen_objects/screen_objects.dm index 2514376f911..fc4c8be9e4f 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects/screen_objects.dm @@ -1,3 +1,4 @@ +INITIALIZE_IMMEDIATE(/atom/movable/screen) // I hate this place /* Screen objects Todo: improve/re-implement @@ -34,6 +35,10 @@ */ var/del_on_map_removal = TRUE + /// A key for cleaning up references in hud datums + var/hud_group_key + var/hud_key + /// If FALSE, this will not be cleared when calling /client/clear_screen() var/clear_with_screen = TRUE /// If TRUE, clicking the screen element will fall through and perform a default "Click" call @@ -50,6 +55,10 @@ set_new_hud(hud_owner) /atom/movable/screen/Destroy() + if(hud) + if (hud_group_key && hud.screen_groups?[hud_group_key]) + hud.screen_groups?[hud_group_key] -= src + hud.screen_objects -= hud_key master_ref = null hud = null return ..() @@ -57,6 +66,7 @@ /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 ..() @@ -101,7 +111,6 @@ maptext_width = 480 /atom/movable/screen/swap_hand - plane = HUD_PLANE name = "swap hand" mouse_over_pointer = MOUSE_HAND_POINTER @@ -187,7 +196,6 @@ var/icon_full /// The overlay when hovering over with an item in your hand var/image/object_overlay - plane = HUD_PLANE /atom/movable/screen/inventory/Click(location, control, params) // At this point in client Click() code we have passed the 1/10 sec check and little else @@ -304,6 +312,7 @@ icon = 'icons/hud/screen_midnight.dmi' icon_state = "storage_close" mouse_over_pointer = MOUSE_HAND_POINTER + hud_group_key = HUD_GROUP_STORAGE /atom/movable/screen/close/Initialize(mapload, datum/hud/hud_owner, new_master) . = ..() @@ -320,7 +329,6 @@ name = "drop" icon = 'icons/hud/screen_midnight.dmi' icon_state = "act_drop" - plane = HUD_PLANE mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/drop/Click() @@ -331,7 +339,7 @@ name = "toggle combat mode" icon = 'icons/hud/screen_midnight.dmi' icon_state = "combat_off" - screen_loc = ui_combat_toggle + screen_loc = ui_acti mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/combattoggle/Initialize(mapload, datum/hud/hud_owner) @@ -470,6 +478,11 @@ icon = 'icons/hud/screen_midnight.dmi' icon_state = "running" mouse_over_pointer = MOUSE_HAND_POINTER + screen_loc = ui_movi + +/atom/movable/screen/mov_intent/Initialize(mapload, datum/hud/hud_owner) + . = ..() + update_appearance(UPDATE_ICON_STATE) /atom/movable/screen/mov_intent/Click() toggle(usr) @@ -496,6 +509,11 @@ icon_state = "pull" base_icon_state = "pull" mouse_over_pointer = MOUSE_HAND_POINTER + screen_loc = ui_living_pull + +/atom/movable/screen/pull/Initialize(mapload, datum/hud/hud_owner) + . = ..() + update_appearance(UPDATE_ICON_STATE) /atom/movable/screen/pull/Click() if(isobserver(usr)) @@ -511,8 +529,8 @@ icon = 'icons/hud/screen_midnight.dmi' icon_state = "act_resist" base_icon_state = "act_resist" - plane = HUD_PLANE mouse_over_pointer = MOUSE_HAND_POINTER + screen_loc = ui_above_movement /atom/movable/screen/resist/Click() flick("[base_icon_state]_on", src) @@ -525,8 +543,12 @@ icon = 'icons/hud/screen_midnight.dmi' icon_state = "act_rest" base_icon_state = "act_rest" - plane = HUD_PLANE mouse_over_pointer = MOUSE_HAND_POINTER + screen_loc = ui_below_throw + +/atom/movable/screen/rest/Initialize(mapload, datum/hud/hud_owner) + . = ..() + update_appearance(UPDATE_ICON_STATE) /atom/movable/screen/rest/Click() if(isliving(usr)) @@ -545,32 +567,38 @@ icon = 'icons/hud/screen_midnight.dmi' icon_state = "act_sleep" base_icon_state = "act_sleep" - plane = HUD_PLANE mouse_over_pointer = MOUSE_HAND_POINTER + screen_loc = ui_above_throw + +/atom/movable/screen/sleep/Initialize(mapload, datum/hud/hud_owner) + . = ..() + // Invisible by default + SetInvisibility(INVISIBILITY_ABSTRACT, "sleep") /atom/movable/screen/sleep/Click() if(!isliving(usr) || HAS_TRAIT(usr, TRAIT_KNOCKEDOUT)) return - if(usr.client?.prefs.read_preference(/datum/preference/toggle/remove_double_click)) - var/tgui_answer = tgui_alert(usr, "You sure you want to sleep for a while?", "Sleeping", list("Yes", "No")) - if(tgui_answer == "Yes" && !HAS_TRAIT(usr, TRAIT_KNOCKEDOUT)) - var/mob/living/L = usr - L.SetSleeping(400) - else + if(!usr.client?.prefs.read_preference(/datum/preference/toggle/remove_double_click)) flick("[base_icon_state]_flick", src) + return + + var/tgui_answer = tgui_alert(usr, "You sure you want to sleep for a while?", "Sleeping", list("Yes", "No")) + if(tgui_answer == "Yes" && !HAS_TRAIT(usr, TRAIT_KNOCKEDOUT)) + var/mob/living/L = usr + L.Sleeping(400) /atom/movable/screen/sleep/DblClick(location, control, params) if(!isliving(usr) || usr.client?.prefs.read_preference(/datum/preference/toggle/remove_double_click)) return if(isliving(usr)) var/mob/living/L = usr - L.SetSleeping(400) + L.Sleeping(400) /atom/movable/screen/storage name = "storage" icon = 'icons/hud/screen_midnight.dmi' icon_state = "storage_cell" - plane = HUD_PLANE + hud_group_key = HUD_GROUP_STORAGE /atom/movable/screen/storage/Initialize(mapload, datum/hud/hud_owner, new_master) . = ..() @@ -638,6 +666,7 @@ icon = 'icons/hud/screen_midnight.dmi' icon_state = "act_throw" mouse_over_pointer = MOUSE_HAND_POINTER + screen_loc = ui_drop_throw /atom/movable/screen/throw_catch/Click() if(isliving(usr)) @@ -653,6 +682,10 @@ var/static/list/hover_overlays_cache = list() var/hovering +/atom/movable/screen/zone_sel/Initialize(mapload, datum/hud/hud_owner) + . = ..() + update_appearance() + /atom/movable/screen/zone_sel/Click(location, control,params) if(isobserver(usr)) return @@ -941,7 +974,6 @@ plane = SPLASHSCREEN_PLANE var/client/holder -INITIALIZE_IMMEDIATE(/atom/movable/screen/splash) /atom/movable/screen/splash/Initialize(mapload, datum/hud/hud_owner, client/C, visible, use_previous_title) . = ..() diff --git a/code/_onclick/hud/screentip.dm b/code/_onclick/hud/screen_objects/screentip.dm similarity index 100% rename from code/_onclick/hud/screentip.dm rename to code/_onclick/hud/screen_objects/screentip.dm diff --git a/code/_onclick/hud/voidwalkerhud.dm b/code/_onclick/hud/screen_objects/voidwalker.dm similarity index 73% rename from code/_onclick/hud/voidwalkerhud.dm rename to code/_onclick/hud/screen_objects/voidwalker.dm index 7ba892f7d7a..6d718ac58d7 100644 --- a/code/_onclick/hud/voidwalkerhud.dm +++ b/code/_onclick/hud/screen_objects/voidwalker.dm @@ -1,30 +1,3 @@ -/datum/hud/dextrous/voidwalker - ui_style = 'icons/hud/screen_voidwalker.dmi' - -/datum/hud/dextrous/voidwalker/New(mob/living/owner) - . = ..() - - floor_change.icon = ui_style - floor_change.screen_loc = ui_rest - static_inventory += floor_change - - resist_icon = new /atom/movable/screen/resist(null, src) - resist_icon.icon = ui_style - resist_icon.screen_loc = ui_voidwalker_left_of_hands - resist_icon.update_appearance() - - action_intent = new /atom/movable/screen/combattoggle/flashy/voidwalker(null, src) - action_intent.icon = ui_style - static_inventory += action_intent - - var/atom/movable/screen/space_camo_toggle = new /atom/movable/screen/space_camo(null, src) - space_camo_toggle.screen_loc = ui_above_movement - static_inventory += space_camo_toggle - - var/atom/movable/screen/vomit_jump/vomit = new /atom/movable/screen/vomit_jump(null, src) - vomit.screen_loc = ui_mood - static_inventory += vomit - /// This exists because for some reason only the combat indicator screen_loc is constantly set to initial /atom/movable/screen/combattoggle/flashy/voidwalker screen_loc = ui_movi @@ -33,6 +6,7 @@ name = "space camouflage toggle" icon = 'icons/hud/screen_voidwalker.dmi' icon_state = "camo_toggle" + screen_loc = ui_above_movement /// Wheter or not we're toggled on or off var/invisibility_toggle = TRUE @@ -57,6 +31,7 @@ name = "vomit tracker" icon = 'icons/hud/screen_voidwalker.dmi' icon_state = "template" + screen_loc = ui_mood /// So we can sort of loop through it var/index = 1 diff --git a/code/_onclick/hud/soulscythe.dm b/code/_onclick/hud/soulscythe.dm index 8c7a3359c8a..e290d960e56 100644 --- a/code/_onclick/hud/soulscythe.dm +++ b/code/_onclick/hud/soulscythe.dm @@ -1,4 +1,3 @@ -/datum/hud/soulscythe/New(mob/living/basic/soulscythe/owner) +/datum/hud/soulscythe/initialize_screen_objects() . = ..() - var/atom/movable/screen/using = new /atom/movable/screen/blood_level(null, src) - static_inventory += using + add_screen_object(/atom/movable/screen/blood_level, HUD_MOB_BLOOD_LEVEL, HUD_GROUP_INFO) diff --git a/code/_onclick/hud/voidwalker.dm b/code/_onclick/hud/voidwalker.dm new file mode 100644 index 00000000000..7fe95fc3f28 --- /dev/null +++ b/code/_onclick/hud/voidwalker.dm @@ -0,0 +1,14 @@ +/datum/hud/dextrous/voidwalker + ui_style = 'icons/hud/screen_voidwalker.dmi' + +/datum/hud/dextrous/voidwalker/initialize_screen_objects() + . = ..() + var/atom/movable/screen/floor_change = screen_objects[HUD_MOB_FLOOR_CHANGER] + floor_change.icon = ui_style + floor_change.screen_loc = ui_below_throw + + add_screen_object(/atom/movable/screen/resist, HUD_MOB_RESIST, HUD_GROUP_HOTKEYS, ui_style, ui_voidwalker_left_of_hands) + add_screen_object(/atom/movable/screen/combattoggle/flashy/voidwalker, HUD_MOB_INTENTS, HUD_GROUP_STATIC, ui_style) + add_screen_object(/atom/movable/screen/space_camo, HUD_VOIDWALKER_SPACE_CAMO) + add_screen_object(/atom/movable/screen/vomit_jump, HUD_VOIDWALKER_VOID_JUMP) + diff --git a/code/datums/actions/action.dm b/code/datums/actions/action.dm index 64f2f2a6c2b..b5993e1894a 100644 --- a/code/datums/actions/action.dm +++ b/code/datums/actions/action.dm @@ -373,7 +373,7 @@ /// Creates an action button movable for the passed mob, and returns it. /datum/action/proc/create_button() - var/atom/movable/screen/movable/action_button/button = new() + var/atom/movable/screen/movable/action_button/button = owner.hud_used.add_screen_object(/atom/movable/screen/movable/action_button) button.linked_action = src button.allow_observer_click = allow_observer_click build_button_icon(button, ALL, TRUE) diff --git a/code/datums/components/crafting/crafting.dm b/code/datums/components/crafting/crafting.dm index d8b6103e338..a042bfe7a02 100644 --- a/code/datums/components/crafting/crafting.dm +++ b/code/datums/components/crafting/crafting.dm @@ -15,20 +15,29 @@ /datum/component/personal_crafting/Initialize(screen_loc_override) src.screen_loc_override = screen_loc_override - if(ismob(parent)) - RegisterSignal(parent, COMSIG_MOB_CLIENT_LOGIN, PROC_REF(create_mob_button)) -/datum/component/personal_crafting/proc/create_mob_button(mob/user, client/user_client) +/datum/component/personal_crafting/RegisterWithParent() + if(!ismob(parent)) + return + + var/mob/user = parent + RegisterSignal(parent, COMSIG_MOB_HUD_CREATED, PROC_REF(on_hud_created)) + if(user.hud_used) + on_hud_created() + +/datum/component/personal_crafting/UnregisterFromParent() + if(!ismob(parent)) + return + var/mob/user = parent + UnregisterSignal(parent, COMSIG_MOB_HUD_CREATED) + user.hud_used?.remove_screen_object(HUD_MOB_CRAFTING_MENU) + +/datum/component/personal_crafting/proc/on_hud_created(datum/source) SIGNAL_HANDLER - var/datum/hud/hud = user.hud_used - var/atom/movable/screen/craft/craft_ui = new() - craft_ui.icon = hud.ui_style - if (screen_loc_override) - craft_ui.screen_loc = screen_loc_override - hud.static_inventory += craft_ui - user_client.screen += craft_ui - RegisterSignal(craft_ui, COMSIG_SCREEN_ELEMENT_CLICK, PROC_REF(component_ui_interact)) + var/mob/user = parent + var/atom/movable/screen/screen_obj = user.hud_used.add_screen_object(/atom/movable/screen/craft, HUD_MOB_CRAFTING_MENU, HUD_GROUP_STATIC, user.hud_used.ui_style, screen_loc_override, update_screen = TRUE) + RegisterSignal(screen_obj, COMSIG_SCREEN_ELEMENT_CLICK, PROC_REF(component_ui_interact)) #define COOKING TRUE #define CRAFTING FALSE diff --git a/code/datums/components/food/edible.dm b/code/datums/components/food/edible.dm index b58ef88a3dc..465b6ae2066 100644 --- a/code/datums/components/food/edible.dm +++ b/code/datums/components/food/edible.dm @@ -504,7 +504,9 @@ Behavior that's still missing from this component that original food items had t var/fraction = 0.3 fraction = min(bite_consumption / owner.reagents.total_volume, 1) owner.reagents.trans_to(eater, bite_consumption, transferred_by = feeder, methods = INGEST) - eater.hud_used?.hunger?.update_hunger_bar() + var/atom/movable/screen/hunger/hunger_bar = eater.hud_used?.screen_objects[HUD_MOB_HUNGER] + if (istype(hunger_bar)) + hunger_bar.update_hunger_bar() bitecount++ checkLiked(fraction, eater) diff --git a/code/datums/components/fov_handler.dm b/code/datums/components/fov_handler.dm index df56df1ff6e..cd3061291a2 100644 --- a/code/datums/components/fov_handler.dm +++ b/code/datums/components/fov_handler.dm @@ -90,8 +90,6 @@ /datum/component/fov_handler/proc/remove_mask() var/mob/parent_mob = parent var/client/parent_client = parent_mob.client - // Prevents stupid ass hard deletes - parent_mob.hud_used.always_visible_inventory -= blocker_mask if(!parent_client) //Love client volatility!! return applied_mask = FALSE @@ -104,7 +102,8 @@ return applied_mask = TRUE parent_client.screen += blocker_mask - parent_mob.hud_used.always_visible_inventory += blocker_mask + parent_mob.hud_used.screen_objects += blocker_mask + parent_mob.hud_used.screen_groups[HUD_GROUP_SCREEN_OVERLAYS] += blocker_mask /// When a direction of the user changes, so do the masks /datum/component/fov_handler/proc/on_dir_change(mob/source, old_dir, new_dir) diff --git a/code/datums/components/life_link.dm b/code/datums/components/life_link.dm index a79758122c5..d1371467682 100644 --- a/code/datums/components/life_link.dm +++ b/code/datums/components/life_link.dm @@ -118,8 +118,9 @@ mob_parent.overlay_fullscreen("brute", /atom/movable/screen/fullscreen/brute, severity) else mob_parent.clear_fullscreen("brute") - if(mob_parent.hud_used?.healths) - mob_parent.hud_used.healths.maptext = MAPTEXT("
[round(healthpercent, 0.5)]%
") + + if(mob_parent.hud_used?.screen_objects[HUD_MOB_HEALTH]) + mob_parent.hud_used.screen_objects[HUD_MOB_HEALTH].maptext = MAPTEXT("
[round(healthpercent, 0.5)]%
") /// Update our health on the medical hud /datum/component/life_link/proc/update_med_hud_health(mob/living/mob_parent) diff --git a/code/datums/components/style/style.dm b/code/datums/components/style/style.dm index 6e1147a7ba3..04ea7b3654c 100644 --- a/code/datums/components/style/style.dm +++ b/code/datums/components/style/style.dm @@ -74,23 +74,7 @@ if(!ismob(parent)) return COMPONENT_INCOMPATIBLE - var/mob/mob_parent = parent - - meter = new() - meter_image = new() - meter.vis_contents += meter_image - meter_image.add_filter("meter_mask", 1, list(type = "alpha", icon = icon('icons/hud/style_meter.dmi', "style_meter"), flags = MASK_INVERSE)) - meter.update_appearance() - meter_image.update_appearance() - - update_screen() - - if(mob_parent.hud_used) - mob_parent.hud_used.static_inventory += meter - mob_parent.hud_used.show_hud(mob_parent.hud_used.hud_version) - START_PROCESSING(SSdcs, src) - if(multitooled) src.multitooled = multitooled @@ -107,7 +91,11 @@ RegisterSignal(parent, COMSIG_LIVING_DEFUSED_GIBTONITE, PROC_REF(on_gibtonite_defuse)) RegisterSignal(parent, COMSIG_LIVING_CRUSHER_DETONATE, PROC_REF(on_crusher_detonate)) RegisterSignal(parent, COMSIG_LIVING_DISCOVERED_GEYSER, PROC_REF(on_geyser_discover)) + RegisterSignal(parent, COMSIG_MOB_HUD_CREATED, PROC_REF(on_hud_created)) ADD_TRAIT(parent, TRAIT_MINING_PARRYING, STYLE_TRAIT) + var/mob/mob_parent = parent + if (mob_parent.hud_used) + on_hud_created() /datum/component/style/UnregisterFromParent() UnregisterSignal(parent, COMSIG_USER_PRE_ITEM_ATTACK) @@ -121,16 +109,31 @@ UnregisterSignal(parent, COMSIG_LIVING_DEFUSED_GIBTONITE) UnregisterSignal(parent, COMSIG_LIVING_CRUSHER_DETONATE) UnregisterSignal(parent, COMSIG_LIVING_DISCOVERED_GEYSER) + UnregisterSignal(parent, COMSIG_MOB_HUD_CREATED) REMOVE_TRAIT(parent, TRAIT_MINING_PARRYING, STYLE_TRAIT) /datum/component/style/Destroy(force) STOP_PROCESSING(SSdcs, src) + QDEL_NULL(meter) + QDEL_NULL(meter_image) var/mob/mob_parent = parent if(mob_parent.hud_used) - mob_parent.hud_used.static_inventory -= meter mob_parent.hud_used.show_hud(mob_parent.hud_used.hud_version) return ..() + +/datum/component/style/proc/on_hud_created(datum/source) + SIGNAL_HANDLER + + var/mob/owner = parent + meter = owner.hud_used.add_screen_object(/atom/movable/screen/style_meter_background, HUD_MOB_STYLE_METER, update_screen = TRUE) + meter_image = new() + meter.vis_contents += meter_image + meter_image.add_filter("meter_mask", 1, list(type = "alpha", icon = icon('icons/hud/style_meter.dmi', "style_meter"), flags = MASK_INVERSE)) + meter.update_appearance() + meter_image.update_appearance() + update_screen() + /datum/component/style/process(seconds_per_tick) point_multiplier = round(max(point_multiplier - 0.2 * seconds_per_tick, 1), 0.1) change_points(-5 * seconds_per_tick * ROUND_UP((style_points + 1) / 200), use_multiplier = FALSE) @@ -195,6 +198,9 @@ mob_parent.balloon_alert(mob_parent, "hotswapping disabled") rank = rank_changed + + if(!meter) + return meter.maptext = "[format_rank_string(rank)][generate_multiplier()][generate_actions()]" meter.maptext_y = initial(meter.maptext_y) - 12 * length(actions) update_meter(point_to_rank(), go_back) diff --git a/code/datums/elements/attack_zone_randomiser.dm b/code/datums/elements/attack_zone_randomiser.dm index 1e364265bab..efd7648bc7c 100644 --- a/code/datums/elements/attack_zone_randomiser.dm +++ b/code/datums/elements/attack_zone_randomiser.dm @@ -21,14 +21,14 @@ SIGNAL_HANDLER if (!iscarbon(target)) return - if (!isnull(source.mind) && !isnull(source.hud_used?.zone_select)) + if (!isnull(source.mind) && !isnull(source.hud_used?.screen_objects[HUD_MOB_ZONE_SELECTOR])) return var/mob/living/living_target = target var/list/blacklist_zones = GLOB.all_body_zones - valid_attack_zones var/new_zone = living_target.get_random_valid_zone(blacklisted_parts = blacklist_zones, bypass_warning = TRUE) if (isnull(new_zone)) new_zone = BODY_ZONE_CHEST - var/atom/movable/screen/zone_sel/zone_selector = source.hud_used?.zone_select + var/atom/movable/screen/zone_sel/zone_selector = source.hud_used?.screen_objects[HUD_MOB_ZONE_SELECTOR] if (isnull(zone_selector)) source.zone_selected = new_zone else diff --git a/code/datums/keybinding/living.dm b/code/datums/keybinding/living.dm index 42eb96bf5da..d9d12020ef2 100644 --- a/code/datums/keybinding/living.dm +++ b/code/datums/keybinding/living.dm @@ -18,8 +18,8 @@ return var/mob/living/owner = user.mob owner.resist() - if (owner.hud_used?.resist_icon) - owner.hud_used.resist_icon.icon_state = "[owner.hud_used.resist_icon.base_icon_state]_on" + if (owner.hud_used?.screen_objects[HUD_MOB_RESIST]) + owner.hud_used.screen_objects[HUD_MOB_RESIST].icon_state = "[owner.hud_used.screen_objects[HUD_MOB_RESIST].base_icon_state]_on" return TRUE /datum/keybinding/living/resist/up(client/user, turf/target) @@ -27,8 +27,8 @@ if(.) return var/mob/living/owner = user.mob - if (owner.hud_used?.resist_icon) - owner.hud_used.resist_icon.icon_state = owner.hud_used.resist_icon.base_icon_state + if (owner.hud_used?.screen_objects[HUD_MOB_RESIST]) + owner.hud_used.screen_objects[HUD_MOB_RESIST].icon_state = owner.hud_used.screen_objects[HUD_MOB_RESIST].base_icon_state /datum/keybinding/living/look_up hotkey_keys = list("L") diff --git a/code/datums/martial/_martial.dm b/code/datums/martial/_martial.dm index 4a0c9c84b30..1281d028b22 100644 --- a/code/datums/martial/_martial.dm +++ b/code/datums/martial/_martial.dm @@ -24,8 +24,6 @@ var/smashes_tables = FALSE /// If TRUE, a combo meter will be displayed on the HUD for the current streak var/display_combos = FALSE - ///The Combo HUD given to display comboes, if we're set to display them. - var/atom/movable/screen/combo/combo_display /// The length of time until streaks are auto-reset. var/combo_timer = 6 SECONDS /// Timer ID for the combo reset timer. @@ -276,8 +274,11 @@ streak += element if(length(streak) > max_streak_length) streak = copytext(streak, 1 + length(streak[1])) - if(display_combos) - timerid = addtimer(CALLBACK(src, PROC_REF(reset_streak), null, FALSE), combo_timer, TIMER_UNIQUE | TIMER_STOPPABLE) + if(!display_combos) + return + timerid = addtimer(CALLBACK(src, PROC_REF(reset_streak), null, FALSE), combo_timer, TIMER_UNIQUE | TIMER_STOPPABLE) + var/atom/movable/screen/combo/combo_display = holder.hud_used?.screen_objects[HUD_MOB_COMBO] + if(istype(combo_display)) combo_display.update_icon_state(streak, combo_timer - 2 SECONDS) /** @@ -292,7 +293,8 @@ deltimer(timerid) current_target = WEAKREF(new_target) streak = "" - if(display_combos && update_icon) + var/atom/movable/screen/combo/combo_display = holder.hud_used?.screen_objects[HUD_MOB_COMBO] + if(istype(combo_display) && display_combos && update_icon) combo_display.update_icon_state(streak) /datum/martial_art/proc/smash_table(mob/living/source, mob/living/pushed_mob, obj/structure/table/table) @@ -383,10 +385,9 @@ RegisterSignal(new_holder, COMSIG_LIVING_GRAB, PROC_REF(attempt_grab)) RegisterSignals(new_holder, list(COMSIG_LIVING_TABLE_SLAMMING, COMSIG_LIVING_TABLE_LIMB_SLAMMING), PROC_REF(smash_table)) if(display_combos) + RegisterSignal(new_holder, COMSIG_MOB_HUD_CREATED, PROC_REF(on_hud_created)) if(new_holder.hud_used) on_hud_created(new_holder) - else - RegisterSignal(new_holder, COMSIG_MOB_HUD_CREATED, PROC_REF(on_hud_created)) /** * Called when this martial art is removed from a mob. @@ -397,19 +398,12 @@ if(help_verb) remove_verb(remove_from, help_verb) UnregisterSignal(remove_from, list(COMSIG_LIVING_UNARMED_ATTACK, COMSIG_LIVING_GRAB, COMSIG_LIVING_TABLE_SLAMMING, COMSIG_LIVING_TABLE_LIMB_SLAMMING)) - if(!isnull(combo_display)) - var/datum/hud/hud_used = remove_from.hud_used - hud_used.infodisplay -= combo_display - hud_used.show_hud(hud_used.hud_version) - QDEL_NULL(combo_display) + remove_from.hud_used?.remove_screen_object(HUD_MOB_COMBO) ///Gives the owner of the martial art the combo HUD. /datum/martial_art/proc/on_hud_created(mob/source) SIGNAL_HANDLER - var/datum/hud/hud_used = source.hud_used - combo_display = new(null, hud_used) - hud_used.infodisplay += combo_display - hud_used.show_hud(hud_used.hud_version) + source.hud_used.add_screen_object(/atom/movable/screen/combo, HUD_MOB_COMBO, HUD_GROUP_INFO, update_screen = TRUE) /mob/living/proc/verb_switch_style() set name = "Swap Style" diff --git a/code/datums/mood.dm b/code/datums/mood.dm index 6ee75391517..afc7824380f 100644 --- a/code/datums/mood.dm +++ b/code/datums/mood.dm @@ -36,8 +36,6 @@ var/sanity_level = SANITY_LEVEL_NEUTRAL /// Is the owner being punished for low mood? if so, how much? var/insanity_effect = 0 - /// The screen object for the current mood level - var/atom/movable/screen/mood/mood_screen_object /// List of mood events currently active on this datum var/list/mood_events = list() @@ -308,7 +306,11 @@ /// Updates the mob's mood icon /datum/mood/proc/update_mood_icon() - if (!(mob_parent.client || mob_parent.hud_used) || isnull(mood_screen_object)) + if (!mob_parent.client || !mob_parent.hud_used) + return + + var/atom/movable/screen/mood/mood_screen_object = mob_parent.hud_used.screen_objects[HUD_MOB_MOOD] + if (!istype(mood_screen_object)) return mood_screen_object.cut_overlays() @@ -356,9 +358,8 @@ SIGNAL_HANDLER var/datum/hud/hud = mob_parent.hud_used - mood_screen_object = new + var/atom/movable/screen/mood/mood_screen_object = hud.add_screen_object(/atom/movable/screen/mood, HUD_MOB_MOOD, HUD_GROUP_INFO, update_screen = TRUE) mood_screen_object.color = "#4b96c4" - hud.infodisplay += mood_screen_object RegisterSignal(hud, COMSIG_QDELETING, PROC_REF(unmodify_hud)) RegisterSignal(mood_screen_object, COMSIG_SCREEN_ELEMENT_CLICK, PROC_REF(hud_click)) @@ -366,12 +367,17 @@ /datum/mood/proc/unmodify_hud(datum/source) SIGNAL_HANDLER + var/datum/hud/hud = mob_parent.hud_used + if (!hud) + return + + var/atom/movable/screen/mood/mood_screen_object = hud.screen_objects[HUD_MOB_MOOD] if(!mood_screen_object) return - var/datum/hud/hud = mob_parent.hud_used - if(hud?.infodisplay) - hud.infodisplay -= mood_screen_object + QDEL_NULL(mood_screen_object) + if (!QDELETED(hud)) + hud.show_hud(hud.hud_version) UnregisterSignal(hud, COMSIG_QDELETING) /// Handles clicking on the mood HUD object diff --git a/code/datums/status_effects/debuffs/screwy_hud.dm b/code/datums/status_effects/debuffs/screwy_hud.dm index 10c20112160..4779db579c6 100644 --- a/code/datums/status_effects/debuffs/screwy_hud.dm +++ b/code/datums/status_effects/debuffs/screwy_hud.dm @@ -40,7 +40,7 @@ if(other_screwy_hud.priority > priority) return - source.hud_used.healths.icon_state = override_icon + source.hud_used?.screen_objects[HUD_MOB_HEALTH]?.icon_state = override_icon return COMPONENT_OVERRIDE_HEALTH_HUD /datum/status_effect/grouped/screwy_hud/fake_dead diff --git a/code/datums/storage/storage.dm b/code/datums/storage/storage.dm index baab88cf239..472f9c6baa6 100644 --- a/code/datums/storage/storage.dm +++ b/code/datums/storage/storage.dm @@ -718,9 +718,12 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) SIGNAL_HANDLER for(var/mob/user as anything in is_using) - user.hud_used?.open_containers -= gone + if (user.hud_used?.screen_groups[HUD_GROUP_STORAGE]) + user.hud_used.screen_groups[HUD_GROUP_STORAGE] -= gone + if(!user.client) continue + var/client/cuser = user.client cuser.screen -= gone @@ -1086,9 +1089,10 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) LAZYOR(is_using, to_show) - to_show.hud_used.open_containers |= storage_interfaces[to_show].list_ui_elements() + // Don't add to screen_objects as that one gets its contents actually deleted + LAZYOR(to_show.hud_used.screen_groups[HUD_GROUP_STORAGE], storage_interfaces[to_show].list_ui_elements()) to_show.client.screen |= storage_interfaces[to_show].list_ui_elements() - to_show.hud_used.open_containers |= real_location.contents + LAZYOR(to_show.hud_used.screen_groups[HUD_GROUP_STORAGE], real_location.contents) to_show.client.screen |= real_location.contents return TRUE @@ -1116,9 +1120,9 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) if(to_hide.client) to_hide.client.screen -= storage_interfaces[to_hide].list_ui_elements() to_hide.client.screen -= real_location.contents - if(to_hide.hud_used) - to_hide.hud_used.open_containers -= storage_interfaces[to_hide].list_ui_elements() - to_hide.hud_used.open_containers -= real_location.contents + if(to_hide.hud_used.screen_groups[HUD_GROUP_STORAGE]) + to_hide.hud_used.screen_groups[HUD_GROUP_STORAGE] -= storage_interfaces[to_hide].list_ui_elements() + to_hide.hud_used.screen_groups[HUD_GROUP_STORAGE] -= real_location.contents QDEL_NULL(storage_interfaces[to_hide]) storage_interfaces -= to_hide diff --git a/code/datums/wounds/bones.dm b/code/datums/wounds/bones.dm index f6ba5f3acb9..695af1eaef9 100644 --- a/code/datums/wounds/bones.dm +++ b/code/datums/wounds/bones.dm @@ -286,7 +286,7 @@ /datum/wound/blunt/bone/moderate/try_handling(mob/living/user) if(user.usable_hands <= 0 || user.pulling != victim) return FALSE - if(!isnull(user.hud_used?.zone_select) && user.zone_selected != limb.body_zone) + if(!isnull(user.hud_used?.screen_objects[HUD_MOB_ZONE_SELECTOR]) && user.zone_selected != limb.body_zone) return FALSE if(user.grab_state == GRAB_PASSIVE) diff --git a/code/datums/wounds/cranial_fissure.dm b/code/datums/wounds/cranial_fissure.dm index e26e3a97d9d..9a2fd0eb439 100644 --- a/code/datums/wounds/cranial_fissure.dm +++ b/code/datums/wounds/cranial_fissure.dm @@ -87,7 +87,7 @@ if (user.usable_hands <= 0 || user.combat_mode) return FALSE - if(!isnull(user.hud_used?.zone_select) && (user.zone_selected != BODY_ZONE_HEAD && user.zone_selected != BODY_ZONE_PRECISE_EYES)) + if(!isnull(user.hud_used?.screen_objects[HUD_MOB_ZONE_SELECTOR]) && (user.zone_selected != BODY_ZONE_HEAD && user.zone_selected != BODY_ZONE_PRECISE_EYES)) return FALSE if (victim.body_position != LYING_DOWN) diff --git a/code/datums/wounds/slash.dm b/code/datums/wounds/slash.dm index 68f6d685ae8..5ed2e8695b7 100644 --- a/code/datums/wounds/slash.dm +++ b/code/datums/wounds/slash.dm @@ -181,7 +181,7 @@ /datum/wound/slash/flesh/try_handling(mob/living/user) if(user.pulling != victim || !HAS_TRAIT(user, TRAIT_WOUND_LICKER) || !victim.try_inject(user, injection_flags = INJECT_TRY_SHOW_ERROR_MESSAGE)) return FALSE - if(!isnull(user.hud_used?.zone_select) && user.zone_selected != limb.body_zone) + if(!isnull(user.hud_used?.screen_objects[HUD_MOB_ZONE_SELECTOR]) && user.zone_selected != limb.body_zone) return FALSE if(DOING_INTERACTION_WITH_TARGET(user, victim)) diff --git a/code/game/machinery/computer/operating_computer.dm b/code/game/machinery/computer/operating_computer.dm index 416f4c16fac..79d9b9279e0 100644 --- a/code/game/machinery/computer/operating_computer.dm +++ b/code/game/machinery/computer/operating_computer.dm @@ -148,7 +148,7 @@ if(!zone_found) return - var/atom/movable/screen/zone_sel/selector = user.hud_used?.zone_select + var/atom/movable/screen/zone_sel/selector = user.hud_used?.screen_objects[HUD_MOB_ZONE_SELECTOR] selector?.set_selected_zone(zone_found, user, FALSE) LAZYREMOVE(zone_on_open, WEAKREF(user)) if(!LAZYLEN(zone_on_open)) @@ -257,7 +257,7 @@ if("change_zone") if(params["new_zone"] in (GLOB.all_body_zones + GLOB.all_precise_body_zones)) target_zone = params["new_zone"] - var/atom/movable/screen/zone_sel/selector = ui.user.hud_used?.zone_select + var/atom/movable/screen/zone_sel/selector = ui.user.hud_used?.screen_objects[HUD_MOB_ZONE_SELECTOR] selector?.set_selected_zone(params["new_zone"], ui.user, FALSE) update_static_data_for_all_viewers() return TRUE diff --git a/code/game/machinery/computer/records/records.dm b/code/game/machinery/computer/records/records.dm index 2f6e429c772..a860e66d4f7 100644 --- a/code/game/machinery/computer/records/records.dm +++ b/code/game/machinery/computer/records/records.dm @@ -111,7 +111,7 @@ if(user.client?.screen_maps[assigned_view]) return - var/atom/movable/screen/map_view/char_preview/new_view = new(null, src) + var/atom/movable/screen/map_view/char_preview/new_view = new(null, null, src) new_view.generate_view(assigned_view) new_view.display_to(user, window) return new_view diff --git a/code/game/objects/items/devices/multitool.dm b/code/game/objects/items/devices/multitool.dm index 6a3ec38c3da..c58e46e7478 100644 --- a/code/game/objects/items/devices/multitool.dm +++ b/code/game/objects/items/devices/multitool.dm @@ -97,19 +97,27 @@ user.balloon_alert(user, balloon_message) var/datum/hud/user_hud = user.hud_used - if(!user_hud || !istype(user_hud, /datum/hud) || !islist(user_hud.infodisplay)) + if(!user_hud) return - var/atom/movable/screen/multitool_arrow/arrow = new(null, user_hud) + var/atom/movable/screen/multitool_arrow/arrow = user_hud.add_screen_object(/atom/movable/screen/multitool_arrow, HUD_MULTITOOL_ARROW, HUD_GROUP_INFO, update_screen = TRUE) arrow.color = arrow_color - arrow.screen_loc = around_player arrow.transform = matrix(dir2angle(dir), MATRIX_ROTATE) - - user_hud.infodisplay += arrow - user_hud.show_hud(user_hud.hud_version) - QDEL_IN(arrow, 1.5 SECONDS) +/atom/movable/screen/multitool_arrow + icon = 'icons/effects/96x96.dmi' + icon_state = "multitool_arrow" + pixel_x = -32 + pixel_y = -32 + screen_loc = around_player + +/atom/movable/screen/multitool_arrow/Destroy() + var/datum/hud/our_hud = hud + . = ..() + if (!QDELETED(our_hud)) + INVOKE_ASYNC(our_hud, TYPE_PROC_REF(/datum/hud, show_hud), our_hud.hud_version) + /obj/item/multitool/suicide_act(mob/living/carbon/user) user.visible_message(span_suicide("[user] puts the [src] to [user.p_their()] chest. It looks like [user.p_theyre()] trying to pulse [user.p_their()] heart off!")) return OXYLOSS//there's a reason it wasn't recommended by doctors diff --git a/code/modules/antagonists/blob/overmind.dm b/code/modules/antagonists/blob/overmind.dm index 2fc737cb365..e6f8ad51e22 100644 --- a/code/modules/antagonists/blob/overmind.dm +++ b/code/modules/antagonists/blob/overmind.dm @@ -61,9 +61,6 @@ GLOBAL_LIST_EMPTY(blob_nodes) /// The list of strains the blob can reroll for. var/list/strain_choices - ///The HUD given to blobs with their power - var/atom/movable/screen/blob_power_display/blob_power_hud - /mob/eye/blob/Initialize(mapload, starting_points = OVERMIND_STARTING_POINTS) ADD_TRAIT(src, TRAIT_BLOB_ALLY, INNATE_TRAIT) validate_location() @@ -85,14 +82,6 @@ GLOBAL_LIST_EMPTY(blob_nodes) START_PROCESSING(SSobj, src) GLOB.blob_telepathy_mobs |= src -/mob/eye/blob/create_mob_hud() - . = ..() - if(!.) - return - blob_power_hud = new(null, src) - hud_used.infodisplay += blob_power_hud - hud_used.show_hud(hud_used.hud_version) - /mob/eye/blob/proc/validate_location() var/turf/T = get_turf(src) if(is_valid_turf(T)) @@ -263,7 +252,6 @@ GLOBAL_LIST_EMPTY(blob_nodes) /mob/eye/blob/Destroy() QDEL_NULL(blobstrain) - QDEL_NULL(blob_power_hud) // Clear references immediately without iterating to avoid blocking all_blobs = null @@ -304,15 +292,15 @@ GLOBAL_LIST_EMPTY(blob_nodes) return FALSE var/current_health = round((blob_core.get_integrity() / blob_core.max_integrity) * 100) var/new_maptext = MAPTEXT("
[current_health]%
") - hud_used.healths.maptext = new_maptext + hud_used.screen_objects[HUD_MOB_HEALTH].maptext = new_maptext for(var/mob/living/basic/blob_minion/blobbernaut/blobbernaut in blob_mobs) - if(isnull(blobbernaut.overmind_hud)) - continue - blobbernaut.overmind_hud.maptext = new_maptext + var/atom/movable/screen/overmind_hud = blobbernaut.hud_used?.screen_objects[HUD_BLOBBERNAUT_OVERMIND] + if (overmind_hud) + overmind_hud.maptext = new_maptext /mob/eye/blob/proc/add_points(points) blob_points = clamp(blob_points + points, 0, max_blob_points) - blob_power_hud.maptext = MAPTEXT("
[round(blob_points)]
") + hud_used.screen_objects[HUD_BLOB_POWER_DISPLAY].maptext = MAPTEXT("
[round(blob_points)]
") /mob/eye/blob/say( message, diff --git a/code/modules/antagonists/blood_worm/blood_worm_host_handling.dm b/code/modules/antagonists/blood_worm/blood_worm_host_handling.dm index 67543842cd0..2b87fd4c9f6 100644 --- a/code/modules/antagonists/blood_worm/blood_worm_host_handling.dm +++ b/code/modules/antagonists/blood_worm/blood_worm_host_handling.dm @@ -132,7 +132,7 @@ host.remove_blood_volume_modifier(REF(src)) sync_health(already_ejecting = TRUE) - remove_host_hud() + host.hud_used?.remove_screen_object(HUD_MOB_BLOOD_LEVEL) host.set_blood_volume(0) @@ -245,16 +245,8 @@ UnregisterSignal(host, COMSIG_MOB_HUD_CREATED) var/datum/hud/hud = host.hud_used - blood_display = new(null, hud) - hud.infodisplay += blood_display - hud.show_hud(hud.hud_version) - -/mob/living/basic/blood_worm/proc/remove_host_hud() - var/datum/hud/hud = host.hud_used - - if (!hud) - QDEL_NULL(blood_display) + var/atom/movable/screen/blood_level/blood_display = hud.screen_objects[HUD_MOB_BLOOD_LEVEL] + if (blood_display) return - hud.infodisplay -= blood_display - QDEL_NULL(blood_display) + blood_display = hud.add_screen_object(/atom/movable/screen/blood_level, HUD_MOB_BLOOD_LEVEL, HUD_GROUP_INFO, update_screen = TRUE) diff --git a/code/modules/antagonists/blood_worm/blood_worm_mob.dm b/code/modules/antagonists/blood_worm/blood_worm_mob.dm index a3a960abcd9..6fe2a41391f 100644 --- a/code/modules/antagonists/blood_worm/blood_worm_mob.dm +++ b/code/modules/antagonists/blood_worm/blood_worm_mob.dm @@ -62,9 +62,6 @@ /// This mob is always dead as it's just a mind holder. var/mob/living/blood_worm_host/backseat - /// The blood display on the left side of the screen, which is shown to the blood worm while in a host, if any. - var/atom/movable/screen/blood_level/blood_display - // Innate and shared actions /// Typed, please initialize with a proper action subtype. (empty = no action) diff --git a/code/modules/antagonists/changeling/changeling.dm b/code/modules/antagonists/changeling/changeling.dm index ad138d35d56..1fdf17ef8d7 100644 --- a/code/modules/antagonists/changeling/changeling.dm +++ b/code/modules/antagonists/changeling/changeling.dm @@ -71,11 +71,6 @@ /// A reference to our cellular emporium action (which opens the UI for the datum). var/datum/action/cellular_emporium/emporium_action - /// UI displaying how many chems we have - var/atom/movable/screen/ling/chems/lingchemdisplay - /// UI displayng our currently active sting - var/atom/movable/screen/ling/sting/lingstingdisplay - /// The name of our "hive" that our ling came from. Flavor. var/hive_name @@ -144,23 +139,14 @@ RegisterSignal(living_mob, COMSIG_LIVING_LIFE, PROC_REF(on_life)) RegisterSignal(living_mob, COMSIG_LIVING_POST_FULLY_HEAL, PROC_REF(on_fullhealed)) RegisterSignal(living_mob, COMSIG_CARBON_GAIN_ORGAN, PROC_REF(new_brain)) + RegisterSignal(living_mob, COMSIG_MOB_HUD_CREATED, PROC_REF(on_hud_created)) RegisterSignals(living_mob, list(COMSIG_MOB_MIDDLECLICKON, COMSIG_MOB_ALTCLICKON), PROC_REF(on_click_sting)) ADD_TRAIT(living_mob, TRAIT_FAKE_SOULLESS, CHANGELING_TRAIT) ADD_TRAIT(living_mob, TRAIT_BRAINLESS_CARBON, CHANGELING_TRAIT) ADD_TRAIT(living_mob, TRAIT_CHANGELING_HIVEMIND, CHANGELING_TRAIT) - if(living_mob.hud_used) - var/datum/hud/hud_used = living_mob.hud_used - - lingchemdisplay = new /atom/movable/screen/ling/chems(null, hud_used) - hud_used.infodisplay += lingchemdisplay - - lingstingdisplay = new /atom/movable/screen/ling/sting(null, hud_used) - hud_used.infodisplay += lingstingdisplay - - hud_used.show_hud(hud_used.hud_version) - else - RegisterSignal(living_mob, COMSIG_MOB_HUD_CREATED, PROC_REF(on_hud_created)) + if (living_mob.hud_used) + on_hud_created() make_brain_decoy(living_mob) @@ -193,14 +179,8 @@ SIGNAL_HANDLER var/datum/hud/ling_hud = owner.current.hud_used - - lingchemdisplay = new(null, ling_hud) - ling_hud.infodisplay += lingchemdisplay - - lingstingdisplay = new(null, ling_hud) - ling_hud.infodisplay += lingstingdisplay - - ling_hud.show_hud(ling_hud.hud_version) + ling_hud.add_screen_object(/atom/movable/screen/ling/chems, HUD_CHANGELING_CHEMS, HUD_GROUP_INFO) + ling_hud.add_screen_object(/atom/movable/screen/ling/sting, HUD_CHANGELING_STING, HUD_GROUP_INFO, update_screen = TRUE) /datum/antagonist/changeling/proc/new_brain(mob/living/carbon/ling, obj/item/organ/new_brain) SIGNAL_HANDLER @@ -228,14 +208,12 @@ for(var/mob/eye/imaginary_friend/hivemind/hivemind_member in living_mob.imaginary_group) qdel(hivemind_member) - if(living_mob.hud_used) - var/datum/hud/hud_used = living_mob.hud_used - - hud_used.infodisplay -= lingchemdisplay - hud_used.infodisplay -= lingstingdisplay - QDEL_NULL(lingchemdisplay) - QDEL_NULL(lingstingdisplay) + if(!living_mob.hud_used) + return + var/datum/hud/hud_used = living_mob.hud_used + hud_used.remove_screen_object(HUD_CHANGELING_CHEMS, update = FALSE) + hud_used.remove_screen_object(HUD_CHANGELING_STING) // The old body's brain still remains a decoy, I guess? /datum/antagonist/changeling/on_removal() @@ -351,12 +329,13 @@ ///Updates the Changeling's chemical HUD to display the information we want it to (chem charges, or max if hovered over). /datum/antagonist/changeling/proc/update_chemical_hud(amount) - if(isnull(lingchemdisplay)) + var/atom/movable/screen/ling/chems/chems = owner.current?.hud_used?.screen_objects[HUD_CHANGELING_CHEMS] + if(isnull(chems)) return - if(lingchemdisplay.hovering) - lingchemdisplay.maptext = FORMAT_CHEM_MAX_TEXT(total_chem_storage) + if(chems.hovering) + chems.maptext = FORMAT_CHEM_MAX_TEXT(total_chem_storage) else - lingchemdisplay.maptext = FORMAT_CHEM_CHARGES_TEXT(amount) + chems.maptext = FORMAT_CHEM_CHARGES_TEXT(amount) /* * Remove changeling powers from the current Changeling's purchased_powers list. diff --git a/code/modules/antagonists/changeling/powers/tiny_prick.dm b/code/modules/antagonists/changeling/powers/tiny_prick.dm index 91d7f8ba059..3368417c2c6 100644 --- a/code/modules/antagonists/changeling/powers/tiny_prick.dm +++ b/code/modules/antagonists/changeling/powers/tiny_prick.dm @@ -1,7 +1,8 @@ /datum/action/changeling/sting//parent path, not meant for users afaik - name = "Tiny Prick" + name = "Tiny Prick" //cellularemporium uses `nameToIconState` to button icon state must match this, on top of matching the hud below. desc = "Stabby stabby" category = "stings" + button_icon_state = "sting_null" //This must be equal to the icon state for `/atom/movable/screen/ling/sting` /datum/action/changeling/sting/Trigger(mob/clicker, trigger_flags) var/mob/user = owner @@ -21,16 +22,20 @@ var/datum/antagonist/changeling/changeling = IS_CHANGELING(user) changeling.chosen_sting = src - changeling.lingstingdisplay.icon_state = button_icon_state - changeling.lingstingdisplay.SetInvisibility(0, id=type) + var/atom/movable/screen/ling/sting/sting = user.hud_used?.screen_objects[HUD_CHANGELING_STING] + if (sting) + sting.icon_state = button_icon_state + sting.SetInvisibility(0, id=type) /datum/action/changeling/sting/proc/unset_sting(mob/user) to_chat(user, span_warning("We retract our sting, we can't sting anyone for now.")) var/datum/antagonist/changeling/changeling = IS_CHANGELING(user) changeling.chosen_sting = null - changeling.lingstingdisplay.icon_state = null - changeling.lingstingdisplay.RemoveInvisibility(type) + var/atom/movable/screen/ling/sting/sting = user.hud_used?.screen_objects[HUD_CHANGELING_STING] + if (sting) + sting.icon_state = null + sting.RemoveInvisibility(type) /mob/living/carbon/proc/unset_sting() if(mind) @@ -71,7 +76,7 @@ For complex humanoids, the transformation is temporarily, but the duration is paused while the victim is dead or in stasis. \ For more simple humanoids, such as monkeys, the transformation is permanent. \ Does not provide a warning to others. Mutations will not be transferred." - button_icon_state = "sting_transform" + button_icon_state = "transformation_sting" chemical_cost = 33 // Low enough that you can sting only two people in quick succession dna_cost = 2 /// A reference to our active profile, which we grab DNA from diff --git a/code/modules/antagonists/cult/datums/cult_team.dm b/code/modules/antagonists/cult/datums/cult_team.dm index 130683a9046..939938f621c 100644 --- a/code/modules/antagonists/cult/datums/cult_team.dm +++ b/code/modules/antagonists/cult/datums/cult_team.dm @@ -169,7 +169,8 @@ SEND_SOUND(cultist.current, sound(SFX_HALLUCINATION_OVER_HERE, 0, 1, 75)) cultist.current.client.images += blood_target_image if (cultist.current.hud_used) - new /atom/movable/screen/navigate_arrow(null, cultist.current.hud_used, get_turf(new_target), COLOR_CULT_RED) + var/atom/movable/screen/navigate_arrow/arrow = cultist.current.hud_used.add_screen_object(/atom/movable/screen/navigate_arrow, HUD_CULTIST_ARROW, HUD_GROUP_INFO, update_screen = TRUE) + arrow.start_effect(get_turf(new_target), COLOR_CULT_RED) if(duration != INFINITY) blood_target_reset_timer = addtimer(CALLBACK(src, PROC_REF(unset_blood_target)), duration, TIMER_STOPPABLE) diff --git a/code/modules/antagonists/heretic/heretic_living_heart.dm b/code/modules/antagonists/heretic/heretic_living_heart.dm index f8f18a8188e..78256b12a63 100644 --- a/code/modules/antagonists/heretic/heretic_living_heart.dm +++ b/code/modules/antagonists/heretic/heretic_living_heart.dm @@ -249,7 +249,8 @@ arrow_color = COLOR_RED if(owner.hud_used) - new /atom/movable/screen/navigate_arrow(null, owner.hud_used, their_turf, arrow_color) + var/atom/movable/screen/navigate_arrow/arrow = owner.hud_used.add_screen_object(/atom/movable/screen/navigate_arrow, HUD_HERETIC_ARROW, HUD_GROUP_INFO, update_screen = TRUE) + arrow.start_effect(their_turf, arrow_color) if(ismob(tracked_thing)) var/mob/tracked_mob = tracked_thing @@ -265,25 +266,21 @@ pixel_x = -32 pixel_y = -32 mouse_opacity = MOUSE_OPACITY_TRANSPARENT + screen_loc = around_player -/atom/movable/screen/navigate_arrow/Initialize(mapload, datum/hud/hud_owner, turf/tracked_turf, arrow_color) - . = ..() +/atom/movable/screen/navigate_arrow/proc/start_effect(turf/tracked_turf, arrow_color) var/mob/owner = get_mob() if (owner) animate(src, transform = matrix(get_angle(owner, tracked_turf), MATRIX_ROTATE), 0.2 SECONDS) - screen_loc = around_player color = arrow_color - if (hud) - hud.infodisplay += src - hud.show_hud(hud.hud_version) addtimer(CALLBACK(src, PROC_REF(end_effect)), 1.6 SECONDS) +/atom/movable/screen/navigate_arrow/Destroy() + var/datum/hud/our_hud = hud + . = ..() + if (!QDELETED(our_hud)) + INVOKE_ASYNC(our_hud, TYPE_PROC_REF(/datum/hud, show_hud), our_hud.hud_version) + /atom/movable/screen/navigate_arrow/proc/end_effect() icon_state = "navigate_arrow_disappear" - addtimer(CALLBACK(src, PROC_REF(null_arrow)), 0.4 SECONDS) - -/atom/movable/screen/navigate_arrow/proc/null_arrow() - if (hud) - hud.infodisplay -= src - hud.show_hud(hud.hud_version) - qdel(src) + QDEL_IN(src, 0.4 SECONDS) diff --git a/code/modules/antagonists/heretic/items/heretic_armor.dm b/code/modules/antagonists/heretic/items/heretic_armor.dm index 8e496353fae..20cdbed7a9a 100644 --- a/code/modules/antagonists/heretic/items/heretic_armor.dm +++ b/code/modules/antagonists/heretic/items/heretic_armor.dm @@ -533,8 +533,6 @@ TRAIT_PACIFISM, TRAIT_NOHUNGER ) - /// Hud that gets shown to the wearer, gives a rough estimate of their current brain damage - var/atom/movable/screen/moon_health/health_hud /// Boolean if you are brain dead so the sound doesn't spam during the delay var/braindead = FALSE //---- Messages that get sent when someone wearing the moon robes is attacked @@ -624,8 +622,7 @@ if(our_brain) REMOVE_TRAIT(our_brain, TRAIT_BRAIN_DAMAGE_NODEATH, REF(src)) braindead = FALSE - if(health_hud in user.hud_used.infodisplay) - on_hud_remove(user) + on_hud_remove(user) /obj/item/clothing/suit/hooded/cultrobes/eldritch/moon/proc/on_apply_modifiers(mob/living/user, damage_mods, damage, damagetype, def_zone, sharpness, attack_direction, attacking_item) SIGNAL_HANDLER @@ -655,35 +652,30 @@ /obj/item/clothing/suit/hooded/cultrobes/eldritch/moon/proc/on_hud_created(mob/living/carbon/human/wearer) SIGNAL_HANDLER var/datum/hud/original_hud = wearer.hud_used - // Remove the old health elements - var/list/to_remove = list(/atom/movable/screen/stamina, /atom/movable/screen/healths, /atom/movable/screen/healthdoll/human) - for(var/removing in original_hud.infodisplay) - if(is_type_in_list(removing, to_remove)) - original_hud.infodisplay -= removing - QDEL_NULL(removing) + + for(var/removing in list(HUD_MOB_STAMINA, HUD_MOB_HEALTH, HUD_MOB_HEALTHDOLL)) + var/atom/movable/screen/to_remove = original_hud.screen_objects[removing] + if (to_remove) + to_remove.SetInvisibility(INVISIBILITY_ABSTRACT, type) wearer.mob_mood.unmodify_hud() // Add the moon health hud element - health_hud = new(null, original_hud) - original_hud.infodisplay += health_hud - original_hud.show_hud(original_hud.hud_version) + original_hud.add_screen_object(/atom/movable/screen/moon_health, HUD_HERETIC_MOON_HEALTH, HUD_GROUP_INFO, update_screen = TRUE) UnregisterSignal(wearer, COMSIG_MOB_HUD_CREATED) signal_registered -= COMSIG_MOB_HUD_CREATED /// Removes the HUD element from the wearer /obj/item/clothing/suit/hooded/cultrobes/eldritch/moon/proc/on_hud_remove(mob/living/carbon/human/wearer) var/datum/hud/original_hud = wearer.hud_used - original_hud.infodisplay -= health_hud - QDEL_NULL(health_hud) + QDEL_NULL(original_hud.screen_objects[HUD_HERETIC_MOON_HEALTH]) // Restore the old health elements - var/atom/movable/screen/stamina/stamina_hud = new(null, original_hud) - var/atom/movable/screen/healths/old_health_hud = new(null, original_hud) - var/atom/movable/screen/healthdoll/human/health_doll_hud = new(null, original_hud) - original_hud.infodisplay += stamina_hud - original_hud.infodisplay += old_health_hud - original_hud.infodisplay += health_doll_hud + for(var/restoring in list(HUD_MOB_STAMINA, HUD_MOB_HEALTH, HUD_MOB_HEALTHDOLL)) + var/atom/movable/screen/to_restore = original_hud.screen_objects[restoring] + if (to_restore) + to_restore.RemoveInvisibility(type) + + // Updates HUD on its own wearer.mob_mood.modify_hud() - original_hud.show_hud(original_hud.hud_version) /obj/item/clothing/suit/hooded/cultrobes/eldritch/moon/can_mob_unequip(mob/user) if(!ishuman(user)) diff --git a/code/modules/antagonists/wizard/equipment/spellbook_entries/perks.dm b/code/modules/antagonists/wizard/equipment/spellbook_entries/perks.dm index 087f9b6a16b..d676c284daa 100644 --- a/code/modules/antagonists/wizard/equipment/spellbook_entries/perks.dm +++ b/code/modules/antagonists/wizard/equipment/spellbook_entries/perks.dm @@ -7,44 +7,28 @@ requires_wizard_garb = FALSE /// Icon that will be shown on wizard hud when purchasing a perk. var/hud_icon - /// Type path to perks hud. - var/atom/movable/screen/perk/hud_to_show = /atom/movable/screen/perk /datum/spellbook_entry/perks/buy_spell(mob/living/carbon/human/user, obj/item/spellbook/book, log_buy) var/datum/antagonist/wizard/wizard_datum = user.mind.has_antag_datum(/datum/antagonist/wizard) if(wizard_datum) wizard_datum.perks += src - create_hud_icon(user, wizard_datum) + RegisterSignal(user, COMSIG_MOB_HUD_CREATED, PROC_REF(on_hud_created)) + if (user.hud_used) + on_hud_created() to_chat(user, span_notice("You got a new perk: [src.name].")) log_purchase(user.key) return TRUE -/datum/spellbook_entry/perks/proc/create_compact_button(mob/living/carbon/human/user, datum/antagonist/wizard/wizard_datum) - var/datum/hud/user_hud = user.hud_used - wizard_datum.compact_button = new /atom/movable/screen/perk/more(null, user_hud) - wizard_datum.compact_button.screen_loc = ui_perk_position(0) - user_hud.infodisplay += wizard_datum.compact_button - user_hud.show_hud(user_hud.hud_version) - -/datum/spellbook_entry/perks/proc/create_hud_icon(mob/living/carbon/human/user, datum/antagonist/wizard/wizard_datum) - if(user.hud_used) - var/datum/hud/user_hud = user.hud_used - if(isnull(wizard_datum.compact_button)) - create_compact_button(user, wizard_datum) - hud_to_show = new hud_to_show(null, user_hud) - hud_to_show.name = name - hud_to_show.icon_state = hud_icon - hud_to_show.screen_loc = ui_perk_position(wizard_datum.perks.len) - user_hud.infodisplay += hud_to_show - user_hud.show_hud(user_hud.hud_version) - wizard_datum.compact_button.perks_on_hud += hud_to_show - else - RegisterSignal(user, COMSIG_MOB_HUD_CREATED, wizard_datum, PROC_REF(on_hud_created)) - /datum/spellbook_entry/perks/proc/on_hud_created(mob/living/carbon/human/user, datum/antagonist/wizard/wizard_datum) SIGNAL_HANDLER - create_hud_icon(user, wizard_datum) + var/datum/hud/user_hud = user.hud_used + if(!user_hud.screen_objects[HUD_WIZARD_COMPACT_PERKS]) + user_hud.add_screen_object(/atom/movable/screen/perk/more, HUD_WIZARD_COMPACT_PERKS, HUD_GROUP_INFO, ui_loc = ui_perk_position(0), update_screen = TRUE) + + var/atom/movable/screen/perk/perk = user_hud.add_screen_object(/atom/movable/screen/perk, HUD_WIZARD_PERK(length(wizard_datum.perks)), HUD_GROUP_INFO, ui_loc = ui_perk_position(length(wizard_datum.perks)), update_screen = TRUE) + perk.name = name + perk.icon_state = hud_icon /datum/spellbook_entry/perks/fourhands name = "Four Hands" diff --git a/code/modules/antagonists/wizard/wizard.dm b/code/modules/antagonists/wizard/wizard.dm index ce38b05c426..d76d90a35c8 100644 --- a/code/modules/antagonists/wizard/wizard.dm +++ b/code/modules/antagonists/wizard/wizard.dm @@ -28,8 +28,6 @@ GLOBAL_LIST_EMPTY(wizard_spellbook_purchases_by_key) var/datum/action/cooldown/grand_ritual/ritual /// Perks that wizard learn var/list/perks = list() - /// Button that hide perks hud. - var/atom/movable/screen/perk/more/compact_button /datum/antagonist/wizard_minion name = "Wizard Minion" diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index dd280d120f5..af6789d02f4 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -295,7 +295,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) return TRUE /datum/preferences/proc/create_character_preview_view(mob/user) - character_preview_view = new(null, src) + character_preview_view = new(null, null, src) character_preview_view.generate_view("character_preview_[REF(character_preview_view)]") character_preview_view.update_body() @@ -348,7 +348,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) /// Whether we show current job clothes or nude/loadout only var/show_job_clothes = TRUE -/atom/movable/screen/map_view/char_preview/Initialize(mapload, datum/preferences/preferences) +/atom/movable/screen/map_view/char_preview/Initialize(mapload, datum/hud/hud_owner, datum/preferences/preferences) . = ..() src.preferences = preferences diff --git a/code/modules/clothing/spacesuits/_spacesuits.dm b/code/modules/clothing/spacesuits/_spacesuits.dm index d5283c7c20c..f4535059a05 100644 --- a/code/modules/clothing/spacesuits/_spacesuits.dm +++ b/code/modules/clothing/spacesuits/_spacesuits.dm @@ -123,7 +123,9 @@ STOP_PROCESSING(SSobj, src) var/mob/living/carbon/human/human_user = user if(istype(human_user) && human_user.hud_used) - human_user.hud_used.spacesuit_hud.update_spacesuit_hud_icon(SPACESUIT_NO_ICON) + var/atom/movable/screen/spacesuit/spacesuit_hud = human_user.hud_used.screen_objects[HUD_MOB_SPACESUIT] + if (spacesuit_hud) + spacesuit_hud.update_spacesuit_hud_icon(SPACESUIT_NO_ICON) // Space Suit temperature regulation and power usage /obj/item/clothing/suit/space/process(seconds_per_tick) @@ -159,7 +161,9 @@ QDEL_NULL(cell) var/mob/living/carbon/human/human = src.loc if(istype(human) && human.hud_used) - human.hud_used.spacesuit_hud.update_spacesuit_hud_icon(SPACESUIT_NO_ICON) + var/atom/movable/screen/spacesuit/spacesuit_hud = human.hud_used.screen_objects[HUD_MOB_SPACESUIT] + if (spacesuit_hud) + spacesuit_hud.update_spacesuit_hud_icon(SPACESUIT_NO_ICON) STOP_PROCESSING(SSobj, src) return ..() @@ -306,8 +310,12 @@ if(!show_hud || human.wear_suit != src || isnull(human.hud_used)) return + var/atom/movable/screen/spacesuit/spacesuit_hud = human.hud_used.screen_objects[HUD_MOB_SPACESUIT] + if(!spacesuit_hud) + return + if(!cell) - human.hud_used.spacesuit_hud.update_spacesuit_hud_icon(SPACESUIT_CELL_MISSING, 0, thermal_on) + spacesuit_hud.update_spacesuit_hud_icon(SPACESUIT_CELL_MISSING, 0, thermal_on) return var/cell_percent = cell.percent() @@ -315,17 +323,17 @@ // if there is, whethere the cell's capacity indicates high, medium or low // charge based on it. if(cell.charge < THERMAL_REGULATOR_COST) - human.hud_used.spacesuit_hud.update_spacesuit_hud_icon(SPACESUIT_CELL_EMPTY, cell_percent, thermal_on) + spacesuit_hud.update_spacesuit_hud_icon(SPACESUIT_CELL_EMPTY, cell_percent, thermal_on) return switch(cell_percent) if(0 to 20) - human.hud_used.spacesuit_hud.update_spacesuit_hud_icon(SPACESUIT_CELL_VERY_LOW, cell_percent, thermal_on) + spacesuit_hud.update_spacesuit_hud_icon(SPACESUIT_CELL_VERY_LOW, cell_percent, thermal_on) if(21 to 40) - human.hud_used.spacesuit_hud.update_spacesuit_hud_icon(SPACESUIT_CELL_LOW, cell_percent, thermal_on) + spacesuit_hud.update_spacesuit_hud_icon(SPACESUIT_CELL_LOW, cell_percent, thermal_on) if(41 to 60) - human.hud_used.spacesuit_hud.update_spacesuit_hud_icon(SPACESUIT_CELL_MID, cell_percent, thermal_on) + spacesuit_hud.update_spacesuit_hud_icon(SPACESUIT_CELL_MID, cell_percent, thermal_on) if(61 to 100) - human.hud_used.spacesuit_hud.update_spacesuit_hud_icon(SPACESUIT_CELL_HIGH, cell_percent, thermal_on) + spacesuit_hud.update_spacesuit_hud_icon(SPACESUIT_CELL_HIGH, cell_percent, thermal_on) // zap the cell if we get hit with an emp /obj/item/clothing/suit/space/emp_act(severity) diff --git a/code/modules/engineering/tools/multitool.dm b/code/modules/engineering/tools/multitool.dm deleted file mode 100644 index 47f4857ffc3..00000000000 --- a/code/modules/engineering/tools/multitool.dm +++ /dev/null @@ -1,11 +0,0 @@ -/atom/movable/screen/multitool_arrow - icon = 'icons/effects/96x96.dmi' - icon_state = "multitool_arrow" - pixel_x = -32 - pixel_y = -32 - -/atom/movable/screen/multitool_arrow/Destroy() - if(hud) - hud.infodisplay -= src - INVOKE_ASYNC(hud, TYPE_PROC_REF(/datum/hud, show_hud), hud.hud_version) - return ..() diff --git a/code/modules/escape_menu/escape_menu.dm b/code/modules/escape_menu/escape_menu.dm index 842d70a8c77..0042a6f7332 100644 --- a/code/modules/escape_menu/escape_menu.dm +++ b/code/modules/escape_menu/escape_menu.dm @@ -151,9 +151,6 @@ GLOBAL_LIST_EMPTY(escape_menus) plane = ESCAPE_MENU_PLANE clear_with_screen = FALSE -// The escape menu can be opened before SSatoms -INITIALIZE_IMMEDIATE(/atom/movable/screen/escape_menu) - #undef PAGE_HOME #undef PAGE_LEAVE_BODY #undef PAGE_QUIT_GAME diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 80d383faba9..1a8e2a7c00f 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -644,8 +644,9 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp else remove_data_huds() update_sight() - for(var/atom/movable/screen/ghost/hudbox/hud in hud_used?.static_inventory) - if(hud.relevant_flag & toggled) + for(var/hud_key in hud_used?.screen_objects) + var/atom/movable/screen/ghost/hudbox/hud = hud_used.screen_objects[hud_key] + if(istype(hud) && (hud.relevant_flag & toggled)) hud.update_appearance(UPDATE_ICON_STATE) // This is the ghost's follow verb with an argument diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm index 4c57ced89bb..5fd9172e160 100644 --- a/code/modules/mob/inventory.dm +++ b/code/modules/mob/inventory.dm @@ -675,9 +675,13 @@ dropItemToGround(held_items[i]) held_items.len = amt - if(hud_used) - hud_used.build_hand_slots() - hud_used.healthdoll.update_body_zones() + if(!hud_used) + return + + hud_used.build_hand_slots(update_hud = TRUE) + var/atom/movable/screen/healthdoll/doll = hud_used.screen_objects[HUD_MOB_HEALTHDOLL] + if(doll) + doll.update_body_zones() //GetAllContents that is reasonable and not stupid /mob/living/proc/get_all_gear(equipment_flags = INCLUDE_ACCESSORIES|INCLUDE_PROSTHETICS, recursive = TRUE) diff --git a/code/modules/mob/living/basic/blob_minions/blobbernaut.dm b/code/modules/mob/living/basic/blob_minions/blobbernaut.dm index bbc9c1be16f..703fd0d4d1d 100644 --- a/code/modules/mob/living/basic/blob_minions/blobbernaut.dm +++ b/code/modules/mob/living/basic/blob_minions/blobbernaut.dm @@ -27,8 +27,6 @@ mob_size = MOB_SIZE_LARGE ai_controller = /datum/ai_controller/basic_controller/blobbernaut loot = null - ///The HUD given to blobbernauts, updated by the Blob itself - var/atom/movable/screen/healths/blob/overmind/overmind_hud ///The overlay for veins. var/mutable_appearance/vein_overlay ///The overlay for our eyes @@ -53,11 +51,6 @@ AddComponent(/datum/component/tameable, food_types = food_types, tame_chance = 25, bonus_tame_chance = 15) update_appearance() - -/mob/living/basic/blob_minion/blobbernaut/Destroy() - QDEL_NULL(overmind_hud) - return ..() - /mob/living/basic/blob_minion/blobbernaut/death(gibbed) flick("[icon_state]_death", src) playsound(src, 'sound/mobs/non-humanoids/blobmob/blobbernaut_death.ogg', 100, TRUE) @@ -68,9 +61,7 @@ . = ..() if(!.) return - overmind_hud = new(null, hud_used) - hud_used.infodisplay += overmind_hud - hud_used.show_hud(hud_used.hud_version) + hud_used.add_screen_object(/atom/movable/screen/healths/blob/overmind, HUD_BLOBBERNAUT_OVERMIND, HUD_GROUP_INFO, update_screen = TRUE) /mob/living/basic/blob_minion/blobbernaut/on_strain_updated(mob/eye/blob/overmind, datum/blobstrain/new_strain) . = ..() diff --git a/code/modules/mob/living/basic/space_fauna/revenant/_revenant.dm b/code/modules/mob/living/basic/space_fauna/revenant/_revenant.dm index 436f8e27c89..ea32e7e5d6d 100644 --- a/code/modules/mob/living/basic/space_fauna/revenant/_revenant.dm +++ b/code/modules/mob/living/basic/space_fauna/revenant/_revenant.dm @@ -182,7 +182,7 @@ essencecolor = "#9A5ACB" //oh boy you've got a lot of essence else if(essence <= 0) essencecolor = "#1D2953" //oh jeez you're dying - hud_used.healths.maptext = MAPTEXT("
[essence]E
") + hud_used.screen_objects[HUD_MOB_HEALTH]?.maptext = MAPTEXT("
[essence]E
") /mob/living/basic/revenant/say( message, diff --git a/code/modules/mob/living/carbon/alien/adult/alien_powers.dm b/code/modules/mob/living/carbon/alien/adult/alien_powers.dm index 928b5e16bdd..5633d54fb53 100644 --- a/code/modules/mob/living/carbon/alien/adult/alien_powers.dm +++ b/code/modules/mob/living/carbon/alien/adult/alien_powers.dm @@ -390,12 +390,7 @@ Doesn't work on other aliens/AI.*/ var/obj/item/organ/alien/plasmavessel/vessel = get_organ_by_type(/obj/item/organ/alien/plasmavessel) if(!vessel) return FALSE - vessel.stored_plasma = max(vessel.stored_plasma + amount,0) - vessel.stored_plasma = min(vessel.stored_plasma, vessel.max_plasma) //upper limit of max_plasma, lower limit of 0 + vessel.adjust_plasma(amount) for(var/datum/action/cooldown/alien/ability in actions) ability.build_all_button_icons() return TRUE - -/mob/living/carbon/alien/adjustPlasma(amount) - . = ..() - updatePlasmaDisplay() diff --git a/code/modules/mob/living/carbon/alien/adult/caste/hunter.dm b/code/modules/mob/living/carbon/alien/adult/caste/hunter.dm index c056f663849..995235d5fa2 100644 --- a/code/modules/mob/living/carbon/alien/adult/caste/hunter.dm +++ b/code/modules/mob/living/carbon/alien/adult/caste/hunter.dm @@ -18,7 +18,6 @@ ORGAN_SLOT_EXTERNAL_TAIL = /obj/item/organ/tail/xeno, ) - var/atom/movable/screen/leap_icon = null ///How fast does our pounce move us? var/pounce_speed = 2 @@ -26,7 +25,8 @@ /mob/living/carbon/alien/adult/hunter/proc/toggle_leap(message = 1) leap_on_click = !leap_on_click - leap_icon.icon_state = "leap_[leap_on_click ? "on":"off"]" + var/atom/movable/screen/leap_icon = hud_used?.screen_objects[HUD_ALIEN_HUNTER_LEAP] + leap_icon?.icon_state = "leap_[leap_on_click ? "on":"off"]" update_icons() if(message) to_chat(src, span_noticealien("You will now [leap_on_click ? "leap at":"slash at"] enemies!")) diff --git a/code/modules/mob/living/carbon/alien/organs.dm b/code/modules/mob/living/carbon/alien/organs.dm index f5705c88494..ebbacdf2c02 100644 --- a/code/modules/mob/living/carbon/alien/organs.dm +++ b/code/modules/mob/living/carbon/alien/organs.dm @@ -56,38 +56,55 @@ //Instantly healing to max health in a single tick would be silly. If it takes 8 seconds to fire, then something's fucked. var/delta_time_capped = min(delta_time, 8) //If there are alien weeds on the ground then heal if needed or give some plasma - if(locate(/obj/structure/alien/weeds) in owner.loc) - if(owner.health >= owner.maxHealth) - owner.adjustPlasma(plasma_rate * delta_time) - else - var/heal_amt = heal_rate - if(!isalien(owner)) - heal_amt *= 0.2 - owner.adjustPlasma(0.5 * plasma_rate * delta_time_capped) - owner.adjust_brute_loss(-heal_amt * delta_time_capped) - owner.adjust_fire_loss(-heal_amt * delta_time_capped) - owner.adjust_oxy_loss(-heal_amt * delta_time_capped) - else + if(!(locate(/obj/structure/alien/weeds) in owner.loc)) owner.adjustPlasma(0.1 * plasma_rate * delta_time) + return + + if(owner.health >= owner.maxHealth) + owner.adjustPlasma(plasma_rate * delta_time) + return + + var/heal_amt = heal_rate + if(!isalien(owner)) + heal_amt *= 0.2 + owner.adjustPlasma(0.5 * plasma_rate * delta_time_capped) + owner.adjust_brute_loss(-heal_amt * delta_time_capped) + owner.adjust_fire_loss(-heal_amt * delta_time_capped) + owner.adjust_oxy_loss(-heal_amt * delta_time_capped) + +/obj/item/organ/alien/plasmavessel/proc/adjust_plasma(amount) + stored_plasma = clamp(stored_plasma + amount, 0, max_plasma) + update_plasma_display() + +/obj/item/organ/alien/plasmavessel/proc/on_hud_created(mob/source) + SIGNAL_HANDLER + + if (!owner.hud_used.screen_objects[HUD_ALIEN_PLASMA_DISPLAY]) + owner.hud_used.add_screen_object(/atom/movable/screen/alien/plasma_display, HUD_ALIEN_PLASMA_DISPLAY, HUD_GROUP_INFO, ui_loc = istype(owner.hud_used, /datum/hud/alien) ? null : ui_alienplasmadisplay_human, update_screen = TRUE) + update_plasma_display() /obj/item/organ/alien/plasmavessel/on_mob_insert(mob/living/carbon/organ_owner) . = ..() - if(isalien(organ_owner)) - var/mob/living/carbon/alien/target_alien = organ_owner - target_alien.updatePlasmaDisplay() RegisterSignal(organ_owner, COMSIG_MOB_GET_STATUS_TAB_ITEMS, PROC_REF(get_status_tab_item)) + RegisterSignal(organ_owner, COMSIG_MOB_HUD_CREATED, PROC_REF(on_hud_created)) + if (organ_owner.hud_used) + on_hud_created() /obj/item/organ/alien/plasmavessel/on_mob_remove(mob/living/carbon/organ_owner) . = ..() - if(isalien(organ_owner)) - var/mob/living/carbon/alien/organ_owner_alien = organ_owner - organ_owner_alien.updatePlasmaDisplay() UnregisterSignal(organ_owner, COMSIG_MOB_GET_STATUS_TAB_ITEMS) + UnregisterSignal(organ_owner, COMSIG_MOB_HUD_CREATED) + organ_owner.hud_used?.remove_screen_object(HUD_ALIEN_PLASMA_DISPLAY) /obj/item/organ/alien/plasmavessel/proc/get_status_tab_item(mob/living/carbon/source, list/items) SIGNAL_HANDLER items += "Plasma Stored: [stored_plasma]/[max_plasma]" +/obj/item/organ/alien/plasmavessel/proc/update_plasma_display() + owner.hud_used?.screen_objects[HUD_ALIEN_PLASMA_DISPLAY]?.maptext = MAPTEXT( \ + "
[round(owner.getPlasma())]
" \ + ) + #define QUEEN_DEATH_DEBUFF_DURATION 2400 /obj/item/organ/alien/hivenode diff --git a/code/modules/mob/living/carbon/alien/screen.dm b/code/modules/mob/living/carbon/alien/screen.dm index ca75bb2d789..1526f78a320 100644 --- a/code/modules/mob/living/carbon/alien/screen.dm +++ b/code/modules/mob/living/carbon/alien/screen.dm @@ -1,33 +1,30 @@ -/mob/living/carbon/alien/proc/updatePlasmaDisplay() - if(hud_used) //clientless aliens - hud_used.alien_plasma_display.maptext = MAPTEXT("
[round(getPlasma())]
") - -/mob/living/carbon/alien/larva/updatePlasmaDisplay() - return - /mob/living/carbon/alien/proc/findQueen() - if(hud_used) - hud_used.alien_queen_finder.cut_overlays() - var/mob/queen = get_alien_type(/mob/living/carbon/alien/adult/royal/queen) - if(!queen) - return - var/turf/Q = get_turf(queen) - var/turf/A = get_turf(src) - if(Q.z != A.z) //The queen is on a different Z level, we cannot sense that far. - return - var/Qdir = get_dir(src, Q) - var/Qdist = get_dist(src, Q) - var/finder_icon = "finder_center" //Overlay showed when adjacent to or on top of the queen! - switch(Qdist) - if(2 to 7) - finder_icon = "finder_near" - if(8 to 20) - finder_icon = "finder_med" - if(21 to INFINITY) - finder_icon = "finder_far" - var/image/finder_eye = image('icons/hud/screen_alien.dmi', finder_icon, dir = Qdir) - hud_used.alien_queen_finder.add_overlay(finder_eye) + if(!hud_used) + return + var/atom/movable/screen/alien/alien_queen_finder/finder = hud_used.screen_objects[HUD_ALIEN_QUEEN_FINDER] + if (!finder) + return + finder.cut_overlays() + var/mob/queen = get_alien_type(/mob/living/carbon/alien/adult/royal/queen) + if(!queen) + return + var/turf/Q = get_turf(queen) + var/turf/A = get_turf(src) + if(Q.z != A.z) //The queen is on a different Z level, we cannot sense that far. + return + var/Qdir = get_dir(src, Q) + var/Qdist = get_dist(src, Q) + var/finder_icon = "finder_center" //Overlay showed when adjacent to or on top of the queen! + switch(Qdist) + if(2 to 7) + finder_icon = "finder_near" + if(8 to 20) + finder_icon = "finder_med" + if(21 to INFINITY) + finder_icon = "finder_far" + var/image/finder_eye = image('icons/hud/screen_alien.dmi', finder_icon, dir = Qdir) + finder.add_overlay(finder_eye) /mob/living/carbon/alien/adult/royal/queen/findQueen() return //Queen already knows where she is. Hopefully. diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 514e7035cba..924227483a9 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -635,11 +635,16 @@ clear_fullscreen("brute") /mob/living/carbon/update_health_hud(shown_health_amount) - if(!client || !hud_used?.healths) + if(!client || !hud_used) + return + + var/atom/movable/screen/healths/health_hud = hud_used.screen_objects[HUD_MOB_HEALTH] + + if (!health_hud) return if(stat == DEAD) - hud_used.healths.icon_state = "health7" + health_hud.icon_state = "health7" return if(SEND_SIGNAL(src, COMSIG_CARBON_UPDATING_HEALTH_HUD, shown_health_amount) & COMPONENT_OVERRIDE_HEALTH_HUD) @@ -649,25 +654,11 @@ shown_health_amount = health if(shown_health_amount >= maxHealth) - hud_used.healths.icon_state = "health0" - - else if(shown_health_amount > maxHealth * 0.8) - hud_used.healths.icon_state = "health1" - - else if(shown_health_amount > maxHealth * 0.6) - hud_used.healths.icon_state = "health2" - - else if(shown_health_amount > maxHealth * 0.4) - hud_used.healths.icon_state = "health3" - - else if(shown_health_amount > maxHealth*0.2) - hud_used.healths.icon_state = "health4" - - else if(shown_health_amount > 0) - hud_used.healths.icon_state = "health5" - + health_hud.icon_state = "health0" + else if(shown_health_amount > 0 && maxHealth > 0) + health_hud.icon_state = "health[6 - ceil(shown_health_amount / (maxHealth * 0.2))]" else - hud_used.healths.icon_state = "health6" + health_hud.icon_state = "health6" /mob/living/carbon/set_health(new_value) . = ..() diff --git a/code/modules/mob/living/carbon/carbon_update_icons.dm b/code/modules/mob/living/carbon/carbon_update_icons.dm index b759c290efe..fb1ceda9558 100644 --- a/code/modules/mob/living/carbon/carbon_update_icons.dm +++ b/code/modules/mob/living/carbon/carbon_update_icons.dm @@ -417,11 +417,11 @@ //update whether handcuffs appears on our hud. /mob/living/carbon/proc/update_hud_handcuffed() - if(hud_used) - for(var/hand in hud_used.hand_slots) - var/atom/movable/screen/inventory/hand/H = hud_used.hand_slots[hand] - if(H) - H.update_appearance() + if(!hud_used) + return + + for(var/atom/movable/screen/inventory/hand/hand in hud_used.hand_slots) + hand.update_appearance() //update whether our head item appears on our hud. /mob/living/carbon/proc/update_hud_head(obj/item/I) diff --git a/code/modules/mob/living/carbon/human/_species.dm b/code/modules/mob/living/carbon/human/_species.dm index 75dbe2f24e9..72f9968d250 100644 --- a/code/modules/mob/living/carbon/human/_species.dm +++ b/code/modules/mob/living/carbon/human/_species.dm @@ -381,7 +381,9 @@ GLOBAL_LIST_EMPTY(features_by_species) human_who_gained_species.butcher_results = knife_butcher_results?.Copy() //update body zones to match what they are supposed to have - human_who_gained_species.hud_used?.healthdoll.update_body_zones() + var/atom/movable/screen/healthdoll/doll = human_who_gained_species.hud_used?.screen_objects[HUD_MOB_HEALTHDOLL] + if (doll) + doll.update_body_zones() if(old_species.type != type) replace_body(human_who_gained_species, src) @@ -433,7 +435,7 @@ GLOBAL_LIST_EMPTY(features_by_species) human_who_gained_species.living_flags &= ~STOP_OVERLAY_UPDATE_BODY_PARTS //we don't allow it to update during species transition, so update it now - human_who_gained_species.hud_used?.healthdoll.update_appearance() + human_who_gained_species.hud_used?.screen_objects[HUD_MOB_HEALTHDOLL]?.update_appearance() /** * Proc called when a carbon is no longer this species. diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index bfac199095d..9d78211d91f 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -690,7 +690,7 @@ . = ..() // Handles changing limb colors and stuff if(!(living_flags & STOP_OVERLAY_UPDATE_BODY_PARTS)) - hud_used.healthdoll?.update_appearance() + hud_used.screen_objects[HUD_MOB_HEALTHDOLL]?.update_appearance() /mob/living/carbon/human/fully_heal(heal_flags = HEAL_ALL) if(heal_flags & HEAL_NEGATIVE_MUTATIONS) diff --git a/code/modules/mob/living/carbon/human/species_types/vampire.dm b/code/modules/mob/living/carbon/human/species_types/vampire.dm index 0539776acbe..6013c6d2b92 100644 --- a/code/modules/mob/living/carbon/human/species_types/vampire.dm +++ b/code/modules/mob/living/carbon/human/species_types/vampire.dm @@ -21,8 +21,6 @@ mutanttongue = /obj/item/organ/tongue/vampire ///some starter text sent to the vampire initially, because vampires have shit to do to stay alive var/info_text = "You are a Vampire. You will slowly but constantly lose blood if outside of a coffin. If inside a coffin, you will slowly heal. You may gain more blood by grabbing a live victim and using your drain ability." - /// UI displaying how much blood we have - var/atom/movable/screen/blood_level/blood_display /datum/species/human/vampire/check_roundstart_eligible() if(check_holidays(HALLOWEEN)) @@ -35,17 +33,14 @@ new_vampire.skin_tone = "albino" new_vampire.update_body(0) RegisterSignal(new_vampire, COMSIG_ATOM_ATTACKBY, PROC_REF(on_attackby)) + RegisterSignal(new_vampire, COMSIG_MOB_HUD_CREATED, PROC_REF(on_hud_created)) if(new_vampire.hud_used) on_hud_created(new_vampire) - else - RegisterSignal(new_vampire, COMSIG_MOB_HUD_CREATED, PROC_REF(on_hud_created)) /datum/species/human/vampire/on_species_loss(mob/living/carbon/human/old_vampire, datum/species/new_species, pref_load) . = ..() UnregisterSignal(old_vampire, COMSIG_ATOM_ATTACKBY) - if(blood_display) - old_vampire.hud_used.infodisplay -= blood_display - QDEL_NULL(blood_display) + old_vampire.hud_used?.remove_screen_object(HUD_MOB_BLOOD_LEVEL) /datum/species/human/vampire/spec_life(mob/living/carbon/human/vampire, seconds_per_tick) . = ..() @@ -72,10 +67,7 @@ ///Gives the blood HUD to the vampire so they always know how much blood they have. /datum/species/human/vampire/proc/on_hud_created(mob/source) SIGNAL_HANDLER - var/datum/hud/blood_hud = source.hud_used - blood_display = new(null, blood_hud) - blood_hud.infodisplay += blood_display - blood_hud.show_hud(blood_hud.hud_version) + source.hud_used.add_screen_object(/atom/movable/screen/blood_level, HUD_MOB_BLOOD_LEVEL, HUD_GROUP_INFO, update_screen = TRUE) /datum/species/human/vampire/proc/on_attackby(mob/living/source, obj/item/attacking_item, mob/living/attacker, list/modifiers, list/attack_modifiers) SIGNAL_HANDLER diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 9d6ca3159d6..a0a1ae072cc 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -761,15 +761,17 @@ /mob/living/update_rest_hud_icon() . = ..() - if(!.) + if(!. || !hud_used) return FALSE - if(!hud_used.sleep_icon || HAS_TRAIT(src, TRAIT_SLEEPIMMUNE)) + + var/atom/movable/screen/sleep/sleep_icon = hud_used.screen_objects[HUD_MOB_SLEEP] + if(!sleep_icon || HAS_TRAIT(src, TRAIT_SLEEPIMMUNE)) return TRUE + if(resting || HAS_TRAIT(src, TRAIT_FLOORED)) - hud_used.static_inventory |= hud_used.sleep_icon + sleep_icon.RemoveInvisibility(INVISIBILITY_SOURCE_SLEEP_HUD_BUTTON) else - hud_used.static_inventory -= hud_used.sleep_icon - hud_used.show_hud(hud_used.hud_version) + sleep_icon.SetInvisibility(INVISIBILITY_ABSTRACT, INVISIBILITY_SOURCE_SLEEP_HUD_BUTTON) return TRUE //Recursive function to find everything a mob is holding. Really shitty proc tbh. @@ -833,8 +835,8 @@ /mob/living/update_health_hud() var/severity = 0 var/healthpercent = (health/maxHealth) * 100 - if(hud_used?.healthdoll) //to really put you in the boots of a simplemob - var/atom/movable/screen/healthdoll/living/livingdoll = hud_used.healthdoll + var/atom/movable/screen/healthdoll/living/livingdoll = hud_used?.screen_objects[HUD_MOB_HEALTHDOLL] + if(istype(livingdoll)) //to really put you in the boots of a simplemob switch(healthpercent) if(100 to INFINITY) severity = 0 @@ -859,6 +861,7 @@ mob_mask = icon('icons/hud/screen_gen.dmi', health_doll_icon_state) //swap to something generic if they have no special doll livingdoll.add_filter("mob_shape_mask", 1, alpha_mask_filter(icon = mob_mask)) livingdoll.add_filter("inset_drop_shadow", 2, drop_shadow_filter(size = -1)) + if(severity > 0) overlay_fullscreen("brute", /atom/movable/screen/fullscreen/brute, severity) else @@ -1430,32 +1433,27 @@ update_stamina_hud() /mob/living/update_stamina_hud(shown_stamina_loss) - if(!client || !hud_used?.stamina) + if(!client || !hud_used) + return + + var/atom/movable/screen/stamina/stamina = hud_used.screen_objects[HUD_MOB_STAMINA] + if (!stamina) + return + + if(stat == DEAD) + stamina.icon_state = "stamina_dead" return var/stam_crit_threshold = maxHealth - crit_threshold + if(shown_stamina_loss == null) + shown_stamina_loss = get_stamina_loss() - if(stat == DEAD) - hud_used.stamina.icon_state = "stamina_dead" + if(shown_stamina_loss >= stam_crit_threshold) + stamina.icon_state = "stamina_crit" + else if(shown_stamina_loss > 0 && maxHealth > 0) + stamina.icon_state = "stamina_[6 - ceil(shown_stamina_loss / (maxHealth * 0.2))]" else - - if(shown_stamina_loss == null) - shown_stamina_loss = get_stamina_loss() - - if(shown_stamina_loss >= stam_crit_threshold) - hud_used.stamina.icon_state = "stamina_crit" - else if(shown_stamina_loss > maxHealth*0.8) - hud_used.stamina.icon_state = "stamina_5" - else if(shown_stamina_loss > maxHealth*0.6) - hud_used.stamina.icon_state = "stamina_4" - else if(shown_stamina_loss > maxHealth*0.4) - hud_used.stamina.icon_state = "stamina_3" - else if(shown_stamina_loss > maxHealth*0.2) - hud_used.stamina.icon_state = "stamina_2" - else if(shown_stamina_loss > 0) - hud_used.stamina.icon_state = "stamina_1" - else - hud_used.stamina.icon_state = "stamina_full" + stamina.icon_state = "stamina_full" /mob/living/carbon/alien/update_stamina() return diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index 68bcf1fee29..701b118ebdc 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -225,8 +225,7 @@ . = combat_mode combat_mode = new_mode SEND_SIGNAL(src, COMSIG_COMBAT_MODE_TOGGLED) - if(hud_used?.action_intent) - hud_used.action_intent.update_appearance() + hud_used?.screen_objects[HUD_MOB_INTENTS]?.update_appearance() if(silent || !client?.prefs.read_preference(/datum/preference/toggle/sound_combatmode)) return if(combat_mode) diff --git a/code/modules/mob/living/living_fov.dm b/code/modules/mob/living/living_fov.dm index a16cf111133..8c6c0833fbf 100644 --- a/code/modules/mob/living/living_fov.dm +++ b/code/modules/mob/living/living_fov.dm @@ -131,3 +131,5 @@ mouse_opacity = MOUSE_OPACITY_TRANSPARENT plane = FIELD_OF_VISION_BLOCKER_PLANE screen_loc = "BOTTOM,LEFT" + hud_key = HUD_MOB_FOV_BLOCKER + hud_group_key = HUD_GROUP_SCREEN_OVERLAYS diff --git a/code/modules/mob/living/living_item_handling.dm b/code/modules/mob/living/living_item_handling.dm index 482e0099491..24b3e2692d1 100644 --- a/code/modules/mob/living/living_item_handling.dm +++ b/code/modules/mob/living/living_item_handling.dm @@ -17,7 +17,7 @@ return throw_mode = THROW_MODE_DISABLED if(hud_used) - hud_used.throw_icon.icon_state = "act_throw" + hud_used.screen_objects[HUD_MOB_THROW]?.icon_state = "act_throw" SEND_SIGNAL(src, COMSIG_LIVING_THROW_MODE_TOGGLE, throw_mode) @@ -26,7 +26,7 @@ return throw_mode = mode if(hud_used) - hud_used.throw_icon.icon_state = "act_throw_on" + hud_used.screen_objects[HUD_MOB_THROW]?.icon_state = "act_throw_on" SEND_SIGNAL(src, COMSIG_LIVING_THROW_MODE_TOGGLE, throw_mode) /mob/proc/throw_item(atom/target) diff --git a/code/modules/mob/living/silicon/death.dm b/code/modules/mob/living/silicon/death.dm index 8aff9b59278..1522555af70 100644 --- a/code/modules/mob/living/silicon/death.dm +++ b/code/modules/mob/living/silicon/death.dm @@ -8,12 +8,10 @@ /mob/living/silicon/set_stat(new_stat) . = ..() - if(. != DEAD) + if(. != DEAD || !hud_used) return // Clean up hud element used for the death sequence - for(var/atom/movable/screen/cyborg_death/deathhud in hud_used?.always_visible_inventory) - hud_used.always_visible_inventory -= deathhud - qdel(deathhud) + hud_used.remove_screen_object(HUD_CYBORG_DEATH) /mob/living/silicon/death(gibbed) diag_hud_set_status() @@ -38,10 +36,8 @@ if(get_oxy_loss() > 100) cause_of_death = "Critically low power." - var/atom/movable/screen/cyborg_death/deathhud = new(null, hud_used, cause_of_death) - hud_used.always_visible_inventory += deathhud - hud_used.show_hud(hud_used.hud_version) - deathhud.run_animation() + var/atom/movable/screen/cyborg_death/deathhud = hud_used.add_screen_object(/atom/movable/screen/cyborg_death, HUD_CYBORG_DEATH, HUD_GROUP_SCREEN_OVERLAYS, update_screen = TRUE) + deathhud.run_animation(cause_of_death) #define WARNING_ROBOT(text) ("" + text + "") #define DANGER_ROBOT(text) ("" + text + "") @@ -88,13 +84,10 @@ WARNING_ROBOT("WARNI-"), ) -/atom/movable/screen/cyborg_death/Initialize(mapload, datum/hud/hud_owner, cause_of_death = "Unidentified kernel error.") - . = ..() - messages.Insert(1, WARNING_ROBOT("WARNING: [cause_of_death]")) - -/atom/movable/screen/cyborg_death/proc/run_animation() +/atom/movable/screen/cyborg_death/proc/run_animation(cause_of_death = "Unidentified kernel error.") set waitfor = FALSE + messages.Insert(1, WARNING_ROBOT("WARNING: [cause_of_death]")) if(prob(1)) messages[length(messages)] = SENTIENT_ROBOT(pick("I don't want to go.", "I don't feel good.", "I don't want to die.")) diff --git a/code/modules/mob/living/silicon/robot/inventory.dm b/code/modules/mob/living/silicon/robot/inventory.dm index d7a320c6e67..30790c176b5 100644 --- a/code/modules/mob/living/silicon/robot/inventory.dm +++ b/code/modules/mob/living/silicon/robot/inventory.dm @@ -77,16 +77,17 @@ . = ..() if(isnull(client) || isnull(hud_used) || hud_used.hud_version == HUD_STYLE_NOHUD) return - var/turf/our_turf = get_turf(src) - for(var/obj/item/held in held_items) + var/turf/our_turf = get_turf(src) + for (var/held_index in 1 to length(held_items)) + var/obj/item/held = held_items[held_index] + if (!held) + continue SET_PLANE(held, ABOVE_HUD_PLANE, our_turf) - if(held_items[BORG_CHOOSE_MODULE_ONE] == held) - held.screen_loc = inv1.screen_loc - else if(held_items[BORG_CHOOSE_MODULE_TWO] == held) - held.screen_loc = inv2.screen_loc - else if(held_items[BORG_CHOOSE_MODULE_THREE] == held) - held.screen_loc = inv3.screen_loc + var/atom/movable/screen/robot/module_slot/slot = hud_used.screen_objects[HUD_KEY_CYBORG_MODULE(held_index)] + if (!slot) //?? + continue + held.screen_loc = slot.screen_loc client.screen |= held /mob/living/silicon/robot/put_in_hand_check(obj/item/item_equipping) @@ -111,7 +112,6 @@ if(disabled_modules & BORG_MODULE_ALL_DISABLED) return FALSE - inv1.icon_state = "[initial(inv1.icon_state)] +b" disabled_modules |= BORG_MODULE_ALL_DISABLED playsound(src, 'sound/machines/warning-buzzer.ogg', 75, TRUE, TRUE) @@ -127,7 +127,6 @@ if(disabled_modules & BORG_MODULE_TWO_DISABLED) return FALSE - inv2.icon_state = "[initial(inv2.icon_state)] +b" disabled_modules |= BORG_MODULE_TWO_DISABLED playsound(src, 'sound/machines/warning-buzzer.ogg', 60, TRUE, TRUE) @@ -138,13 +137,15 @@ if(disabled_modules & BORG_MODULE_THREE_DISABLED) return FALSE - inv3.icon_state = "[initial(inv3.icon_state)] +b" disabled_modules |= BORG_MODULE_THREE_DISABLED playsound(src, 'sound/machines/warning-buzzer.ogg', 50, TRUE, TRUE) audible_message(span_warning("[src] sounds an alarm! \"SYSTEM ERROR: Module [module_num] OFFLINE.\"")) to_chat(src, span_userdanger("SYSTEM ERROR: Module [module_num] OFFLINE.")) + var/atom/movable/screen/robot/module_slot/module = hud_used?.screen_objects[HUD_KEY_CYBORG_MODULE(module_num)] + if(module) + module.icon_state = "[module.base_icon_state] +b" return TRUE /** @@ -169,26 +170,27 @@ if(!(disabled_modules & BORG_MODULE_ALL_DISABLED)) return FALSE - inv1.icon_state = initial(inv1.icon_state) disabled_modules &= ~BORG_MODULE_ALL_DISABLED if(builtInCamera) builtInCamera.camera_enabled = TRUE to_chat(src, span_notice("You hear your built in security camera focus adjust as it comes back online!")) + if(BORG_CHOOSE_MODULE_TWO) if(!(disabled_modules & BORG_MODULE_TWO_DISABLED)) return FALSE - inv2.icon_state = initial(inv2.icon_state) disabled_modules &= ~BORG_MODULE_TWO_DISABLED + if(BORG_CHOOSE_MODULE_THREE) if(!(disabled_modules & BORG_MODULE_THREE_DISABLED)) return FALSE - inv3.icon_state = initial(inv3.icon_state) disabled_modules &= ~BORG_MODULE_THREE_DISABLED to_chat(src, span_notice("ERROR CLEARED: Module [module_num] back online.")) - + var/atom/movable/screen/robot/module_slot/module = hud_used?.screen_objects[HUD_KEY_CYBORG_MODULE(module_num)] + if(module) + module.icon_state = module.base_icon_state return TRUE /** @@ -268,16 +270,9 @@ if(is_invalid_module_number(module_num) || !held_items[module_num]) //If the slot number is invalid, or there's nothing there, we have nothing to equip return FALSE - switch(module_num) - if(BORG_CHOOSE_MODULE_ONE) - if(module_active != held_items[module_num]) - inv1.icon_state = "[initial(inv1.icon_state)] +a" - if(BORG_CHOOSE_MODULE_TWO) - if(module_active != held_items[module_num]) - inv2.icon_state = "[initial(inv2.icon_state)] +a" - if(BORG_CHOOSE_MODULE_THREE) - if(module_active != held_items[module_num]) - inv3.icon_state = "[initial(inv3.icon_state)] +a" + var/atom/movable/screen/robot/module_slot/module = hud_used?.screen_objects[HUD_KEY_CYBORG_MODULE(module_num)] + if(module && module_active != held_items[module_num]) + module.icon_state = "[module.base_icon_state] +a" module_active = held_items[module_num] return TRUE @@ -287,13 +282,9 @@ * * module_num - the slot number being de-selected */ /mob/living/silicon/robot/proc/deselect_module(module_num) - switch(module_num) - if(BORG_CHOOSE_MODULE_ONE) - inv1.icon_state = initial(inv1.icon_state) - if(BORG_CHOOSE_MODULE_TWO) - inv2.icon_state = initial(inv2.icon_state) - if(BORG_CHOOSE_MODULE_THREE) - inv3.icon_state = initial(inv3.icon_state) + var/atom/movable/screen/robot/module_slot/module = hud_used?.screen_objects[HUD_KEY_CYBORG_MODULE(module_num)] + if(module) + module.icon_state = module.base_icon_state module_active = null return TRUE diff --git a/code/modules/mob/living/silicon/robot/life.dm b/code/modules/mob/living/silicon/robot/life.dm index d428c275171..a4da3bd1c80 100644 --- a/code/modules/mob/living/silicon/robot/life.dm +++ b/code/modules/mob/living/silicon/robot/life.dm @@ -37,22 +37,27 @@ /mob/living/silicon/robot/update_health_hud() if(!client || !hud_used) return - if(hud_used.healths) - if(stat != DEAD) - if(health >= maxHealth) - hud_used.healths.icon_state = "health0" - else if(health > maxHealth*0.6) - hud_used.healths.icon_state = "health2" - else if(health > maxHealth*0.2) - hud_used.healths.icon_state = "health3" - else if(health > -maxHealth*0.2) - hud_used.healths.icon_state = "health4" - else if(health > -maxHealth*0.6) - hud_used.healths.icon_state = "health5" - else - hud_used.healths.icon_state = "health6" - else - hud_used.healths.icon_state = "health7" + + var/atom/movable/screen/healths/healths = hud_used.screen_objects[HUD_MOB_HEALTH] + if(!healths) + return + + if(stat == DEAD) + healths.icon_state = "health7" + return + + if(health >= maxHealth) + healths.icon_state = "health0" + else if(health > maxHealth*0.6) + healths.icon_state = "health2" + else if(health > maxHealth*0.2) + healths.icon_state = "health3" + else if(health > -maxHealth*0.2) + healths.icon_state = "health4" + else if(health > -maxHealth*0.6) + healths.icon_state = "health5" + else + healths.icon_state = "health6" /mob/living/silicon/robot/proc/update_cell_hud_icon() if(cell) diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index b132ce92987..429b66c1a34 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -20,10 +20,6 @@ RegisterSignal(src, COMSIG_LIGHT_EATER_ACT, PROC_REF(on_light_eater)) RegisterSignal(src, SIGNAL_ADDTRAIT(TRAIT_GOT_DAMPENED), PROC_REF(on_dampen)) - inv1 = new /atom/movable/screen/robot/module1() - inv2 = new /atom/movable/screen/robot/module2() - inv3 = new /atom/movable/screen/robot/module3() - previous_health = health if(ispath(cell)) @@ -131,10 +127,6 @@ QDEL_NULL(model) QDEL_NULL(eye_lights) QDEL_NULL(hat_overlay) - QDEL_NULL(inv1) - QDEL_NULL(inv2) - QDEL_NULL(inv3) - QDEL_NULL(hands) QDEL_NULL(spark_system) QDEL_NULL(alert_control) QDEL_LIST(upgrades) @@ -513,19 +505,21 @@ if(!COOLDOWN_FINISHED(src, disabled_time)) balloon_alert(src, "disrupted!") return FALSE + if(!(update_color && lamp_enabled) && (turn_off || lamp_enabled || update_color || !lamp_functional || stat || low_power_mode)) set_light_on(lamp_functional && stat != DEAD && lamp_doom) //If the lamp isn't broken and borg isn't dead, doomsday borgs cannot disable their light fully. set_light_color(COLOR_RED) //This should only matter for doomsday borgs, as any other time the lamp will be off and the color not seen set_light_range(1) //Again, like above, this only takes effect when the light is forced on by doomsday mode. lamp_enabled = FALSE - lampButton?.update_appearance() + hud_used?.screen_objects[HUD_CYBORG_LAMP]?.update_appearance() update_icons() return + set_light_range(max(MINIMUM_USEFUL_LIGHT_RANGE, lamp_intensity)) set_light_color(lamp_doom ? COLOR_RED : lamp_color) //Red for doomsday killborgs, borg's choice otherwise set_light_on(TRUE) lamp_enabled = TRUE - lampButton?.update_appearance() + hud_used?.screen_objects[HUD_CYBORG_LAMP]?.update_appearance() update_icons() ///Completely deconstructs the borg, dropping the MMI/posibrain, removing applied upgrades and stripping the exoskeleton of all limbs, @@ -762,18 +756,15 @@ /mob/living/silicon/robot/proc/update_module_innate() designation = model.name - if(hands) - hands.icon_state = model.model_select_icon + hud_used?.screen_objects[HUD_CYBORG_HANDS]?.icon_state = model.model_select_icon REMOVE_TRAITS_IN(src, MODEL_TRAIT) if(length(model.model_traits)) add_traits(model.model_traits, MODEL_TRAIT) hat_offset = model.hat_offset - INVOKE_ASYNC(src, PROC_REF(updatename)) - /mob/living/silicon/robot/proc/place_on_head(obj/item/new_hat) if(hat) hat.forceMove(get_turf(src)) diff --git a/code/modules/mob/living/silicon/robot/robot_defines.dm b/code/modules/mob/living/silicon/robot/robot_defines.dm index 2cf30e5a5d9..c4cf75317d9 100644 --- a/code/modules/mob/living/silicon/robot/robot_defines.dm +++ b/code/modules/mob/living/silicon/robot/robot_defines.dm @@ -69,30 +69,15 @@ // Overlay for borg hat var/mutable_appearance/hat_overlay - - // Hud - var/atom/movable/screen/inv1 = null - var/atom/movable/screen/inv2 = null - var/atom/movable/screen/inv3 = null - var/atom/movable/screen/hands = null - - ///Lamp button reference - var/atom/movable/screen/robot/lamp/lampButton - - ///The reference to the built-in tablet that borgs carry. - var/atom/movable/screen/robot/modpc/interfaceButton - var/sight_mode = 0 hud_possible = list(ANTAG_HUD, DIAG_STAT_HUD, DIAG_HUD, DIAG_BATT_HUD, DIAG_TRACK_HUD) - // Modules (tool slots) var/obj/item/module_active = null ///For checking which modules are disabled or not. var/disabled_modules - // Status var/mob/living/silicon/ai/connected_ai = null diff --git a/code/modules/mob/living/simple_animal/hostile/ooze.dm b/code/modules/mob/living/simple_animal/hostile/ooze.dm index aec9457ecae..4bb2858bce1 100644 --- a/code/modules/mob/living/simple_animal/hostile/ooze.dm +++ b/code/modules/mob/living/simple_animal/hostile/ooze.dm @@ -85,7 +85,9 @@ ///Does ooze_nutrition + supplied amount and clamps it within 0 and 500 /mob/living/simple_animal/hostile/ooze/proc/adjust_ooze_nutrition(amount) ooze_nutrition = clamp(ooze_nutrition + amount, 0, 500) - updateNutritionDisplay() + hud_used?.screen_objects[HUD_OOZE_NUTRITION_DISPLAY]?.maptext = MAPTEXT( \ + "
[round(ooze_nutrition)]
" \ + ) ///Tries to transfer the atoms reagents then delete it /mob/living/simple_animal/hostile/ooze/proc/eat_atom(atom/eat_target, silent) @@ -98,12 +100,6 @@ to_chat(src, span_warning("[eat_target] cannot be eaten!")) return FALSE -///Updates the display that shows the mobs nutrition -/mob/living/simple_animal/hostile/ooze/proc/updateNutritionDisplay() - if(hud_used) //clientless oozes - hud_used.alien_plasma_display.maptext = MAPTEXT("
[round(ooze_nutrition)]
") - - ///* Gelatinious Ooze code below *\\\\ diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 4a8c75c0b11..dfdce3c3292 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -766,13 +766,13 @@ ///Update the pulling hud icon /mob/proc/update_pull_hud_icon() - hud_used?.pull_icon?.update_appearance() + hud_used?.screen_objects[HUD_MOB_PULL]?.update_appearance() ///Update the resting hud icon /mob/proc/update_rest_hud_icon() if(!hud_used) return FALSE - hud_used.rest_icon?.update_appearance() + hud_used.screen_objects[HUD_MOB_REST]?.update_appearance() return TRUE /** @@ -943,10 +943,10 @@ active_hand_index = held_index if(hud_used) var/atom/movable/screen/inventory/hand/held_location - held_location = hud_used.hand_slots["[previous_index]"] + held_location = hud_used.hand_slots[previous_index] if(!isnull(held_location)) held_location.update_appearance() - held_location = hud_used.hand_slots["[held_index]"] + held_location = hud_used.hand_slots[held_index] if(!isnull(held_location)) held_location.update_appearance() return TRUE @@ -1501,7 +1501,9 @@ /// Updates nutrition related effects /mob/living/proc/update_nutrition() mob_mood?.update_nutrition_moodlets() - hud_used?.hunger?.update_hunger_bar() + var/atom/movable/screen/hunger/hunger_bar = hud_used?.screen_objects[HUD_MOB_HUNGER] + if (hunger_bar) + hunger_bar.update_hunger_bar() SEND_SIGNAL(src, COMSIG_LIVING_UPDATE_NUTRITION) /// Apply a proper movespeed modifier based on items we have equipped diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index d461d9458cb..f0e07051a14 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -398,7 +398,7 @@ ///Validate the client's mob has a valid zone selected /client/proc/check_has_body_select() - return mob && mob.hud_used && mob.hud_used.zone_select && istype(mob.hud_used.zone_select, /atom/movable/screen/zone_sel) + return istype(mob?.hud_used?.screen_objects[HUD_MOB_ZONE_SELECTOR], /atom/movable/screen/zone_sel) /** * Hidden verbs to set desired body target zone @@ -423,7 +423,7 @@ else next_in_line = BODY_ZONE_HEAD - var/atom/movable/screen/zone_sel/selector = mob.hud_used.zone_select + var/atom/movable/screen/zone_sel/selector = mob.hud_used.screen_objects[HUD_MOB_ZONE_SELECTOR] selector.set_selected_zone(next_in_line, mob) ///Hidden verb to target the head, unbound by default. @@ -434,7 +434,7 @@ if(!check_has_body_select()) return - var/atom/movable/screen/zone_sel/selector = mob.hud_used.zone_select + var/atom/movable/screen/zone_sel/selector = mob.hud_used.screen_objects[HUD_MOB_ZONE_SELECTOR] selector.set_selected_zone(BODY_ZONE_HEAD, mob) ///Hidden verb to target the eyes, bound to 7 @@ -445,7 +445,7 @@ if(!check_has_body_select()) return - var/atom/movable/screen/zone_sel/selector = mob.hud_used.zone_select + var/atom/movable/screen/zone_sel/selector = mob.hud_used.screen_objects[HUD_MOB_ZONE_SELECTOR] selector.set_selected_zone(BODY_ZONE_PRECISE_EYES, mob) ///Hidden verb to target the mouth, bound to 9 @@ -456,7 +456,7 @@ if(!check_has_body_select()) return - var/atom/movable/screen/zone_sel/selector = mob.hud_used.zone_select + var/atom/movable/screen/zone_sel/selector = mob.hud_used.screen_objects[HUD_MOB_ZONE_SELECTOR] selector.set_selected_zone(BODY_ZONE_PRECISE_MOUTH, mob) ///Hidden verb to target the right arm, bound to 4 @@ -467,7 +467,7 @@ if(!check_has_body_select()) return - var/atom/movable/screen/zone_sel/selector = mob.hud_used.zone_select + var/atom/movable/screen/zone_sel/selector = mob.hud_used.screen_objects[HUD_MOB_ZONE_SELECTOR] selector.set_selected_zone(BODY_ZONE_R_ARM, mob) ///Hidden verb to target the chest, bound to 5 @@ -478,7 +478,7 @@ if(!check_has_body_select()) return - var/atom/movable/screen/zone_sel/selector = mob.hud_used.zone_select + var/atom/movable/screen/zone_sel/selector = mob.hud_used.screen_objects[HUD_MOB_ZONE_SELECTOR] selector.set_selected_zone(BODY_ZONE_CHEST, mob) ///Hidden verb to target the left arm, bound to 6 @@ -489,7 +489,7 @@ if(!check_has_body_select()) return - var/atom/movable/screen/zone_sel/selector = mob.hud_used.zone_select + var/atom/movable/screen/zone_sel/selector = mob.hud_used.screen_objects[HUD_MOB_ZONE_SELECTOR] selector.set_selected_zone(BODY_ZONE_L_ARM, mob) ///Hidden verb to target the right leg, bound to 1 @@ -500,7 +500,7 @@ if(!check_has_body_select()) return - var/atom/movable/screen/zone_sel/selector = mob.hud_used.zone_select + var/atom/movable/screen/zone_sel/selector = mob.hud_used.screen_objects[HUD_MOB_ZONE_SELECTOR] selector.set_selected_zone(BODY_ZONE_R_LEG, mob) ///Hidden verb to target the groin, bound to 2 @@ -511,7 +511,7 @@ if(!check_has_body_select()) return - var/atom/movable/screen/zone_sel/selector = mob.hud_used.zone_select + var/atom/movable/screen/zone_sel/selector = mob.hud_used.screen_objects[HUD_MOB_ZONE_SELECTOR] selector.set_selected_zone(BODY_ZONE_PRECISE_GROIN, mob) ///Hidden verb to target the left leg, bound to 3 @@ -522,7 +522,7 @@ if(!check_has_body_select()) return - var/atom/movable/screen/zone_sel/selector = mob.hud_used.zone_select + var/atom/movable/screen/zone_sel/selector = mob.hud_used.screen_objects[HUD_MOB_ZONE_SELECTOR] selector.set_selected_zone(BODY_ZONE_L_LEG, mob) ///Verb to toggle the walk or run status @@ -544,11 +544,9 @@ move_intent = MOVE_INTENT_WALK else move_intent = MOVE_INTENT_RUN - if(hud_used?.static_inventory) - for(var/atom/movable/screen/mov_intent/selector in hud_used.static_inventory) - selector.update_appearance() - update_move_intent_slowdown() + hud_used?.screen_objects[HUD_MOB_MOVE_INTENT]?.update_appearance() + update_move_intent_slowdown() SEND_SIGNAL(src, COMSIG_MOVE_INTENT_TOGGLED) ///Moves a mob upwards in z level diff --git a/code/modules/mod/mod_control.dm b/code/modules/mod/mod_control.dm index e9e1f1a05fe..7f6fff2e89e 100644 --- a/code/modules/mod/mod_control.dm +++ b/code/modules/mod/mod_control.dm @@ -524,7 +524,9 @@ module.on_unequip() UnregisterSignal(wearer, list(COMSIG_ATOM_EXITED, COMSIG_SPECIES_GAIN, COMSIG_MOB_CLICKON)) SEND_SIGNAL(src, COMSIG_MOD_WEARER_UNSET, wearer) - wearer.hud_used?.spacesuit_hud.update_spacesuit_hud_icon() + var/atom/movable/screen/spacesuit/spacesuit_hud = wearer.hud_used?.screen_objects[HUD_MOB_SPACESUIT] + if (spacesuit_hud) + spacesuit_hud.update_spacesuit_hud_icon() wearer = null /obj/item/mod/control/proc/get_sealed_slots(list/parts) @@ -725,7 +727,9 @@ else state_to_use = core.get_charge_icon_state() - wearer.hud_used.spacesuit_hud.update_spacesuit_hud_icon(state_to_use || SPACESUIT_NO_ICON) + var/atom/movable/screen/spacesuit/spacesuit_hud = wearer.hud_used?.screen_objects[HUD_MOB_SPACESUIT] + if (spacesuit_hud) + spacesuit_hud.update_spacesuit_hud_icon(state_to_use || SPACESUIT_NO_ICON) /obj/item/mod/control/proc/update_speed() var/total_slowdown = 0 diff --git a/code/modules/reagents/reagent_containers/cups/_cup.dm b/code/modules/reagents/reagent_containers/cups/_cup.dm index 953fb3d248a..e19880d6a66 100644 --- a/code/modules/reagents/reagent_containers/cups/_cup.dm +++ b/code/modules/reagents/reagent_containers/cups/_cup.dm @@ -138,7 +138,9 @@ SEND_SIGNAL(src, COMSIG_GLASS_DRANK, target_mob, user) var/fraction = min(gulp_size / reagents.total_volume, 1) reagents.trans_to(target_mob, gulp_size, transferred_by = user, methods = reagent_consumption_method) - user.hud_used?.hunger?.update_hunger_bar() + var/atom/movable/screen/hunger/hunger_bar = user.hud_used?.screen_objects[HUD_MOB_HUNGER] + if (istype(hunger_bar)) + hunger_bar.update_hunger_bar() checkLiked(fraction, target_mob) playsound(target_mob, consumption_sound, rand(10, 50), TRUE) var/list/datum/disease/diseases_to_add diff --git a/code/modules/research/xenobiology/xenobio_camera.dm b/code/modules/research/xenobiology/xenobio_camera.dm index 65fcb3ffc38..b26e759c218 100644 --- a/code/modules/research/xenobiology/xenobio_camera.dm +++ b/code/modules/research/xenobiology/xenobio_camera.dm @@ -46,8 +46,6 @@ var/max_slimes = 5 /// The amount of monkey cubes inside this machine. var/stored_monkeys = 0 - /// The HUD for this console. - var/atom/movable/screen/xenobio_console/xeno_hud /obj/machinery/computer/camera_advanced/xenobio/Initialize(mapload) . = ..() @@ -60,8 +58,6 @@ actions += new /datum/action/innate/hotkey_help(src) stored_slimes = list() - xeno_hud = new(null, src) - xeno_hud.on_update_hud(LAZYLEN(stored_slimes), stored_monkeys, max_slimes) register_context() /obj/machinery/computer/camera_advanced/xenobio/post_machine_initialize() @@ -77,7 +73,6 @@ var/mob/living/basic/slime/stored_slime = thing stored_slime.forceMove(drop_location()) stored_slimes.Cut() - QDEL_NULL(xeno_hud) return ..() /obj/machinery/computer/camera_advanced/xenobio/add_context(atom/source, list/context, obj/item/held_item, mob/living/user) @@ -115,8 +110,8 @@ RegisterSignal(user, COMSIG_CLICK_SHIFT, PROC_REF(user_shift_click)) if(!user.hud_used) return - user.hud_used.static_inventory += xeno_hud - user.hud_used.show_hud(user.hud_used.hud_version) + var/atom/movable/screen/xenobio_console/xeno_hud = user.hud_used.add_screen_object(/atom/movable/screen/xenobio_console, HUD_XENOBIO_CONSOLE, update_screen = TRUE) + xeno_hud.on_update_hud(LAZYLEN(stored_slimes), stored_monkeys, max_slimes) /obj/machinery/computer/camera_advanced/xenobio/remove_eye_control(mob/living/user) UnregisterSignal(user, list( @@ -124,10 +119,7 @@ COMSIG_MOB_ALTCLICKON, COMSIG_CLICK_SHIFT, )) - if(user.hud_used) - if(xeno_hud) - user.hud_used.static_inventory -= xeno_hud - user.hud_used.show_hud(user.hud_used.hud_version) + user.hud_used?.remove_screen_object(HUD_XENOBIO_CONSOLE) return ..() /obj/machinery/computer/camera_advanced/xenobio/item_interaction(mob/living/user, obj/item/tool, list/modifiers) @@ -156,14 +148,18 @@ balloon_alert(user, "inserted") current_potion = used_potion - xeno_hud.update_potion(current_potion) + var/atom/movable/screen/xenobio_console/xeno_hud = user.hud_used?.screen_objects[HUD_XENOBIO_CONSOLE] + if(xeno_hud) + xeno_hud.update_potion(current_potion) return ITEM_INTERACT_SUCCESS /// Handles inserting a monkey cube into the console. /obj/machinery/computer/camera_advanced/xenobio/proc/monkeycube_act(mob/living/user, obj/item/food/monkeycube/used_cube) stored_monkeys += 1 balloon_alert(user, "[stored_monkeys] cube\s stored") - xeno_hud.on_update_hud(LAZYLEN(stored_slimes), stored_monkeys, max_slimes) + var/atom/movable/screen/xenobio_console/xeno_hud = user.hud_used?.screen_objects[HUD_XENOBIO_CONSOLE] + if(xeno_hud) + xeno_hud.on_update_hud(LAZYLEN(stored_slimes), stored_monkeys, max_slimes) qdel(used_cube) return ITEM_INTERACT_SUCCESS @@ -180,7 +176,9 @@ return ITEM_INTERACT_BLOCKING balloon_alert(user, "[stored_monkeys] cube\s stored") - xeno_hud.on_update_hud(LAZYLEN(stored_slimes), stored_monkeys, max_slimes) + var/atom/movable/screen/xenobio_console/xeno_hud = user.hud_used?.screen_objects[HUD_XENOBIO_CONSOLE] + if(xeno_hud) + xeno_hud.on_update_hud(LAZYLEN(stored_slimes), stored_monkeys, max_slimes) return ITEM_INTERACT_SUCCESS /obj/machinery/computer/camera_advanced/xenobio/multitool_act(mob/living/user, obj/item/multitool/tool) @@ -212,19 +210,24 @@ return TRUE ///Places every slime in storage on target turf -/obj/machinery/computer/camera_advanced/xenobio/proc/slime_place(turf/open/target_turf) +/obj/machinery/computer/camera_advanced/xenobio/proc/slime_place(turf/open/target_turf, mob/living/user) spit_out(stored_slimes, target_turf) if(stored_slimes.len <= 0) return + if(stored_slimes.len == 1) target_turf.visible_message(span_notice("The slime is spat out!")) else target_turf.visible_message(span_notice("[stored_slimes.len] slimes are spat out!")) + for(var/mob/living/basic/slime/stored_slime in stored_slimes) stored_slime.forceMove(target_turf) REMOVE_TRAIT(stored_slime, TRAIT_STASIS, XENOBIO_CONSOLE_TRAIT) stored_slime.handle_slime_stasis() - xeno_hud.on_update_hud(LAZYLEN(stored_slimes), stored_monkeys, max_slimes) + + var/atom/movable/screen/xenobio_console/xeno_hud = user.hud_used?.screen_objects[HUD_XENOBIO_CONSOLE] + if(xeno_hud) + xeno_hud.on_update_hud(LAZYLEN(stored_slimes), stored_monkeys, max_slimes) ///Places every slime not controlled by a player into the internal storage, respecting its limits ///Returns TRUE to signal it hitting the limit, in case its being called from a loop and we want it to stop @@ -233,13 +236,16 @@ // It's possible for this proc to be called on a slime that's already being picked up, // so we need to check whether we already have to avoid duplicate entries. return FALSE + if(stored_slimes.len >= max_slimes) to_chat(user, span_warning("Slime storage is full.")) target_slime.balloon_alert(user, "storage full") return TRUE + if(target_slime.ckey) to_chat(user, span_warning("The slime wiggled free!")) return FALSE + if(target_slime.buckled) target_slime.stop_feeding(silent = TRUE) target_slime.visible_message(span_notice("The slime gets sucked up!")) @@ -247,8 +253,10 @@ target_slime.forceMove(src) stored_slimes += target_slime ADD_TRAIT(target_slime, TRAIT_STASIS, XENOBIO_CONSOLE_TRAIT) - xeno_hud.on_update_hud(LAZYLEN(stored_slimes), stored_monkeys, max_slimes) + var/atom/movable/screen/xenobio_console/xeno_hud = user.hud_used?.screen_objects[HUD_XENOBIO_CONSOLE] + if(xeno_hud) + xeno_hud.on_update_hud(LAZYLEN(stored_slimes), stored_monkeys, max_slimes) return FALSE ///Places one monkey, if possible @@ -261,13 +269,16 @@ var/mob/living/carbon/human/species/monkey/food = new /mob/living/carbon/human/species/monkey(target_turf, TRUE, user) if (QDELETED(food)) return + food.apply_status_effect(/datum/status_effect/slime_food, user) ADD_TRAIT(food, TRAIT_SPAWNED_MOB, INNATE_TRAIT) - stored_monkeys-- stored_monkeys = round(stored_monkeys, 0.1) //Prevents rounding errors spit_out(food, target_turf) - xeno_hud.on_update_hud(LAZYLEN(stored_slimes), stored_monkeys, max_slimes) + + var/atom/movable/screen/xenobio_console/xeno_hud = user.hud_used?.screen_objects[HUD_XENOBIO_CONSOLE] + if(xeno_hud) + xeno_hud.on_update_hud(LAZYLEN(stored_slimes), stored_monkeys, max_slimes) /// Check whether we can recycle monkeys at all. Optionally, displays a balloon alert over a target atom for feedback. /obj/machinery/computer/camera_advanced/xenobio/proc/can_recycle_monkeys(mob/living/user, atom/target_atom) @@ -302,7 +313,7 @@ for(var/mob/living/carbon/human/target_human in target_turf) if(!can_recycle_target_monkey(target_human)) continue - recycle_monkey(target_human) + recycle_monkey(target_human, user) monkey_found = TRUE return monkey_found @@ -314,11 +325,11 @@ if(!can_recycle_monkeys(user, target_human)) return FALSE - recycle_monkey(target_human) + recycle_monkey(target_human, user) return TRUE /// Recycles a given monkey. -/obj/machinery/computer/camera_advanced/xenobio/proc/recycle_monkey(mob/living/carbon/human/target_monkey) +/obj/machinery/computer/camera_advanced/xenobio/proc/recycle_monkey(mob/living/carbon/human/target_monkey, mob/living/user) var/obj/machinery/monkey_recycler/connected_recycler = connected_recycler_ref?.resolve() if(isnull(connected_recycler)) return @@ -328,7 +339,9 @@ connected_recycler.use_energy(500 JOULES) stored_monkeys += connected_recycler.cube_production stored_monkeys = round(stored_monkeys, 0.1) //Prevents rounding errors - xeno_hud.on_update_hud(LAZYLEN(stored_slimes), stored_monkeys, max_slimes) + var/atom/movable/screen/xenobio_console/xeno_hud = user.hud_used?.screen_objects[HUD_XENOBIO_CONSOLE] + if(xeno_hud) + xeno_hud.on_update_hud(LAZYLEN(stored_slimes), stored_monkeys, max_slimes) qdel(target_monkey) /datum/action/innate/slime_place @@ -346,7 +359,7 @@ if(!xeno_console.validate_turf(owner, eye_turf)) return - xeno_console.slime_place(eye_turf) + xeno_console.slime_place(eye_turf, owner) /datum/action/innate/slime_pick_up name = "Pick up Slime" @@ -443,7 +456,9 @@ for(var/mob/living/basic/slime/potioned_slime in eye_turf) xeno_console.spit_atom(xeno_console.current_potion, eye_turf) xeno_console.current_potion.interact_with_slime(potioned_slime, living_owner) - xeno_console.xeno_hud.update_potion(xeno_console.current_potion) + var/atom/movable/screen/xenobio_console/xeno_hud = owner.hud_used?.screen_objects[HUD_XENOBIO_CONSOLE] + if(xeno_hud) + xeno_hud.update_potion(xeno_console.current_potion) break /datum/action/innate/hotkey_help @@ -485,7 +500,9 @@ spit_atom(current_potion, slime_turf) INVOKE_ASYNC(current_potion, TYPE_PROC_REF(/obj/item/slimepotion/slime, attack), target_slime, user) - xeno_hud.update_potion(current_potion) + var/atom/movable/screen/xenobio_console/xeno_hud = user.hud_used?.screen_objects[HUD_XENOBIO_CONSOLE] + if(xeno_hud) + xeno_hud.update_potion(current_potion) /// Handles console user shift-clicking, forwards to other procs based on target type. /obj/machinery/computer/camera_advanced/xenobio/proc/user_shift_click(mob/living/user, atom/target) diff --git a/code/modules/surgery/bodyparts/dismemberment.dm b/code/modules/surgery/bodyparts/dismemberment.dm index 72108859d3e..d0a3d18cfa2 100644 --- a/code/modules/surgery/bodyparts/dismemberment.dm +++ b/code/modules/surgery/bodyparts/dismemberment.dm @@ -204,7 +204,7 @@ arm_owner.set_handcuffed(null) arm_owner.dropItemToGround(lost_cuffs, force = TRUE) if(arm_owner.hud_used) - var/atom/movable/screen/inventory/hand/associated_hand = arm_owner.hud_used.hand_slots["[held_index]"] + var/atom/movable/screen/inventory/hand/associated_hand = arm_owner.hud_used.hand_slots[held_index] associated_hand?.update_appearance() if(arm_owner.num_hands == 0) arm_owner.dropItemToGround(arm_owner.gloves, force = TRUE) diff --git a/code/modules/surgery/bodyparts/parts.dm b/code/modules/surgery/bodyparts/parts.dm index 7c112950265..9b0f56c6a58 100644 --- a/code/modules/surgery/bodyparts/parts.dm +++ b/code/modules/surgery/bodyparts/parts.dm @@ -211,7 +211,7 @@ if(!old_owner.hud_used) return - var/atom/movable/screen/inventory/hand/hand = old_owner.hud_used.hand_slots["[held_index]"] + var/atom/movable/screen/inventory/hand/hand = old_owner.hud_used.hand_slots[held_index] hand?.update_appearance() /// We need to add hand hud items and appearance, so do that here @@ -230,7 +230,7 @@ if(!new_owner.hud_used) return - var/atom/movable/screen/inventory/hand/hand = new_owner.hud_used.hand_slots["[held_index]"] + var/atom/movable/screen/inventory/hand/hand = new_owner.hud_used.hand_slots[held_index] hand?.update_appearance() /obj/item/bodypart/arm/set_disabled(new_disabled) @@ -249,7 +249,7 @@ owner.set_usable_hands(owner.usable_hands + 1) if(owner.hud_used) - var/atom/movable/screen/inventory/hand/hand_screen_object = owner.hud_used.hand_slots["[held_index]"] + var/atom/movable/screen/inventory/hand/hand_screen_object = owner.hud_used.hand_slots[held_index] hand_screen_object?.update_appearance() /datum/status_effect/arm_speed_penalty diff --git a/code/modules/surgery/organs/internal/stomach/_stomach.dm b/code/modules/surgery/organs/internal/stomach/_stomach.dm index f8cb50193d5..7429f072f53 100644 --- a/code/modules/surgery/organs/internal/stomach/_stomach.dm +++ b/code/modules/surgery/organs/internal/stomach/_stomach.dm @@ -388,7 +388,9 @@ /obj/item/organ/stomach/on_mob_insert(mob/living/carbon/receiver, special, movement_flags) . = ..() - receiver.hud_used?.hunger?.update_hunger_bar() + var/atom/movable/screen/hunger/hunger_bar = receiver.hud_used?.screen_objects[HUD_MOB_HUNGER] + if(hunger_bar) + hunger_bar.update_hunger_bar() RegisterSignal(receiver, COMSIG_CARBON_VOMITED, PROC_REF(on_vomit)) RegisterSignal(receiver, COMSIG_HUMAN_GOT_PUNCHED, PROC_REF(on_punched)) @@ -397,7 +399,9 @@ var/mob/living/carbon/human/human_owner = stomach_owner human_owner.clear_alert(ALERT_DISGUST) human_owner.clear_mood_event("disgust") - stomach_owner.hud_used?.hunger?.update_hunger_bar() + var/atom/movable/screen/hunger/hunger_bar = stomach_owner.hud_used?.screen_objects[HUD_MOB_HUNGER] + if(hunger_bar) + hunger_bar.update_hunger_bar() UnregisterSignal(stomach_owner, list(COMSIG_CARBON_VOMITED, COMSIG_HUMAN_GOT_PUNCHED)) return ..() diff --git a/code/modules/unit_tests/unequip_defib.dm b/code/modules/unit_tests/unequip_defib.dm index e2db399f2de..910cf599af2 100644 --- a/code/modules/unit_tests/unequip_defib.dm +++ b/code/modules/unit_tests/unequip_defib.dm @@ -12,7 +12,7 @@ usr = dummy // mouse drop still uses usr - defib.MouseDrop(dummy.hud_used.hand_slots["1"]) + defib.MouseDrop(dummy.hud_used.hand_slots[1]) if(!dummy.is_holding(defib)) TEST_FAIL("The dummy failed to remove the defib from their back via mouse drop.") diff --git a/code/modules/unit_tests/unit_test.dm b/code/modules/unit_tests/unit_test.dm index 74f14ecea49..289bfc097bc 100644 --- a/code/modules/unit_tests/unit_test.dm +++ b/code/modules/unit_tests/unit_test.dm @@ -351,13 +351,12 @@ GLOBAL_VAR_INIT(focused_tests, focused_tests()) returnable_list += typesof(/obj/structure/transport/linear) // Runtimes if the associated machinery does not exist, but not the base type returnable_list += subtypesof(/obj/machinery/airlock_controller) - // Always ought to have an associated escape menu. Any references it could possibly hold would need one regardless. - returnable_list += subtypesof(/atom/movable/screen/escape_menu) // Can't spawn openspace above nothing, it'll get pissy at me returnable_list += typesof(/turf/open/space/openspace) returnable_list += typesof(/turf/open/openspace) returnable_list += typesof(/obj/item/robot_model) // These should never be spawned outside of a robot. - + //A lot of these depend on a hud datum to function and should not be created in a vacuum + returnable_list += typesof(/atom/movable/screen) return returnable_list /proc/RunUnitTests() diff --git a/icons/hud/screen_changeling.dmi b/icons/hud/screen_changeling.dmi index c3bab062ac4..30c3df29948 100644 Binary files a/icons/hud/screen_changeling.dmi and b/icons/hud/screen_changeling.dmi differ diff --git a/icons/mob/actions/actions_changeling.dmi b/icons/mob/actions/actions_changeling.dmi index a721505a8c0..aae88cd0b5c 100644 Binary files a/icons/mob/actions/actions_changeling.dmi and b/icons/mob/actions/actions_changeling.dmi differ diff --git a/tgstation.dme b/tgstation.dme index 233b01bea38..ca737cae21b 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -619,37 +619,26 @@ #include "code\_onclick\other_mobs.dm" #include "code\_onclick\overmind.dm" #include "code\_onclick\telekinesis.dm" -#include "code\_onclick\hud\action_button.dm" +#include "code\_onclick\hud\action_group.dm" #include "code\_onclick\hud\ai.dm" -#include "code\_onclick\hud\alert.dm" #include "code\_onclick\hud\alien.dm" #include "code\_onclick\hud\alien_larva.dm" #include "code\_onclick\hud\blob_overmind.dm" -#include "code\_onclick\hud\credits.dm" #include "code\_onclick\hud\drones.dm" -#include "code\_onclick\hud\fullscreen.dm" #include "code\_onclick\hud\generic_dextrous.dm" #include "code\_onclick\hud\ghost.dm" #include "code\_onclick\hud\guardian.dm" #include "code\_onclick\hud\hud.dm" #include "code\_onclick\hud\human.dm" +#include "code\_onclick\hud\inventory_slot.dm" #include "code\_onclick\hud\living.dm" -#include "code\_onclick\hud\map_popups.dm" -#include "code\_onclick\hud\map_view.dm" -#include "code\_onclick\hud\movable_screen_objects.dm" #include "code\_onclick\hud\new_player.dm" #include "code\_onclick\hud\ooze.dm" -#include "code\_onclick\hud\perks.dm" -#include "code\_onclick\hud\picture_in_picture.dm" -#include "code\_onclick\hud\radial.dm" -#include "code\_onclick\hud\radial_persistent.dm" +#include "code\_onclick\hud\pai.dm" #include "code\_onclick\hud\revenanthud.dm" #include "code\_onclick\hud\robot.dm" -#include "code\_onclick\hud\screen_object_holder.dm" -#include "code\_onclick\hud\screen_objects.dm" -#include "code\_onclick\hud\screentip.dm" #include "code\_onclick\hud\soulscythe.dm" -#include "code\_onclick\hud\voidwalkerhud.dm" +#include "code\_onclick\hud\voidwalker.dm" #include "code\_onclick\hud\parallax\parallax.dm" #include "code\_onclick\hud\parallax\random_layer.dm" #include "code\_onclick\hud\rendering\plane_master_controller.dm" @@ -657,6 +646,30 @@ #include "code\_onclick\hud\rendering\render_plate.dm" #include "code\_onclick\hud\rendering\plane_masters\_plane_master.dm" #include "code\_onclick\hud\rendering\plane_masters\plane_master_subtypes.dm" +#include "code\_onclick\hud\screen_objects\action_button.dm" +#include "code\_onclick\hud\screen_objects\ai.dm" +#include "code\_onclick\hud\screen_objects\alert.dm" +#include "code\_onclick\hud\screen_objects\alien.dm" +#include "code\_onclick\hud\screen_objects\blob.dm" +#include "code\_onclick\hud\screen_objects\credits.dm" +#include "code\_onclick\hud\screen_objects\fullscreen.dm" +#include "code\_onclick\hud\screen_objects\ghost.dm" +#include "code\_onclick\hud\screen_objects\guardian.dm" +#include "code\_onclick\hud\screen_objects\human.dm" +#include "code\_onclick\hud\screen_objects\map_popups.dm" +#include "code\_onclick\hud\screen_objects\map_view.dm" +#include "code\_onclick\hud\screen_objects\movable_screen_objects.dm" +#include "code\_onclick\hud\screen_objects\new_player.dm" +#include "code\_onclick\hud\screen_objects\pai.dm" +#include "code\_onclick\hud\screen_objects\perks.dm" +#include "code\_onclick\hud\screen_objects\picture_in_picture.dm" +#include "code\_onclick\hud\screen_objects\radial.dm" +#include "code\_onclick\hud\screen_objects\radial_persistent.dm" +#include "code\_onclick\hud\screen_objects\robot.dm" +#include "code\_onclick\hud\screen_objects\screen_object_holder.dm" +#include "code\_onclick\hud\screen_objects\screen_objects.dm" +#include "code\_onclick\hud\screen_objects\screentip.dm" +#include "code\_onclick\hud\screen_objects\voidwalker.dm" #include "code\controllers\admin.dm" #include "code\controllers\controller.dm" #include "code\controllers\failsafe.dm" @@ -4320,7 +4333,6 @@ #include "code\modules\economy\poker_chips.dm" #include "code\modules\emoji\emoji_parse.dm" #include "code\modules\emote_panel\emote_panel.dm" -#include "code\modules\engineering\tools\multitool.dm" #include "code\modules\error_handler\error_handler.dm" #include "code\modules\error_handler\error_viewer.dm" #include "code\modules\escape_menu\details.dm" @@ -5815,7 +5827,6 @@ #include "code\modules\pai\debug.dm" #include "code\modules\pai\defense.dm" #include "code\modules\pai\door_jack.dm" -#include "code\modules\pai\hud.dm" #include "code\modules\pai\login.dm" #include "code\modules\pai\pai.dm" #include "code\modules\pai\personality.dm"