diff --git a/code/__DEFINES/hud.dm b/code/__DEFINES/hud.dm index 7bbd3b5fc6c..d00c7ac066e 100644 --- a/code/__DEFINES/hud.dm +++ b/code/__DEFINES/hud.dm @@ -361,6 +361,13 @@ #define ui_ghost_language_menu "SOUTH:6,CENTER+4:22" #define ui_ghost_floor_changer "SOUTH:6,CENTER+4:7" +//Holoparasites +#define ui_guardian_floor_changer "EAST-1:28,SOUTH+1:7" +#define ui_guardian_communication "CENTER-2:16,SOUTH+0:5" +#define ui_guardian_manifest "CENTER-1:16,SOUTH+0:5" +#define ui_guardian_recall "CENTER+0:16,SOUTH+0:5" +#define ui_guardian_special "CENTER+1:16,SOUTH+0:5" + //Voidwalker #define ui_voidwalker_left_of_hands "CENTER+-2:16,SOUTH+0:5" diff --git a/code/__DEFINES/traits/declarations.dm b/code/__DEFINES/traits/declarations.dm index e3c4bdd8f77..77b96215a44 100644 --- a/code/__DEFINES/traits/declarations.dm +++ b/code/__DEFINES/traits/declarations.dm @@ -1527,7 +1527,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai * (This may be changed later but I chose to do it this way to avoid messing up interactions which require combat mode) */ #define TRAIT_COMBAT_MODE_SKIP_INTERACTION "combat_mode_skip_interaction" -// bars change of combat mode +///Prevents the user from swapping combat intent. #define TRAIT_COMBAT_MODE_LOCK "combat_mode_lock" ///A "fake" effect that should not be subject to normal effect removal methods (like the effect remover component) diff --git a/code/_onclick/hud/generic_dextrous.dm b/code/_onclick/hud/generic_dextrous.dm index 8a7950cfe63..a0faa532533 100644 --- a/code/_onclick/hud/generic_dextrous.dm +++ b/code/_onclick/hud/generic_dextrous.dm @@ -1,3 +1,9 @@ +/datum/hud/dextrous + ///Boolean on whether to give the generic combat indicator + var/give_generic_combat = TRUE + ///Boolean on whether to give a health doll. + var/give_health_doll = TRUE + //Used for normal mobs that have hands. /datum/hud/dextrous/initialize_screen_objects() . = ..() @@ -11,12 +17,14 @@ 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_INFO, ui_style, ui_movi) + if(give_generic_combat) + add_screen_object(/atom/movable/screen/combattoggle/flashy, HUD_MOB_INTENTS, HUD_GROUP_INFO, ui_style, ui_movi) + if(give_health_doll) + add_screen_object(/atom/movable/screen/healthdoll/living, HUD_MOB_HEALTHDOLL, HUD_GROUP_INFO) 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) diff --git a/code/_onclick/hud/guardian.dm b/code/_onclick/hud/guardian.dm index cabe261b14e..18b1b985ccb 100644 --- a/code/_onclick/hud/guardian.dm +++ b/code/_onclick/hud/guardian.dm @@ -1,35 +1,19 @@ -/datum/hud/guardian - ui_style = 'icons/hud/guardian.dmi' - inventory_slots = list(/datum/inventory_slot/guardian_storage) - /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) - + add_screen_object(/atom/movable/screen/pull, HUD_MOB_PULL, HUD_GROUP_STATIC, 'icons/hud/guardian.dmi') + add_screen_object(/atom/movable/screen/floor_changer, HUD_MOB_FLOOR_CHANGER, HUD_GROUP_STATIC, ui_style, ui_below_throw) add_screen_object(/atom/movable/screen/healths/guardian, HUD_MOB_HEALTH, HUD_GROUP_INFO) + add_screen_object(/atom/movable/screen/combattoggle/flashy, HUD_MOB_INTENTS, HUD_GROUP_STATIC, ui_style, ui_loc = ui_zonesel) - var/mob/living/basic/guardian/owner = mymob - if (istype(owner)) - add_screen_object(owner.toggle_button_type, HUD_GUARDIAN_TOGGLE, ui_loc = ui_storage1) +///Dextrous subtype for only dextrous holoparasites. Can hold things hence the inventory slot. +/datum/hud/dextrous/guardian + inventory_slots = list(/datum/inventory_slot/guardian_storage) + give_health_doll = FALSE /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) - add_screen_object(/atom/movable/screen/healths/guardian, HUD_MOB_HEALTH, HUD_GROUP_INFO) - 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 @@ -40,7 +24,7 @@ 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.internal_storage.screen_loc = ui_back dex_guardian.client.screen += dex_guardian.internal_storage else if(dex_guardian.internal_storage) @@ -51,4 +35,5 @@ name = "internal storage" icon_state = "suit_storage" slot_id = ITEM_SLOT_DEX_STORAGE - screen_loc = ui_id + screen_loc = ui_back + diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm index 3ac3685874d..4f917217706 100644 --- a/code/_onclick/hud/hud.dm +++ b/code/_onclick/hud/hud.dm @@ -58,6 +58,8 @@ GLOBAL_LIST_INIT(available_ui_styles, list( /// If this client is being shown atmos debug overlays or not var/atmos_debug_overlays = FALSE + ///Boolean on whether they need at least a healths or healdoll, for unit tests. + var/needs_health_indicator = TRUE /// 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). @@ -303,6 +305,7 @@ GLOBAL_LIST_INIT(available_ui_styles, list( hud_used = new_hud new_hud.build_action_groups() + /** * Shows this hud's hud to some mob * diff --git a/code/_onclick/hud/screen_objects/alert.dm b/code/_onclick/hud/screen_objects/alert.dm index ca4fcc22f80..6a79bf6b0e9 100644 --- a/code/_onclick/hud/screen_objects/alert.dm +++ b/code/_onclick/hud/screen_objects/alert.dm @@ -754,12 +754,6 @@ //GUARDIANS -/atom/movable/screen/alert/canstealth - name = "Stealth Ready" - desc = "You are ready to enter stealth!" - icon_state = "guardian_canstealth" - alerttooltipstyle = "parasite" - /atom/movable/screen/alert/status_effect/instealth name = "In Stealth" desc = "You are in stealth and your next attack will do bonus damage!" diff --git a/code/_onclick/hud/screen_objects/guardian.dm b/code/_onclick/hud/screen_objects/guardian.dm deleted file mode 100644 index 41282bc45ed..00000000000 --- a/code/_onclick/hud/screen_objects/guardian.dm +++ /dev/null @@ -1,68 +0,0 @@ -/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/screen_objects.dm b/code/_onclick/hud/screen_objects/screen_objects.dm index e21dd0bc2dc..7631674c460 100644 --- a/code/_onclick/hud/screen_objects/screen_objects.dm +++ b/code/_onclick/hud/screen_objects/screen_objects.dm @@ -864,7 +864,6 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen) // I hate this place /atom/movable/screen/healthdoll name = "health doll" screen_loc = ui_healthdoll - mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/healthdoll/Click() if (iscarbon(usr)) @@ -877,9 +876,41 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen) // I hate this place /atom/movable/screen/healthdoll/living icon_state = "fullhealth0" screen_loc = ui_living_healthdoll + ///The image we create on New to use for showing mob's HP on hover. It uses a separate image as to not be cut off by `alpha_mask_filter`. + var/image/health_overlay + ///Boolean on whether a mouse is being hovered over us right now. + var/hovering = FALSE var/filtered = FALSE //so we don't repeatedly create the mask of the mob every update +/atom/movable/screen/healthdoll/living/New(loc, ...) + . = ..() + health_overlay = image(loc = src, layer = src.layer+0.1) + +/atom/movable/screen/healthdoll/living/Destroy() + QDEL_NULL(health_overlay) + return ..() + +/atom/movable/screen/healthdoll/living/update_overlays() + . = ..() + if(hovering) + . |= health_overlay + +/atom/movable/screen/healthdoll/living/MouseEntered(location,control,params) + if(usr != get_mob()) + return + . = ..() + hovering = TRUE + update_appearance(UPDATE_ICON) + +/atom/movable/screen/healthdoll/living/MouseExited(location, control, params) + if(usr != get_mob()) + return + . = ..() + hovering = FALSE + update_appearance(UPDATE_ICON) + /atom/movable/screen/healthdoll/human + mouse_over_pointer = MOUSE_HAND_POINTER /// Tracks components of our doll, each limb is a separate atom in our vis_contents VAR_PRIVATE/list/atom/movable/screen/limbs /// Lazylist, tracks all body zones that are wounded currently diff --git a/code/_onclick/hud/soulscythe.dm b/code/_onclick/hud/soulscythe.dm index e290d960e56..53b2d850011 100644 --- a/code/_onclick/hud/soulscythe.dm +++ b/code/_onclick/hud/soulscythe.dm @@ -1,3 +1,7 @@ +/datum/hud/soulscythe + needs_health_indicator = FALSE //we use blood level instead. + /datum/hud/soulscythe/initialize_screen_objects() . = ..() add_screen_object(/atom/movable/screen/blood_level, HUD_MOB_BLOOD_LEVEL, HUD_GROUP_INFO) + add_screen_object(/atom/movable/screen/combattoggle/flashy, HUD_MOB_INTENTS, HUD_GROUP_STATIC, ui_style, ui_loc = ui_zonesel) diff --git a/code/_onclick/hud/voidwalker.dm b/code/_onclick/hud/voidwalker.dm index c6da1e0bf10..5460ee90a5b 100644 --- a/code/_onclick/hud/voidwalker.dm +++ b/code/_onclick/hud/voidwalker.dm @@ -1,5 +1,6 @@ /datum/hud/dextrous/voidwalker ui_style = 'icons/hud/screen_voidwalker.dmi' + give_generic_combat = FALSE //we give our own version below, here. /datum/hud/dextrous/voidwalker/initialize_screen_objects() . = ..() diff --git a/code/datums/actions/mobs/guardians.dm b/code/datums/actions/mobs/guardians.dm new file mode 100644 index 00000000000..ff912c5300e --- /dev/null +++ b/code/datums/actions/mobs/guardians.dm @@ -0,0 +1,77 @@ +/datum/action/cooldown/guardian + button_icon = 'icons/hud/guardian.dmi' + +/datum/action/cooldown/guardian/IsAvailable(feedback) + . = ..() + if(!.) + return . + return !!isguardian(owner) + +/datum/action/cooldown/guardian/check_type + name = "Check Type" + desc = "A reminder on what your abilities are." + //this is based off of the antag ui icon, if that changes then change this too please. + button_icon_state = /datum/action/antag_info::button_icon_state + default_button_position = SCRN_OBJ_INSERT_FIRST + +/datum/action/cooldown/guardian/check_type/Activate(atom/target) + . = ..() + to_chat(owner, astype(owner, /mob/living/basic/guardian)?.playstyle_string) + +/datum/action/cooldown/guardian/communicate + name = "Communicate" + desc = "Communicate telepathically with your user." + button_icon_state = "communicate" + default_button_position = ui_guardian_communication + +/datum/action/cooldown/guardian/communicate/Activate() + astype(owner, /mob/living/basic/guardian)?.communicate() + +/datum/action/cooldown/guardian/manifest + name = "Manifest" + desc = "Spring forth into battle!" + button_icon_state = "manifest" + default_button_position = ui_guardian_manifest + +/datum/action/cooldown/guardian/manifest/Activate() + astype(owner, /mob/living/basic/guardian)?.manifest() + +/datum/action/cooldown/guardian/recall + name = "Recall" + desc = "Return to your user." + button_icon_state = "recall" + default_button_position = ui_guardian_recall + +/datum/action/cooldown/guardian/recall/Activate() + astype(owner, /mob/living/basic/guardian)?.recall() + +/datum/action/cooldown/guardian/toggle_light + name = "Toggle Light" + desc = "Glow like star dust." + button_icon_state = "light" + +/datum/action/cooldown/guardian/toggle_light/Activate() + astype(owner, /mob/living/basic/guardian)?.toggle_light() + +/datum/action/cooldown/guardian/toggle_mode + name = "Toggle Mode" + desc = "Switch between ability modes." + button_icon_state = "toggle" + default_button_position = ui_guardian_special + +/datum/action/cooldown/guardian/toggle_mode/Activate() + astype(owner, /mob/living/basic/guardian)?.toggle_modes() + +/datum/action/cooldown/guardian/toggle_mode/assassin + name = "Toggle Stealth" + desc = "Enter or exit stealth." + button_icon_state = "stealth" + transparent_when_unavailable = TRUE + +/datum/action/cooldown/guardian/toggle_mode/assassin/is_action_active(atom/movable/screen/movable/action_button/current_button) + return owner.has_status_effect(/datum/status_effect/guardian_stealth) + +/datum/action/cooldown/guardian/toggle_mode/gases + name = "Toggle Gas" + desc = "Switch between possible gases." + button_icon_state = "gases" diff --git a/code/datums/components/life_link.dm b/code/datums/components/life_link.dm index d1371467682..026826e4fea 100644 --- a/code/datums/components/life_link.dm +++ b/code/datums/components/life_link.dm @@ -25,14 +25,13 @@ RegisterSignal(parent, COMSIG_CARBON_LIMB_DAMAGED, PROC_REF(on_limb_damage)) RegisterSignals(parent, COMSIG_LIVING_ADJUST_STANDARD_DAMAGE_TYPES, PROC_REF(on_damage_adjusted)) RegisterSignal(parent, COMSIG_LIVING_HEALTH_UPDATE, PROC_REF(on_health_updated)) - RegisterSignal(parent, COMSIG_MOB_GET_STATUS_TAB_ITEMS, PROC_REF(on_status_tab_updated)) if (!isnull(host)) var/mob/living/living_parent = parent living_parent.updatehealth() /datum/component/life_link/UnregisterFromParent() unregister_host() - UnregisterSignal(parent, list(COMSIG_CARBON_LIMB_DAMAGED, COMSIG_LIVING_HEALTH_UPDATE, COMSIG_MOB_GET_STATUS_TAB_ITEMS) + COMSIG_LIVING_ADJUST_STANDARD_DAMAGE_TYPES) + UnregisterSignal(parent, list(COMSIG_CARBON_LIMB_DAMAGED, COMSIG_LIVING_HEALTH_UPDATE) + COMSIG_LIVING_ADJUST_STANDARD_DAMAGE_TYPES) /datum/component/life_link/InheritComponent(datum/component/new_comp, i_am_original, mob/living/host, datum/callback/on_passed_damage, datum/callback/on_linked_death) register_host(host) @@ -133,12 +132,6 @@ else mob_parent.set_hud_image_state(STATUS_HUD, "hudhealthy") -/// When our status tab updates, draw how much HP our host has in there -/datum/component/life_link/proc/on_status_tab_updated(mob/living/source, list/items) - SIGNAL_HANDLER - var/healthpercent = health_percentage(host) - items += "Host Health: [round(healthpercent, 0.5)]%" - /// Called when our host dies, we should die too /datum/component/life_link/proc/on_host_died(mob/living/source, gibbed) SIGNAL_HANDLER diff --git a/code/modules/mob/living/basic/basic.dm b/code/modules/mob/living/basic/basic.dm index bb89e69b42c..0392cfcc6bc 100644 --- a/code/modules/mob/living/basic/basic.dm +++ b/code/modules/mob/living/basic/basic.dm @@ -293,11 +293,6 @@ return return relaydrive(user, direction) -/mob/living/basic/get_status_tab_items() - . = ..() - . += "Health: [round((health / maxHealth) * 100)]%" - . += "Combat Mode: [combat_mode ? "On" : "Off"]" - /mob/living/basic/compare_sentience_type(compare_type) return sentience_type == compare_type diff --git a/code/modules/mob/living/basic/boss/boss.dm b/code/modules/mob/living/basic/boss/boss.dm index 31a7d2379a9..4ffd7961de3 100644 --- a/code/modules/mob/living/basic/boss/boss.dm +++ b/code/modules/mob/living/basic/boss/boss.dm @@ -4,6 +4,7 @@ /mob/living/basic/boss combat_mode = TRUE status_flags = NONE + abstract_type = /mob/living/basic/boss sentience_type = SENTIENCE_BOSS mob_biotypes = MOB_ORGANIC|MOB_SPECIAL faction = list(FACTION_MINING, FACTION_BOSS) diff --git a/code/modules/mob/living/basic/guardian/guardian.dm b/code/modules/mob/living/basic/guardian/guardian.dm index fd84556c99d..9c2592f9748 100644 --- a/code/modules/mob/living/basic/guardian/guardian.dm +++ b/code/modules/mob/living/basic/guardian/guardian.dm @@ -34,7 +34,6 @@ attack_sound = 'sound/items/weapons/punch1.ogg' attack_verb_continuous = "punches" attack_verb_simple = "punch" - combat_mode = TRUE obj_damage = 40 melee_damage_lower = 15 melee_damage_upper = 15 @@ -53,8 +52,8 @@ /// Coloured overlay we apply var/mutable_appearance/overlay - /// Which toggle button the HUD uses. - var/toggle_button_type = /atom/movable/screen/guardian/toggle_mode/inactive + /// Which toggle button the guardian has. Won't get one if it's null. + var/toggle_button_type = null /// Name used by the guardian creator. var/creator_name = "Error" /// Description used by the guardian creator. @@ -76,12 +75,20 @@ /// Cooldown between the summoner resetting the guardian's client. COOLDOWN_DECLARE(resetting_cooldown) - /// List of actions we give to our summoner + /// List of actions we give to our summoner. var/static/list/control_actions = list( /datum/action/cooldown/mob_cooldown/guardian_comms, /datum/action/cooldown/mob_cooldown/recall_guardian, /datum/action/cooldown/mob_cooldown/replace_guardian, ) + /// List of actions we give to ourselves. + var/static/list/self_actions = list( + /datum/action/cooldown/guardian/check_type, + /datum/action/cooldown/guardian/toggle_light, + /datum/action/cooldown/guardian/communicate, + /datum/action/cooldown/guardian/manifest, + /datum/action/cooldown/guardian/recall, + ) /mob/living/basic/guardian/Initialize(mapload, datum/guardian_fluff/theme) . = ..() @@ -90,10 +97,10 @@ theme?.apply(src) AddElement(/datum/element/death_drops, /obj/effect/temp_visual/guardian/phase/out) AddElement(/datum/element/simple_flying) - AddComponent(/datum/component/basic_inhands) // life link update_appearance(UPDATE_ICON) manifest_effects() + create_actions() /mob/living/basic/guardian/Destroy() GLOB.parasites -= src @@ -102,6 +109,18 @@ cut_summoner(different_person = TRUE) return ..() +///Creates the guardian's default action buttons and sets them to go in their proper location. +///Subtypes overwrite this for special ability types and whatnot. +/mob/living/basic/guardian/proc/create_actions() + for (var/action_type in self_actions + toggle_button_type) + if(isnull(action_type)) //no toggle button type + continue + if (locate(action_type) in actions) + continue + var/datum/action/new_action = new action_type(src) + new_action.Grant(src) + update_action_buttons() + /mob/living/basic/guardian/update_overlays() . = ..() . += overlay diff --git a/code/modules/mob/living/basic/guardian/guardian_types/assassin.dm b/code/modules/mob/living/basic/guardian/guardian_types/assassin.dm index 19f98a70f40..377c3fec0b7 100644 --- a/code/modules/mob/living/basic/guardian/guardian_types/assassin.dm +++ b/code/modules/mob/living/basic/guardian/guardian_types/assassin.dm @@ -1,5 +1,3 @@ -#define CAN_STEALTH_ALERT "can_stealth" - /** * Can enter stealth mode to become invisible and deal bonus damage on their next attack, an ambush predator. */ @@ -17,57 +15,44 @@ creator_name = "Assassin" creator_desc = "Does medium damage and takes full damage, but can enter stealth, causing its next attack to do massive damage and ignore armor. However, it becomes briefly unable to recall after attacking from stealth." creator_icon = "assassin" - toggle_button_type = /atom/movable/screen/guardian/toggle_mode/assassin + toggle_button_type = /datum/action/cooldown/guardian/toggle_mode/assassin /// How long to put stealth on cooldown if we are forced out? var/stealth_cooldown_time = 16 SECONDS - /// Cooldown for the stealth toggle. - COOLDOWN_DECLARE(stealth_cooldown) /mob/living/basic/guardian/assassin/Initialize(mapload, datum/guardian_fluff/theme) . = ..() - show_can_stealth() RegisterSignal(src, COMSIG_GUARDIAN_ASSASSIN_REVEALED, PROC_REF(on_forced_unstealth)) // Toggle stealth /mob/living/basic/guardian/assassin/toggle_modes() var/stealthed = has_status_effect(/datum/status_effect/guardian_stealth) + var/datum/action/cooldown/guardian/toggle_mode/assassin/stealth_ability = locate() in actions if (stealthed) to_chat(src, span_bolddanger("You exit stealth.")) remove_status_effect(/datum/status_effect/guardian_stealth) - show_can_stealth() + if(stealth_ability) + stealth_ability.build_all_button_icons() return - if (COOLDOWN_FINISHED(src, stealth_cooldown)) - if (!is_deployed()) - to_chat(src, span_bolddanger("You have to be manifested to enter stealth!")) - return - apply_status_effect(/datum/status_effect/guardian_stealth) - clear_alert(CAN_STEALTH_ALERT) + if (!is_deployed()) + to_chat(src, span_bolddanger("You have to be manifested to enter stealth!")) return - to_chat(src, span_bolddanger("You cannot yet enter stealth, wait another [DisplayTimeText(COOLDOWN_TIMELEFT(src, stealth_cooldown))]!")) - -/mob/living/basic/guardian/assassin/get_status_tab_items() - . = ..() - if(!COOLDOWN_FINISHED(src, stealth_cooldown)) - . += "Stealth Cooldown Remaining: [DisplayTimeText(COOLDOWN_TIMELEFT(src, stealth_cooldown))]" + apply_status_effect(/datum/status_effect/guardian_stealth) + if(stealth_ability) + stealth_ability.build_all_button_icons() /// Called when we are removed from stealth involuntarily /mob/living/basic/guardian/assassin/proc/on_forced_unstealth(mob/living/source) SIGNAL_HANDLER visible_message(span_danger("\The [src] suddenly appears!")) COOLDOWN_START(src, manifest_cooldown, 4 SECONDS) - COOLDOWN_START(src, stealth_cooldown, stealth_cooldown_time) - addtimer(CALLBACK(src, PROC_REF(show_can_stealth)), stealth_cooldown_time) - -/// Displays an alert letting us know that we can enter stealth -/mob/living/basic/guardian/assassin/proc/show_can_stealth() - if(!COOLDOWN_FINISHED(src, stealth_cooldown)) - return - throw_alert(CAN_STEALTH_ALERT, /atom/movable/screen/alert/canstealth) + var/datum/action/cooldown/guardian/toggle_mode/assassin/stealth_ability = locate() in actions + if(stealth_ability) + stealth_ability.StartCooldownSelf(stealth_cooldown_time) /// Status effect which makes us sneakier and do bonus damage /datum/status_effect/guardian_stealth id = "guardian_stealth" - alert_type = /atom/movable/screen/alert/status_effect/instealth + alert_type = null /// Damage added in stealth mode. var/damage_bonus = 35 /// Our wound bonus when in stealth mode. Allows you to actually cause wounds, unlike normal. @@ -112,5 +97,3 @@ SIGNAL_HANDLER SEND_SIGNAL(owner, COMSIG_GUARDIAN_ASSASSIN_REVEALED) qdel(src) - -#undef CAN_STEALTH_ALERT diff --git a/code/modules/mob/living/basic/guardian/guardian_types/charger.dm b/code/modules/mob/living/basic/guardian/guardian_types/charger.dm index 10ef9c34d53..2d21803c25f 100644 --- a/code/modules/mob/living/basic/guardian/guardian_types/charger.dm +++ b/code/modules/mob/living/basic/guardian/guardian_types/charger.dm @@ -11,13 +11,11 @@ creator_name = "Charger" creator_desc = "Moves very fast, does medium damage on attack, can be ridden and can charge at targets, damaging the first target hit and forcing them to drop any items they are holding." creator_icon = "charger" + toggle_button_type = /datum/action/cooldown/mob_cooldown/charge/basic_charge/guardian /mob/living/basic/guardian/charger/Initialize(mapload, datum/guardian_fluff/theme) . = ..() AddElement(/datum/element/ridable, /datum/component/riding/creature/guardian) - var/datum/action/cooldown/mob_cooldown/charge/basic_charge/guardian/charge = new(src) - charge.Grant(src) - charge.set_click_ability(src) /// Guardian charger's charging attack, it knocks items out of people's hands /datum/action/cooldown/mob_cooldown/charge/basic_charge/guardian @@ -28,6 +26,7 @@ button_icon_state = "speed" background_icon = 'icons/hud/guardian.dmi' background_icon_state = "base" + default_button_position = ui_guardian_special charge_delay = 0 recoil_duration = 0 charge_damage = 20 diff --git a/code/modules/mob/living/basic/guardian/guardian_types/dextrous.dm b/code/modules/mob/living/basic/guardian/guardian_types/dextrous.dm index 206b7b79e12..fc4ec678837 100644 --- a/code/modules/mob/living/basic/guardian/guardian_types/dextrous.dm +++ b/code/modules/mob/living/basic/guardian/guardian_types/dextrous.dm @@ -15,6 +15,7 @@ /mob/living/basic/guardian/dextrous/Initialize(mapload, datum/guardian_fluff/theme) . = ..() + AddComponent(/datum/component/basic_inhands) add_traits(list(TRAIT_ADVANCEDTOOLUSER, TRAIT_CAN_STRIP), ROUNDSTART_TRAIT) AddElement(/datum/element/dextrous, hud_type = hud_type, can_throw = TRUE) AddComponent(/datum/component/personal_crafting) @@ -24,6 +25,18 @@ dropItemToGround(internal_storage) return ..() +/mob/living/basic/guardian/dextrous/create_actions() + for (var/action_type in self_actions) + if(isnull(action_type)) //no toggle button type + continue + if (locate(action_type) in actions) + continue + var/datum/action/new_action = new action_type(src) + //Show up at the top left like usual. + new_action.default_button_position = /datum/action::default_button_position + new_action.Grant(src) + update_action_buttons() + /mob/living/basic/guardian/dextrous/examine(mob/user) . = ..() if(isnull(internal_storage) || (internal_storage.item_flags & ABSTRACT)) @@ -95,7 +108,7 @@ /mob/living/basic/guardian/dextrous/proc/update_inv_internal_storage() if(isnull(internal_storage) || isnull(client) || !hud_used?.hud_shown) return - internal_storage.screen_loc = ui_id + internal_storage.screen_loc = ui_back client.screen += internal_storage /mob/living/basic/guardian/dextrous/regenerate_icons() diff --git a/code/modules/mob/living/basic/guardian/guardian_types/explosive.dm b/code/modules/mob/living/basic/guardian/guardian_types/explosive.dm index b3c0684571d..49c15f62f40 100644 --- a/code/modules/mob/living/basic/guardian/guardian_types/explosive.dm +++ b/code/modules/mob/living/basic/guardian/guardian_types/explosive.dm @@ -37,6 +37,7 @@ cooldown_time = 20 SECONDS background_icon = 'icons/hud/guardian.dmi' background_icon_state = "base" + default_button_position = ui_guardian_special /// After this amount of time passses, bomb deactivates. var/decay_time = 1 MINUTES /// Static list of signals that activate the bomb. diff --git a/code/modules/mob/living/basic/guardian/guardian_types/gaseous.dm b/code/modules/mob/living/basic/guardian/guardian_types/gaseous.dm index 8bf00ef4362..a70bd01f43b 100644 --- a/code/modules/mob/living/basic/guardian/guardian_types/gaseous.dm +++ b/code/modules/mob/living/basic/guardian/guardian_types/gaseous.dm @@ -9,7 +9,7 @@ creator_name = "Gaseous" creator_desc = "Creates sparks on touch and continuously expels a gas of its choice. Automatically extinguishes the user if they catch on fire." creator_icon = "gaseous" - toggle_button_type = /atom/movable/screen/guardian/toggle_mode/gases + toggle_button_type = /datum/action/cooldown/guardian/toggle_mode/gases /// Ability we use to select gases var/datum/action/cooldown/mob_cooldown/expel_gas/gas /// Rate of temperature stabilization per second. diff --git a/code/modules/mob/living/basic/guardian/guardian_types/protector.dm b/code/modules/mob/living/basic/guardian/guardian_types/protector.dm index 45d746b2335..229732a30f8 100644 --- a/code/modules/mob/living/basic/guardian/guardian_types/protector.dm +++ b/code/modules/mob/living/basic/guardian/guardian_types/protector.dm @@ -9,7 +9,7 @@ creator_name = "Protector" creator_desc = "Causes you to teleport to it when out of range, unlike other parasites. Has two modes; Combat, where it does and takes medium damage, and Protection, where it does and takes almost no damage but moves slightly slower." creator_icon = "protector" - toggle_button_type = /atom/movable/screen/guardian/toggle_mode + toggle_button_type = /datum/action/cooldown/guardian/toggle_mode /// Action which toggles our shield var/datum/action/cooldown/mob_cooldown/protector_shield/shield diff --git a/code/modules/mob/living/basic/guardian/guardian_types/ranged.dm b/code/modules/mob/living/basic/guardian/guardian_types/ranged.dm index 6752c52a5af..126ca95da2c 100644 --- a/code/modules/mob/living/basic/guardian/guardian_types/ranged.dm +++ b/code/modules/mob/living/basic/guardian/guardian_types/ranged.dm @@ -13,7 +13,7 @@ creator_desc = "Has two modes. Ranged; which fires a constant stream of weak, armor-ignoring projectiles. Scout; where it cannot attack, but can move through walls and is quite hard to see. Can lay surveillance snares, which alert it when crossed, in either mode." creator_icon = "ranged" see_invisible = SEE_INVISIBLE_LIVING - toggle_button_type = /atom/movable/screen/guardian/toggle_mode + toggle_button_type = /datum/action/cooldown/guardian/toggle_mode /mob/living/basic/guardian/ranged/Initialize(mapload, datum/guardian_fluff/theme) . = ..() @@ -120,6 +120,7 @@ button_icon_state = "eye" background_icon = 'icons/hud/guardian.dmi' background_icon_state = "base" + default_button_position = ui_guardian_special cooldown_time = 2 SECONDS melee_cooldown_time = 0 click_to_activate = FALSE diff --git a/code/modules/mob/living/basic/guardian/guardian_verbs.dm b/code/modules/mob/living/basic/guardian/guardian_verbs.dm index c63dffd4316..dc95097953c 100644 --- a/code/modules/mob/living/basic/guardian/guardian_verbs.dm +++ b/code/modules/mob/living/basic/guardian/guardian_verbs.dm @@ -43,15 +43,6 @@ to_chat(src, span_notice("You deactivate your light.")) set_light_on(FALSE) - -/// Prints what type of guardian we are and what we can do. -/mob/living/basic/guardian/verb/check_type() - set name = "Check Guardian Type" - set category = "Guardian" - set desc = "Check what type you are." - to_chat(src, playstyle_string) - - /// Speak with our boss at a distance /mob/living/basic/guardian/proc/communicate() if (isnull(summoner)) 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 ea32e7e5d6d..3bd92b48950 100644 --- a/code/modules/mob/living/basic/space_fauna/revenant/_revenant.dm +++ b/code/modules/mob/living/basic/space_fauna/revenant/_revenant.dm @@ -95,7 +95,7 @@ /mob/living/basic/revenant/Initialize(mapload) . = ..() AddElement(/datum/element/simple_flying) - add_traits(list(TRAIT_SPACEWALK, TRAIT_SIXTHSENSE, TRAIT_FREE_HYPERSPACE_MOVEMENT, TRAIT_SEE_BLESSED_TILES, TRAIT_IGNORE_ELEVATION), INNATE_TRAIT) + add_traits(list(TRAIT_COMBAT_MODE_LOCK, TRAIT_SPACEWALK, TRAIT_SIXTHSENSE, TRAIT_FREE_HYPERSPACE_MOVEMENT, TRAIT_SEE_BLESSED_TILES, TRAIT_IGNORE_ELEVATION), INNATE_TRAIT) grant_actions_by_list(abilities) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index fb7af94d3c4..5ee30cec038 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -861,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)) + livingdoll.health_overlay.maptext = MAPTEXT("