diff --git a/code/__defines/hud.dm b/code/__defines/hud.dm
new file mode 100644
index 00000000000..9c08cf7d025
--- /dev/null
+++ b/code/__defines/hud.dm
@@ -0,0 +1,4 @@
+#define CLEAR_HUD_ALERTS(M) if(istype(M?.hud_used, /datum/hud) && M.hud_used.alerts) { M.hud_used.alerts = null; }
+#define SET_HUD_ALERT(M, A, V) if(istype(M?.hud_used, /datum/hud)) { LAZYSET(M.hud_used.alerts, A, V); }
+#define SET_HUD_ALERT_MIN(M, A, V) if(istype(M?.hud_used, /datum/hud) && V < LAZYACCESS(M.hud_used.alerts, A)) { LAZYSET(M.hud_used.alerts, A, V); }
+#define SET_HUD_ALERT_MAX(M, A, V) if(istype(M?.hud_used, /datum/hud) && V > LAZYACCESS(M.hud_used.alerts, A)) { LAZYSET(M.hud_used.alerts, A, V); }
diff --git a/code/__defines/mob_status.dm b/code/__defines/mob_status.dm
index 1e8ac3ef70c..42bc8854a7a 100644
--- a/code/__defines/mob_status.dm
+++ b/code/__defines/mob_status.dm
@@ -2,4 +2,4 @@
#define GET_STATUS(MOB, COND) (LAZYACCESS(MOB.status_counters, COND))
#define HAS_STATUS(MOB, COND) (GET_STATUS(MOB, COND) > 0)
#define ADJ_STATUS(MOB, COND, AMT) (MOB.set_status(COND, PENDING_STATUS(MOB, COND) + AMT))
-#define SET_STATUS_MAX(MOB, COND, AMT) (MOB.set_status(COND, max(PENDING_STATUS(MOB, COND), AMT)))
+#define SET_STATUS_MAX(MOB, COND, AMT) (MOB.set_status(COND, max(PENDING_STATUS(MOB, COND), AMT)))
\ No newline at end of file
diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm
index b7ec77eacc7..f68fe6e1ffe 100644
--- a/code/_onclick/click.dm
+++ b/code/_onclick/click.dm
@@ -351,8 +351,8 @@ var/global/list/click_catchers
return global.click_catchers
/obj/screen/click_catcher
- icon = 'icons/mob/screen_gen.dmi'
- icon_state = "click_catcher"
+ icon = 'icons/mob/screen/fill.dmi'
+ icon_state = "blank"
plane = CLICKCATCHER_PLANE
mouse_opacity = MOUSE_OPACITY_PRIORITY
screen_loc = "CENTER-7,CENTER-7"
diff --git a/code/_onclick/hud/_defines.dm b/code/_onclick/hud/_defines.dm
index 705994a1400..e308bd0ccdf 100644
--- a/code/_onclick/hud/_defines.dm
+++ b/code/_onclick/hud/_defines.dm
@@ -74,7 +74,6 @@
#define ui_up_hint "RIGHT-1:28,TOP-1:29"
#define ui_toxin "RIGHT-1:28,TOP-2:27"
#define ui_fire "RIGHT-1:28,TOP-3:25"
-#define ui_oxygen "RIGHT-1:28,TOP-4:23"
#define ui_pressure "RIGHT-1:28,TOP-5:21"
#define ui_alien_toxin "RIGHT-1:28,TOP-2:25"
diff --git a/code/_onclick/hud/_hud.dm b/code/_onclick/hud/_hud.dm
new file mode 100644
index 00000000000..4de22e1df01
--- /dev/null
+++ b/code/_onclick/hud/_hud.dm
@@ -0,0 +1,539 @@
+/*
+ The hud datum
+ Used to show and hide huds for all the different mob types,
+ including inventories and item quick actions.
+*/
+/mob
+ var/datum/hud/hud_used
+
+/mob/proc/InitializeHud()
+ if(ispath(hud_used))
+ hud_used = new hud_used(src)
+ else if(istype(hud_used))
+ hud_used.mymob = src // Probably unnecessary.
+ hud_used.refresh_client_hud()
+ refresh_lighting_master()
+
+/datum/hud
+ var/mob/mymob
+
+ var/hud_shown = 1 //Used for the HUD toggle (F12)
+ var/inventory_shown = TRUE //the inventory
+
+ /// A assoc lazylist of hud elements by category type
+ var/list/hud_elements_by_category
+ /// A assoc lazylist of hud element types to elements that need updating in Life()
+ var/list/updating_hud_elements
+ /// A linear list of types to populate the HUD with
+ var/list/hud_elements = list(
+ /decl/hud_element/health,
+ /decl/hud_element/condition/bodytemp,
+ /decl/hud_element/zone_selector,
+ /decl/hud_element/move_intent,
+ /decl/hud_element/action_intent,
+ /decl/hud_element/condition/pressure,
+ /decl/hud_element/condition/fire,
+ /decl/hud_element/condition/toxins,
+ /decl/hud_element/condition/oxygen,
+ /decl/hud_element/condition/nutrition,
+ /decl/hud_element/condition/hydration,
+ /decl/hud_element/stamina_bar,
+ /decl/hud_element/drop,
+ /decl/hud_element/resist,
+ /decl/hud_element/throwing,
+ /decl/hud_element/up_hint,
+ /decl/hud_element/pain,
+ /decl/hud_element/internals,
+ /decl/hud_element/gun_mode,
+ /decl/hud_element/gun_flag_item,
+ /decl/hud_element/gun_flag_move,
+ /decl/hud_element/gun_flag_radio
+ )
+ var/health_hud_type = /decl/hud_element/health
+ var/list/alerts
+
+ /// Whether or not the hotkey UI has been hidden.
+ var/hotkey_ui_hidden = FALSE
+ /// Linear list of hotkey UI elements.
+ var/list/obj/screen/hotkey_hud_elements = list()
+ var/list/obj/screen/misc_hud_elements = list()
+ var/list/obj/screen/hidable_hud_elements = list()
+
+ var/list/hand_hud_objects
+ var/list/swaphand_hud_objects
+
+ var/obj/screen/action_button/hide_toggle/hide_actions_toggle
+ var/action_buttons_hidden = FALSE
+
+/datum/hud/New(mob/owner)
+ mymob = owner
+ instantiate()
+ ..()
+
+/datum/hud/proc/clear_client_hud()
+ if(!mymob?.client)
+ return
+ mymob.client.screen -= hand_hud_objects
+ mymob.client.screen -= swaphand_hud_objects
+ mymob.client.screen -= misc_hud_elements
+ mymob.client.screen -= hidable_hud_elements
+ mymob.client.screen -= hotkey_hud_elements
+
+/datum/hud/proc/populate_client_hud()
+ if(!mymob?.client)
+ return
+ if(length(hand_hud_objects))
+ mymob.client.screen |= hand_hud_objects
+ if(length(swaphand_hud_objects))
+ mymob.client.screen |= swaphand_hud_objects
+ if(length(misc_hud_elements))
+ mymob.client.screen |= misc_hud_elements
+ if(length(hidable_hud_elements))
+ mymob.client.screen |= hidable_hud_elements
+ if(length(hotkey_hud_elements))
+ mymob.client.screen |= hotkey_hud_elements
+
+/datum/hud/Destroy()
+ . = ..()
+
+ clear_client_hud()
+
+ mymob = null
+ hud_elements = null
+ hud_elements_by_category = null
+ updating_hud_elements = null
+
+ QDEL_NULL_LIST(misc_hud_elements)
+ QDEL_NULL_LIST(hidable_hud_elements)
+ QDEL_NULL_LIST(hotkey_hud_elements)
+ QDEL_NULL_LIST(hand_hud_objects)
+ QDEL_NULL_LIST(swaphand_hud_objects)
+
+/mob/proc/get_hud_element(var/hud_elem_type)
+ if(istype(hud_used))
+ return hud_used.get_element(hud_elem_type)
+
+/datum/hud/proc/get_element(var/hud_elem_type)
+ return LAZYACCESS(hud_elements_by_category, hud_elem_type)
+
+/datum/hud/proc/update_stamina()
+ var/obj/screen/stamina/stamina_bar = get_element(/decl/hud_element/stamina_bar)
+ if(istype(stamina_bar))
+ stamina_bar.invisibility = INVISIBILITY_MAXIMUM
+ var/stamina = mymob.get_stamina()
+ if(stamina < 100)
+ stamina_bar.invisibility = 0
+ stamina_bar.icon_state = "prog_bar_[FLOOR(stamina/5)*5][(stamina >= 5) && (stamina <= 25) ? "_fail" : null]"
+
+/datum/hud/proc/hide_inventory()
+ inventory_shown = FALSE
+ hidden_inventory_update()
+ persistant_inventory_update()
+
+/datum/hud/proc/show_inventory()
+ inventory_shown = TRUE
+ hidden_inventory_update()
+ persistant_inventory_update()
+
+/datum/hud/proc/hidden_inventory_update()
+ var/decl/species/species = mymob?.get_species()
+ if(species?.hud)
+ refresh_inventory_slots(species.hud.hidden_slots, (inventory_shown && hud_shown))
+
+/datum/hud/proc/persistant_inventory_update()
+ var/decl/species/species = mymob?.get_species()
+ if(species?.hud)
+ refresh_inventory_slots(species.hud.persistent_slots, hud_shown)
+
+/datum/hud/proc/refresh_inventory_slots(var/list/checking_slots, var/show_hud)
+
+ for(var/slot in checking_slots)
+
+ var/datum/inventory_slot/inv_slot = mymob.get_inventory_slot_datum(slot)
+ if(!istype(inv_slot))
+ continue
+
+ // Check if we're even wearing anything in that slot.
+ var/obj/item/gear = inv_slot.get_equipped_item()
+ if(!istype(gear))
+ continue
+
+ // We're not showing anything, hide it.
+ if(!show_hud)
+ inv_slot.hide_slot()
+ else
+ inv_slot.show_slot()
+
+/datum/hud/proc/instantiate()
+ if(ismob(mymob) && mymob.client)
+ FinalizeInstantiation()
+ return TRUE
+ return FALSE
+
+/datum/hud/proc/FinalizeInstantiation()
+ SHOULD_CALL_PARENT(TRUE)
+
+ for(var/elem_type in hud_elements)
+ var/decl/hud_element/elem_data = GET_DECL(elem_type)
+ var/obj/screen/elem = elem_data.create_screen_object(src)
+ if(QDELETED(elem))
+ hud_elements -= elem_type
+ continue
+ hud_elements[elem_type] = elem
+ if(elem_data.update_in_life)
+ LAZYSET(updating_hud_elements, elem_type, elem)
+ if(elem_data.hud_element_category)
+ LAZYSET(hud_elements_by_category, elem_data.hud_element_category, elem)
+
+ build_inventory_ui()
+ build_hands_ui()
+ refresh_client_hud()
+
+/datum/hud/proc/update_health_hud()
+ if(!health_hud_type)
+ return
+ var/obj/screen/elem = LAZYACCESS(hud_elements, health_hud_type)
+ if(!elem)
+ return
+ var/decl/hud_element/elem_data = GET_DECL(health_hud_type)
+ elem_data.refresh_screen_object(src, elem)
+
+/datum/hud/proc/refresh_client_hud()
+ if(mymob?.client)
+ mymob.client.screen.Cut()
+
+ populate_client_hud()
+ hide_inventory()
+ refresh_ability_hud()
+
+/datum/hud/proc/get_ui_style()
+ return ui_style2icon(mymob?.client?.prefs?.UI_style) || 'icons/mob/screen/white.dmi'
+
+/datum/hud/proc/get_ui_color()
+ return mymob?.client?.prefs?.UI_style_color || COLOR_WHITE
+
+/datum/hud/proc/get_ui_alpha()
+ return mymob?.client?.prefs?.UI_style_alpha || 255
+
+/datum/hud/proc/rebuild_hands()
+
+ var/ui_style = get_ui_style()
+ var/ui_color = get_ui_color()
+ var/ui_alpha = get_ui_alpha()
+
+ // Build held item boxes for missing slots.
+ var/list/held_slots = mymob.get_held_item_slots()
+ for(var/hand_tag in held_slots)
+ var/obj/screen/inventory/inv_box
+ for(var/obj/screen/inventory/existing_box in hand_hud_objects)
+ if(existing_box.slot_id == hand_tag)
+ inv_box = existing_box
+ break
+ if(!inv_box)
+ inv_box = new /obj/screen/inventory()
+ var/datum/inventory_slot/inv_slot = mymob.get_inventory_slot_datum(hand_tag)
+ inv_box.SetName(hand_tag)
+ inv_box.icon = ui_style
+ inv_box.icon_state = "hand_base"
+
+ inv_box.cut_overlays()
+ inv_box.add_overlay("hand_[hand_tag]")
+ if(inv_slot.ui_label)
+ inv_box.add_overlay("hand_[inv_slot.ui_label]")
+ if(mymob.get_active_held_item_slot() == hand_tag)
+ inv_box.add_overlay("hand_selected")
+ inv_box.compile_overlays()
+
+ inv_box.slot_id = hand_tag
+ inv_box.color = ui_color
+ inv_box.alpha = ui_alpha
+ inv_box.appearance_flags |= KEEP_TOGETHER
+
+ LAZYDISTINCTADD(hand_hud_objects, inv_box)
+
+ // Clear held item boxes with no held slot.
+ for(var/obj/screen/inventory/inv_box in hand_hud_objects)
+ if(!(inv_box.slot_id in held_slots))
+ if(mymob.client)
+ mymob.client.screen -= inv_box
+ LAZYREMOVE(hand_hud_objects, inv_box)
+ qdel(inv_box)
+
+ // Rebuild offsets for the hand elements.
+ var/hand_y_offset = 5
+ var/list/elements = hand_hud_objects?.Copy()
+ while(length(elements))
+ var/copy_index = min(length(elements), 2)+1
+ var/list/sublist = elements.Copy(1, copy_index)
+ elements.Cut(1, copy_index)
+ var/obj/screen/inventory/inv_box
+ if(length(sublist) == 1)
+ inv_box = sublist[1]
+ inv_box.screen_loc = "CENTER,BOTTOM:[hand_y_offset]"
+ else
+ inv_box = sublist[1]
+ inv_box.screen_loc = "CENTER:-[world.icon_size/2],BOTTOM:[hand_y_offset]"
+ inv_box = sublist[2]
+ inv_box.screen_loc = "CENTER:[world.icon_size/2],BOTTOM:[hand_y_offset]"
+ hand_y_offset += world.icon_size
+ if(mymob.client)
+ mymob.client.screen |= inv_box
+
+ // Make sure all held items are on the screen and set to the correct screen loc.
+ var/datum/inventory_slot/inv_slot
+ for(var/obj/inv_elem in hand_hud_objects)
+ inv_slot = mymob.get_inventory_slot_datum(inv_elem.name)
+ if(inv_slot)
+ inv_slot.ui_loc = inv_elem.screen_loc
+ var/obj/item/held = inv_slot.get_equipped_item()
+ if(held)
+ held.screen_loc = inv_slot.ui_loc
+ if(mymob.client)
+ mymob.client.screen |= held // just to make sure it's visible post-login
+
+ var/hand_x_offset = -(world.icon_size/2)
+ for(var/i = 1 to length(swaphand_hud_objects))
+ var/obj/swap_elem = swaphand_hud_objects[i]
+ swap_elem.screen_loc = "CENTER:[hand_x_offset],BOTTOM:[hand_y_offset]"
+ if(i > 1) // first two elems share a slot
+ hand_x_offset += world.icon_size
+ if(mymob.client)
+ mymob.client.screen |= swap_elem
+
+/datum/hud/proc/build_inventory_ui()
+
+ var/ui_style = get_ui_style()
+ var/ui_color = get_ui_color()
+ var/ui_alpha = get_ui_alpha()
+
+ var/has_hidden_gear = FALSE
+
+ // Draw the various inventory equipment slots.
+ var/obj/screen/inventory/inv_box
+ var/list/held_slots = mymob.get_held_item_slots()
+ var/list/inventory_slots = mymob.get_inventory_slots()
+ for(var/gear_slot in inventory_slots)
+
+ if(gear_slot in held_slots)
+ continue
+
+ inv_box = new /obj/screen/inventory()
+ inv_box.icon = ui_style
+ inv_box.color = ui_color
+ inv_box.alpha = ui_alpha
+
+ var/datum/inventory_slot/inv_slot = inventory_slots[gear_slot]
+ inv_box.SetName(inv_slot.slot_name)
+ inv_box.slot_id = inv_slot.slot_id
+ inv_box.icon_state = inv_slot.slot_state
+ inv_box.screen_loc = inv_slot.ui_loc
+
+ if(inv_slot.slot_dir)
+ inv_box.set_dir(inv_slot.slot_dir)
+
+ if(inv_slot.can_be_hidden)
+ hidable_hud_elements += inv_box
+ has_hidden_gear = TRUE
+ else
+ misc_hud_elements += inv_box
+
+ if(has_hidden_gear)
+ var/obj/screen/using = new /obj/screen
+ using.SetName("toggle")
+ using.icon = ui_style
+ using.icon_state = "other"
+ using.screen_loc = ui_inventory
+ using.color = ui_color
+ using.alpha = ui_alpha
+ misc_hud_elements += using
+
+/datum/hud/proc/build_hands_ui()
+
+ var/ui_style = get_ui_style()
+ var/ui_color = get_ui_color()
+ var/ui_alpha = get_ui_alpha()
+
+ var/obj/screen/using
+
+ // Swap hand and quick equip screen elems.
+ using = new /obj/screen
+ using.SetName("equip")
+ using.icon = ui_style
+ using.icon_state = "act_equip"
+ using.color = ui_color
+ using.alpha = ui_alpha
+ misc_hud_elements += using
+ LAZYADD(swaphand_hud_objects, using)
+
+ var/list/held_slots = mymob.get_held_item_slots()
+ if(length(held_slots) > 1)
+
+ using = new /obj/screen/inventory()
+ using.SetName("hand")
+ using.icon = ui_style
+ using.icon_state = "hand1"
+ using.color = ui_color
+ using.alpha = ui_alpha
+ misc_hud_elements += using
+ LAZYADD(swaphand_hud_objects, using)
+
+ using = new /obj/screen/inventory()
+ using.SetName("hand")
+ using.icon = ui_style
+ using.icon_state = "hand2"
+ using.color = ui_color
+ using.alpha = ui_alpha
+ misc_hud_elements += using
+ LAZYADD(swaphand_hud_objects, using)
+
+ // Actual hand elems.
+ rebuild_hands()
+
+/mob/verb/minimize_hud_verb()
+ set name = "Minimize Hud"
+ set hidden = TRUE
+ set category = "OOC"
+ minimize_hud()
+
+/mob/proc/minimize_hud(var/zoom = FALSE)
+
+ if(!istype(hud_used))
+ return
+
+ if(!client || client.view != world.view || !hud_used)
+ return
+
+ var/obj/screen/action_intent = get_hud_element(/decl/hud_element/action_intent)
+ if(hud_used.hud_shown)
+ client.screen -= hud_used.misc_hud_elements
+ client.screen -= hud_used.hidable_hud_elements
+ client.screen -= hud_used.hotkey_hud_elements
+ if(action_intent)
+ action_intent.screen_loc = ui_acti_alt // move this to the alternative position, where zone_select usually is.
+ else
+ if(length(hud_used.misc_hud_elements))
+ client.screen |= hud_used.misc_hud_elements
+ if(hud_used.inventory_shown && length(hud_used.hidable_hud_elements))
+ client.screen |= hud_used.hidable_hud_elements
+ if(!hud_used.hotkey_ui_hidden && length(hud_used.hotkey_hud_elements))
+ client.screen |= hud_used.hotkey_hud_elements
+ if(action_intent)
+ action_intent.screen_loc = ui_acti //Restore intent selection to the original position
+
+ // We always want to show our hands.
+ if(LAZYLEN(hud_used.hand_hud_objects))
+ client.screen |= hud_used.hand_hud_objects
+ if(LAZYLEN(hud_used.swaphand_hud_objects))
+ client.screen |= hud_used.swaphand_hud_objects
+
+ hud_used.hud_shown = !hud_used.hud_shown
+ hud_used.hidden_inventory_update()
+ hud_used.persistant_inventory_update()
+ update_action_buttons()
+
+/client/proc/reset_click_catchers()
+
+ var/xmin = -(round(last_view_x_dim*0.5))
+ var/xmax = last_view_x_dim - abs(xmin)
+ var/ymin = -(round(last_view_y_dim*0.5))
+ var/ymax = last_view_y_dim - abs(ymin)
+
+ var/list/click_catchers = get_click_catchers()
+ for(var/obj/screen/click_catcher/catcher in click_catchers)
+ if(catcher.x_offset <= xmin || catcher.x_offset >= xmax || catcher.y_offset <= ymin || catcher.y_offset >= ymax)
+ screen -= catcher
+ else
+ screen |= catcher
+
+/mob/proc/reset_click_catchers()
+ client.reset_click_catchers()
+
+/mob/new_player/reset_click_catchers()
+ return
+
+/datum/hud/proc/update_icons()
+ if(!length(updating_hud_elements) || QDELETED(mymob))
+ return
+
+ var/obj/screen/ability_master/ability_master = get_element(/decl/hud_element/ability_master)
+ if(ability_master)
+ ability_master.update_spells(0)
+
+ var/datum/gas_mixture/environment = mymob.loc?.return_air()
+ for(var/elem_type in updating_hud_elements)
+ var/decl/hud_element/hud_elem_data = GET_DECL(elem_type)
+ hud_elem_data.refresh_screen_object(src, hud_elements[elem_type], environment)
+
+/datum/hud/proc/hide_ability_hud()
+ var/ui_alpha = get_ui_alpha()
+ for(var/elem_type in hud_elements)
+ var/decl/hud_element/hud_elem = GET_DECL(elem_type)
+ if(hud_elem.hidable)
+ var/obj/thing = hud_elements[elem_type]
+ if(istype(thing))
+ thing.alpha = hud_elem.apply_hud_alpha ? ui_alpha : initial(thing.alpha)
+ thing.invisibility = initial(thing.invisibility)
+
+/datum/hud/proc/show_ability_hud()
+ for(var/elem_type in hud_elements)
+ var/decl/hud_element/hud_elem = GET_DECL(elem_type)
+ if(hud_elem.hidable)
+ var/obj/thing = hud_elements[elem_type]
+ if(istype(thing))
+ thing.alpha = 0
+ thing.invisibility = INVISIBILITY_MAXIMUM
+
+/datum/hud/proc/should_show_ability_hud()
+ return TRUE
+
+/datum/hud/proc/refresh_ability_hud()
+
+ var/obj/screen/ability_master/ability_master = get_element(/decl/hud_element/ability_master)
+ if(ability_master)
+ ability_master.update_abilities(TRUE, mymob)
+ ability_master.toggle_open(1)
+ ability_master.synch_spells_to_mind(mymob?.mind)
+
+ if(should_show_ability_hud())
+ show_ability_hud()
+ else
+ hide_ability_hud()
+
+/datum/hud/proc/reset_hud_callback()
+ if(mymob.is_on_special_ability_cooldown())
+ return
+ var/ui_color = get_ui_color()
+ for(var/elem_type in hud_elements)
+ var/decl/hud_element/hud_elem = GET_DECL(elem_type)
+ if(hud_elem.apply_color_on_cooldown)
+ var/obj/thing = hud_elements[elem_type]
+ if(istype(thing))
+ thing.color = hud_elem.apply_hud_color ? ui_color : initial(thing.color)
+
+/datum/hud/proc/set_hud_cooldown(var/time, var/cooldown_color)
+ var/colored_a_thing = FALSE
+ for(var/elem_type in hud_elements)
+ var/decl/hud_element/hud_elem = GET_DECL(elem_type)
+ if(hud_elem.apply_color_on_cooldown)
+ var/obj/thing = hud_elements[elem_type]
+ if(istype(thing))
+ colored_a_thing = TRUE
+ thing.color = cooldown_color
+ if(colored_a_thing)
+ addtimer(CALLBACK(src, /datum/hud/proc/reset_hud_callback), time+1)
+
+/datum/hud/proc/refresh_stat_panel()
+ var/obj/screen/ability_master/ability_master = mymob.get_hud_element(/decl/hud_element/ability_master)
+ if(!ability_master?.spell_objects)
+ return
+ for(var/obj/screen/ability/spell/screen in ability_master.spell_objects)
+ var/spell/S = screen.spell
+ if((!S.connected_button) || !statpanel(S.panel))
+ continue //Not showing the noclothes spell
+ switch(S.charge_type)
+ if(Sp_RECHARGE)
+ statpanel(S.panel,"[S.charge_counter/10.0]/[S.charge_max/10]",S.connected_button)
+ if(Sp_CHARGES)
+ statpanel(S.panel,"[S.charge_counter]/[S.charge_max]",S.connected_button)
+ if(Sp_HOLDVAR)
+ statpanel(S.panel,"[S.holder_var_type] [S.holder_var_amount]",S.connected_button)
diff --git a/code/_onclick/hud/ability_screen_objects.dm b/code/_onclick/hud/ability_screen_objects.dm
index 54094c25e4b..44c9e587523 100644
--- a/code/_onclick/hud/ability_screen_objects.dm
+++ b/code/_onclick/hud/ability_screen_objects.dm
@@ -1,6 +1,6 @@
/obj/screen/ability_master
name = "Abilities"
- icon = 'icons/mob/screen_spells.dmi'
+ icon = 'icons/mob/screen/spells.dmi'
icon_state = "grey_spell_ready"
var/list/obj/screen/ability/ability_objects = list()
var/list/obj/screen/ability/spell_objects = list()
@@ -27,11 +27,6 @@
. = ..()
remove_all_abilities() //Get rid of the ability objects.
ability_objects.Cut()
- if(my_mob) // After that, remove ourselves from the mob seeing us, so we can qdel cleanly.
- my_mob.ability_master = null
- if(my_mob.client && my_mob.client.screen)
- my_mob.client.screen -= src
- my_mob = null
/obj/screen/ability_master/handle_mouse_drop(var/atom/over, var/mob/user)
if(showing)
@@ -41,7 +36,6 @@
/obj/screen/ability_master/Click()
if(!ability_objects.len) // If we're empty for some reason.
return
-
toggle_open()
/obj/screen/ability_master/proc/toggle_open(var/forced_state = 0)
@@ -149,15 +143,11 @@
var/spell/S = screen.spell
M.learned_spells |= S
-/mob/Initialize()
- . = ..()
- ability_master = new /obj/screen/ability_master(null,src)
-
///////////ACTUAL ABILITIES////////////
//This is what you click to do things//
///////////////////////////////////////
/obj/screen/ability
- icon = 'icons/mob/screen_spells.dmi'
+ icon = 'icons/mob/screen/spells.dmi'
icon_state = "grey_spell_base"
maptext_x = 3
var/background_base_state = "grey"
@@ -204,11 +194,13 @@
if(isnull(slot) || !isnum(slot))
to_chat(src,".activate_ability requires a number as input, corrisponding to the slot you wish to use.")
return // Bad input.
- if(!mob.ability_master)
+
+ var/obj/screen/ability_master/ability_master = mob.get_hud_element(/decl/hud_element/ability_master)
+ if(!ability_master)
return // No abilities.
- if(slot > mob.ability_master.ability_objects.len || slot <= 0)
+ if(slot > ability_master.ability_objects.len || slot <= 0)
return // Out of bounds.
- var/obj/screen/ability/A = mob.ability_master.ability_objects[slot]
+ var/obj/screen/ability/A = ability_master.ability_objects[slot]
A.activate()
//////////Verb Abilities//////////
diff --git a/code/_onclick/hud/ai.dm b/code/_onclick/hud/ai.dm
index 40b6339f64d..eefa3565072 100644
--- a/code/_onclick/hud/ai.dm
+++ b/code/_onclick/hud/ai.dm
@@ -1,11 +1,11 @@
/mob/living/silicon/ai
- hud_type = /datum/hud/ai
+ hud_used = /datum/hud/ai
/datum/hud/ai/FinalizeInstantiation()
var/list/ai_hud_data = decls_repository.get_decls_of_subtype(/decl/ai_hud)
for(var/elem_type in ai_hud_data)
var/decl/ai_hud/ai_hud = ai_hud_data[elem_type]
- adding += new /obj/screen/ai_button(null,
+ misc_hud_elements += new /obj/screen/ai_button(null,
ai_hud.screen_loc,
ai_hud.name,
ai_hud.icon_state,
@@ -13,4 +13,4 @@
ai_hud.input_procs,
ai_hud.input_args
)
- ..()
+ return ..()
diff --git a/code/_onclick/hud/ai_screen_objects.dm b/code/_onclick/hud/ai_screen_objects.dm
index cbbff7d5d96..77945ee7e4a 100644
--- a/code/_onclick/hud/ai_screen_objects.dm
+++ b/code/_onclick/hud/ai_screen_objects.dm
@@ -2,7 +2,7 @@
var/mob/living/silicon/ai/ai_verb
var/list/input_procs
var/list/input_args
- icon = 'icons/mob/screen_ai.dmi'
+ icon = 'icons/mob/screen/ai.dmi'
var/list/template_icon = list(null, "template")
var/image/template_undelay
diff --git a/code/_onclick/hud/animal.dm b/code/_onclick/hud/animal.dm
deleted file mode 100644
index 81868526a39..00000000000
--- a/code/_onclick/hud/animal.dm
+++ /dev/null
@@ -1,9 +0,0 @@
-
-/mob/living/simple_animal
- hud_type = /datum/hud/animal
-
-/datum/hud/animal/FinalizeInstantiation()
- action_intent = new /obj/screen/intent()
- adding += action_intent
- ..()
-
diff --git a/code/_onclick/hud/constructs.dm b/code/_onclick/hud/constructs.dm
new file mode 100644
index 00000000000..30a8ac6f975
--- /dev/null
+++ b/code/_onclick/hud/constructs.dm
@@ -0,0 +1,72 @@
+/mob/living/simple_animal/construct
+ hud_used = /datum/hud/construct/wraith
+
+/mob/living/simple_animal/construct/armoured
+ hud_used = /datum/hud/construct/juggernaut
+
+/mob/living/simple_animal/construct/behemoth
+ hud_used = /datum/hud/construct/juggernaut
+
+/mob/living/simple_animal/construct/builder
+ hud_used = /datum/hud/construct/artificer
+
+/mob/living/simple_animal/construct/harvester
+ hud_used = /datum/hud/construct/harvester
+
+/decl/hud_element/condition/fire/construct
+ screen_loc = ui_construct_fire
+
+/decl/hud_element/health/construct
+ screen_loc = ui_construct_health
+ abstract_type = /decl/hud_element/health/construct
+
+/decl/hud_element/health/construct/artificer
+ screen_icon = 'icons/mob/screen/health_construct_artificer.dmi'
+
+/decl/hud_element/health/construct/wraith
+ screen_icon = 'icons/mob/screen/health_construct_wraith.dmi'
+
+/decl/hud_element/health/construct/juggernaut
+ screen_icon = 'icons/mob/screen/health_construct_juggernaut.dmi'
+
+/decl/hud_element/health/construct/harvester
+ screen_icon = 'icons/mob/screen/health_construct_harvester.dmi'
+
+/datum/hud/construct/get_ui_style()
+ return 'icons/mob/screen/construct.dmi'
+
+/datum/hud/construct/artificer
+ health_hud_type = /decl/hud_element/health/construct/artificer
+ hud_elements = list(
+ /decl/hud_element/health/construct/artificer,
+ /decl/hud_element/zone_selector,
+ /decl/hud_element/action_intent,
+ /decl/hud_element/condition/fire/construct
+ )
+
+/datum/hud/construct/wraith
+ health_hud_type = /decl/hud_element/health/construct/wraith
+ hud_elements = list(
+ /decl/hud_element/health/construct/wraith,
+ /decl/hud_element/zone_selector,
+ /decl/hud_element/action_intent,
+ /decl/hud_element/condition/fire/construct
+ )
+
+/datum/hud/construct/juggernaut
+ health_hud_type = /decl/hud_element/health/construct/juggernaut
+ hud_elements = list(
+ /decl/hud_element/health/construct/juggernaut,
+ /decl/hud_element/zone_selector,
+ /decl/hud_element/action_intent,
+ /decl/hud_element/condition/fire/construct
+ )
+
+/datum/hud/construct/harvester
+ health_hud_type = /decl/hud_element/health/construct/harvester
+ hud_elements = list(
+ /decl/hud_element/health/construct/harvester,
+ /decl/hud_element/zone_selector,
+ /decl/hud_element/action_intent,
+ /decl/hud_element/condition/fire/construct
+ )
diff --git a/code/_onclick/hud/deity.dm b/code/_onclick/hud/deity.dm
index 44512dbdf7e..b7866b523c5 100644
--- a/code/_onclick/hud/deity.dm
+++ b/code/_onclick/hud/deity.dm
@@ -1,12 +1,19 @@
/mob/living/deity
- hud_type = /datum/hud/deity
+ hud_used = /datum/hud/deity
-/datum/hud/deity/FinalizeInstantiation()
- var/obj/screen/intent/deity/D = new()
- adding += D
- action_intent = D
- ..()
- D.sync_to_mob(mymob)
+/datum/hud/deity
+ hud_elements = list(
+ /decl/hud_element/action_intent/deity
+ )
+
+/decl/hud_element/action_intent/deity
+ screen_object_type = /obj/screen/intent/deity
+
+/decl/hud_element/action_intent/deity/register_screen_object(obj/screen/elem, datum/hud/hud)
+ var/obj/screen/intent/deity/deity_elem = elem
+ if(istype(deity_elem))
+ deity_elem.sync_to_mob(hud.mymob)
+ return ..()
/obj/screen/intent/deity
var/list/desc_screens = list()
@@ -14,7 +21,7 @@
/obj/screen/intent/deity/Initialize()
. = ..()
- overlays += image('icons/mob/screen_phenomena.dmi', icon_state = "hud", pixel_x = -138, pixel_y = -1)
+ overlays += image('icons/mob/screen/phenomena.dmi', icon_state = "hud", pixel_x = -138, pixel_y = -1)
/obj/screen/intent/deity/proc/sync_to_mob(var/mob)
var/mob/living/deity/D = mob
diff --git a/code/_onclick/hud/fullscreen.dm b/code/_onclick/hud/fullscreen.dm
index cf42a0e99ab..f180f8f608d 100644
--- a/code/_onclick/hud/fullscreen.dm
+++ b/code/_onclick/hud/fullscreen.dm
@@ -1,12 +1,12 @@
/mob
- var/list/screens = list()
+ var/list/_screens
/mob/proc/set_fullscreen(condition, screen_name, screen_type, arg)
condition ? overlay_fullscreen(screen_name, screen_type, arg) : clear_fullscreen(screen_name)
/mob/proc/overlay_fullscreen(category, type, severity)
- var/obj/screen/fullscreen/screen = screens[category]
+ var/obj/screen/fullscreen/screen = LAZYACCESS(_screens, category)
if(screen)
if(screen.type != type)
@@ -21,7 +21,7 @@
screen.icon_state = "[initial(screen.icon_state)][severity]"
screen.severity = severity
- screens[category] = screen
+ LAZYSET(_screens, category, screen)
screen.transform = null
if(screen && client && (stat != DEAD || screen.allstate))
client.screen += screen
@@ -36,11 +36,11 @@
qdel(screen)
/mob/proc/clear_fullscreen(category, animated = 10)
- var/obj/screen/fullscreen/screen = screens[category]
+ var/obj/screen/fullscreen/screen = LAZYACCESS(_screens, category)
if(!screen)
return
- screens -= category
+ LAZYREMOVE(_screens, category)
if(animated)
show_screen(screen, animated)
@@ -50,19 +50,19 @@
qdel(screen)
/mob/proc/clear_fullscreens()
- for(var/category in screens)
+ for(var/category in _screens)
clear_fullscreen(category)
/mob/proc/hide_fullscreens()
if(client)
- for(var/category in screens)
- client.screen -= screens[category]
+ for(var/category in _screens)
+ client.screen -= _screens[category]
/mob/proc/reload_fullscreen()
if(client)
var/largest_bound = max(client.last_view_x_dim, client.last_view_y_dim)
- for(var/category in screens)
- var/obj/screen/fullscreen/screen = screens[category]
+ for(var/category in _screens)
+ var/obj/screen/fullscreen/screen = _screens[category]
screen.transform = null
if(screen.screen_loc != ui_entire_screen && largest_bound > 7)
var/matrix/M = matrix()
@@ -71,7 +71,7 @@
client.screen |= screen
/obj/screen/fullscreen
- icon = 'icons/mob/screen_full.dmi'
+ icon = 'icons/mob/screen/full.dmi'
icon_state = "default"
screen_loc = ui_center_fullscreen
plane = FULLSCREEN_PLANE
@@ -101,7 +101,7 @@
layer = BLIND_LAYER
/obj/screen/fullscreen/blackout
- icon = 'icons/mob/screen1.dmi'
+ icon = 'icons/mob/screen/fill.dmi'
icon_state = "black"
screen_loc = ui_entire_screen
layer = BLIND_LAYER
@@ -111,13 +111,13 @@
layer = IMPAIRED_LAYER
/obj/screen/fullscreen/blurry
- icon = 'icons/mob/screen1.dmi'
+ icon = 'icons/mob/screen/fill.dmi'
screen_loc = ui_entire_screen
icon_state = "blurry"
alpha = 100
/obj/screen/fullscreen/flash
- icon = 'icons/mob/screen1.dmi'
+ icon = 'icons/mob/screen/fill.dmi'
screen_loc = ui_entire_screen
icon_state = "flash"
@@ -125,7 +125,7 @@
icon_state = "noise"
/obj/screen/fullscreen/high
- icon = 'icons/mob/screen1.dmi'
+ icon = 'icons/mob/screen/fill.dmi'
screen_loc = ui_entire_screen
icon_state = "druggy"
alpha = 180
@@ -138,7 +138,7 @@
alpha = 127
/obj/screen/fullscreen/fadeout
- icon = 'icons/mob/screen1.dmi'
+ icon = 'icons/mob/screen/fill.dmi'
icon_state = "black"
screen_loc = ui_entire_screen
alpha = 0
diff --git a/code/_onclick/hud/gun_mode.dm b/code/_onclick/hud/gun_mode.dm
deleted file mode 100644
index 349fce96b0f..00000000000
--- a/code/_onclick/hud/gun_mode.dm
+++ /dev/null
@@ -1,65 +0,0 @@
-/obj/screen/gun
- name = "gun"
- icon = 'icons/mob/screen1.dmi'
- dir = SOUTH
-
-/obj/screen/gun/Click(location, control, params)
- if(!usr)
- return
- return 1
-
-/obj/screen/gun/move
- name = "Allow Movement"
- icon_state = "no_walk1"
- screen_loc = ui_gun2
-
-/obj/screen/gun/move/Click(location, control, params)
- if(..())
- var/mob/living/user = usr
- if(istype(user))
- if(!user.aiming) user.aiming = new(user)
- user.aiming.toggle_permission(TARGET_CAN_MOVE)
- return 1
- return 0
-
-/obj/screen/gun/item
- name = "Allow Item Use"
- icon_state = "no_item1"
- screen_loc = ui_gun1
-
-/obj/screen/gun/item/Click(location, control, params)
- if(..())
- var/mob/living/user = usr
- if(istype(user))
- if(!user.aiming) user.aiming = new(user)
- user.aiming.toggle_permission(TARGET_CAN_CLICK)
- return 1
- return 0
-
-/obj/screen/gun/mode
- name = "Toggle Gun Mode"
- icon_state = "gun0"
- screen_loc = ui_gun_select
-
-/obj/screen/gun/mode/Click(location, control, params)
- if(..())
- var/mob/living/user = usr
- if(istype(user))
- if(!user.aiming) user.aiming = new(user)
- user.aiming.toggle_active()
- return 1
- return 0
-
-/obj/screen/gun/radio
- name = "Disallow Radio Use"
- icon_state = "no_radio1"
- screen_loc = ui_gun4
-
-/obj/screen/gun/radio/Click(location, control, params)
- if(..())
- var/mob/living/user = usr
- if(istype(user))
- if(!user.aiming) user.aiming = new(user)
- user.aiming.toggle_permission(TARGET_CAN_RADIO)
- return 1
- return 0
diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm
deleted file mode 100644
index 01c911e1572..00000000000
--- a/code/_onclick/hud/hud.dm
+++ /dev/null
@@ -1,450 +0,0 @@
-/*
- The hud datum
- Used to show and hide huds for all the different mob types,
- including inventories and item quick actions.
-*/
-
-/mob
- var/hud_type = null
- var/datum/hud/hud_used = null
-
-/mob/proc/InitializeHud()
- if(hud_used)
- qdel(hud_used)
- if(hud_type)
- hud_used = new hud_type(src)
- else
- hud_used = new /datum/hud(src)
- refresh_lighting_master()
-
-/datum/hud
- var/mob/mymob
-
- var/hud_shown = 1 //Used for the HUD toggle (F12)
- var/inventory_shown = TRUE //the inventory
- var/show_intent_icons = FALSE
- var/hotkey_ui_hidden = FALSE //This is to hide the buttons that can be used via hotkeys. (hotkeybuttons list of buttons)
-
- var/obj/screen/lingchemdisplay
- var/list/hand_hud_objects
- var/list/swaphand_hud_objects
- var/obj/screen/action_intent
- var/obj/screen/move_intent
- var/obj/screen/stamina/stamina_bar
-
- var/list/adding = list()
- var/list/other = list()
- var/list/hud_elements = list()
- var/list/obj/screen/hotkeybuttons
-
- var/obj/screen/action_button/hide_toggle/hide_actions_toggle
- var/action_buttons_hidden = FALSE
-
-/datum/hud/New(mob/owner)
- mymob = owner
- instantiate()
- ..()
-
-/datum/hud/Destroy()
- . = ..()
- stamina_bar = null
- lingchemdisplay = null
- action_intent = null
- move_intent = null
- adding = null
- other = null
- hotkeybuttons = null
- mymob = null
- QDEL_NULL_LIST(hand_hud_objects)
- QDEL_NULL_LIST(swaphand_hud_objects)
-
-/datum/hud/proc/update_stamina()
- if(mymob && stamina_bar)
- stamina_bar.set_invisibility(INVISIBILITY_MAXIMUM)
- var/stamina = mymob.get_stamina()
- if(stamina < 100)
- stamina_bar.set_invisibility(INVISIBILITY_NONE)
- stamina_bar.icon_state = "prog_bar_[FLOOR(stamina/5)*5][(stamina >= 5) && (stamina <= 25) ? "_fail" : null]"
-
-/datum/hud/proc/hide_inventory()
- inventory_shown = FALSE
- hidden_inventory_update()
- persistant_inventory_update()
-
-/datum/hud/proc/show_inventory()
- inventory_shown = TRUE
- hidden_inventory_update()
- persistant_inventory_update()
-
-/datum/hud/proc/hidden_inventory_update()
- var/decl/species/species = mymob?.get_species()
- if(species?.hud)
- refresh_inventory_slots(species.hud.hidden_slots, (inventory_shown && hud_shown))
-
-/datum/hud/proc/persistant_inventory_update()
- var/decl/species/species = mymob?.get_species()
- if(species?.hud)
- refresh_inventory_slots(species.hud.persistent_slots, hud_shown)
-
-/datum/hud/proc/refresh_inventory_slots(var/list/checking_slots, var/show_hud)
-
- for(var/slot in checking_slots)
-
- var/datum/inventory_slot/inv_slot = mymob.get_inventory_slot_datum(slot)
- if(!istype(inv_slot))
- continue
-
- // Check if we're even wearing anything in that slot.
- var/obj/item/gear = inv_slot.get_equipped_item()
- if(!istype(gear))
- continue
-
- // We're not showing anything, hide it.
- gear.reconsider_client_screen_presence(mymob?.client, slot)
- if(!show_hud)
- inv_slot.hide_slot()
- else
- inv_slot.show_slot()
-
-/datum/hud/proc/instantiate()
- if(ismob(mymob) && mymob.client)
- FinalizeInstantiation()
- return TRUE
- return FALSE
-
-/datum/hud/proc/FinalizeInstantiation()
- SHOULD_CALL_PARENT(TRUE)
- BuildInventoryUI()
- if(mymob.client)
- mymob.client.screen = list()
- if(length(hand_hud_objects))
- mymob.client.screen |= hand_hud_objects
- if(length(swaphand_hud_objects))
- mymob.client.screen |= swaphand_hud_objects
- if(length(hud_elements))
- mymob.client.screen |= hud_elements
- if(length(adding))
- mymob.client.screen |= adding
- if(length(hotkeybuttons))
- mymob.client.screen |= hotkeybuttons
- hide_inventory()
-
-/datum/hud/proc/get_ui_style()
- return ui_style2icon(mymob?.client?.prefs?.UI_style) || 'icons/mob/screen/white.dmi'
-
-/datum/hud/proc/get_ui_color()
- return mymob?.client?.prefs?.UI_style_color || COLOR_WHITE
-
-/datum/hud/proc/get_ui_alpha()
- return mymob?.client?.prefs?.UI_style_alpha || 255
-
-/datum/hud/proc/rebuild_hands()
-
- var/ui_style = get_ui_style()
- var/ui_color = get_ui_color()
- var/ui_alpha = get_ui_alpha()
-
- // Build held item boxes for missing slots.
- var/list/held_slots = mymob.get_held_item_slots()
-
- // Sort our slots for display.
- var/list/gripper_datums = list()
- for(var/hand_tag in held_slots)
- gripper_datums += mymob.get_inventory_slot_datum(hand_tag)
- gripper_datums = sortTim(gripper_datums, /proc/cmp_gripper_asc)
-
- for(var/datum/inventory_slot/inv_slot in gripper_datums)
-
- // Re-order the held slot list so it aligns with the display order.
- var/hand_tag = inv_slot.slot_id
- held_slots -= hand_tag
- held_slots += hand_tag
-
- var/obj/screen/inventory/inv_box
- for(var/obj/screen/inventory/existing_box in hand_hud_objects)
- if(existing_box.slot_id == hand_tag)
- inv_box = existing_box
- break
- if(!inv_box)
- inv_box = new /obj/screen/inventory(null, mymob)
- inv_box.SetName(hand_tag)
- inv_box.icon = ui_style
- inv_box.icon_state = "hand_base"
-
- inv_box.cut_overlays()
- inv_box.add_overlay("hand_[hand_tag]", TRUE)
- if(inv_slot.ui_label)
- inv_box.add_overlay("hand_[inv_slot.ui_label]", TRUE)
- inv_box.update_icon()
-
- inv_box.slot_id = hand_tag
- inv_box.color = ui_color
- inv_box.alpha = ui_alpha
- inv_box.appearance_flags |= KEEP_TOGETHER
-
- LAZYDISTINCTADD(hand_hud_objects, inv_box)
-
- // Clear held item boxes with no held slot.
- for(var/obj/screen/inventory/inv_box in hand_hud_objects)
- if(!(inv_box.slot_id in held_slots))
- if(mymob.client)
- mymob.client.screen -= inv_box
- LAZYREMOVE(hand_hud_objects, inv_box)
- qdel(inv_box)
-
- // Rebuild offsets for the hand elements.
- var/hand_y_offset = 5
- var/list/elements = hand_hud_objects?.Copy()
- while(length(elements))
- var/copy_index = min(length(elements), 2)+1
- var/list/sublist = elements.Copy(1, copy_index)
- elements.Cut(1, copy_index)
- var/obj/screen/inventory/inv_box
- if(length(sublist) == 1)
- inv_box = sublist[1]
- inv_box.screen_loc = "CENTER,BOTTOM:[hand_y_offset]"
- else
- inv_box = sublist[1]
- inv_box.screen_loc = "CENTER:-[world.icon_size/2],BOTTOM:[hand_y_offset]"
- inv_box = sublist[2]
- inv_box.screen_loc = "CENTER:[world.icon_size/2],BOTTOM:[hand_y_offset]"
- hand_y_offset += world.icon_size
- if(mymob.client)
- mymob.client.screen |= inv_box
-
- // Make sure all held items are on the screen and set to the correct screen loc.
- var/datum/inventory_slot/inv_slot
- for(var/obj/inv_elem in hand_hud_objects)
- inv_slot = mymob.get_inventory_slot_datum(inv_elem.name)
- if(inv_slot)
- inv_slot.ui_loc = inv_elem.screen_loc
- var/obj/item/held = inv_slot.get_equipped_item()
- if(held)
- held.screen_loc = inv_slot.ui_loc
- if(mymob.client)
- mymob.client.screen |= held // just to make sure it's visible post-login
-
- var/hand_x_offset = -(world.icon_size/2)
- for(var/i = 1 to length(swaphand_hud_objects))
- var/obj/swap_elem = swaphand_hud_objects[i]
- swap_elem.screen_loc = "CENTER:[hand_x_offset],BOTTOM:[hand_y_offset]"
- if(i > 1) // first two elems share a slot
- hand_x_offset += world.icon_size
- if(mymob.client)
- mymob.client.screen |= swap_elem
-
-/datum/hud/proc/BuildInventoryUI()
-
- var/ui_style = get_ui_style()
- var/ui_color = get_ui_color()
- var/ui_alpha = get_ui_alpha()
-
- var/has_hidden_gear = FALSE
-
- // Draw the various inventory equipment slots.
- var/obj/screen/inventory/inv_box
- var/list/held_slots = mymob.get_held_item_slots()
- var/list/inventory_slots = mymob.get_inventory_slots()
- for(var/gear_slot in inventory_slots)
-
- if(gear_slot in held_slots)
- continue
-
- inv_box = new /obj/screen/inventory(null, mymob)
- inv_box.icon = ui_style
- inv_box.color = ui_color
- inv_box.alpha = ui_alpha
-
- var/datum/inventory_slot/inv_slot = inventory_slots[gear_slot]
- inv_box.SetName(inv_slot.slot_name)
- inv_box.slot_id = inv_slot.slot_id
- inv_box.icon_state = inv_slot.slot_state
- inv_box.screen_loc = inv_slot.ui_loc
-
- if(inv_slot.slot_dir)
- inv_box.set_dir(inv_slot.slot_dir)
-
- if(inv_slot.can_be_hidden)
- other += inv_box
- has_hidden_gear = TRUE
- else
- adding += inv_box
-
- if(has_hidden_gear)
- var/obj/screen/using = new /obj/screen()
- using.SetName("toggle")
- using.icon = ui_style
- using.icon_state = "other"
- using.screen_loc = ui_inventory
- using.color = ui_color
- using.alpha = ui_alpha
- adding += using
-
-/datum/hud/proc/BuildHandsUI()
-
- var/ui_style = get_ui_style()
- var/ui_color = get_ui_color()
- var/ui_alpha = get_ui_alpha()
-
- var/obj/screen/using
-
- // Swap hand and quick equip screen elems.
- using = new /obj/screen()
- using.SetName("equip")
- using.icon = ui_style
- using.icon_state = "act_equip"
- using.color = ui_color
- using.alpha = ui_alpha
- src.adding += using
- LAZYADD(swaphand_hud_objects, using)
-
- var/list/held_slots = mymob.get_held_item_slots()
- if(length(held_slots) > 1)
-
- using = new /obj/screen/inventory(null, mymob)
- using.SetName("hand")
- using.icon = ui_style
- using.icon_state = "hand1"
- using.color = ui_color
- using.alpha = ui_alpha
- src.adding += using
- LAZYADD(swaphand_hud_objects, using)
-
- using = new /obj/screen/inventory(null, mymob)
- using.SetName("hand")
- using.icon = ui_style
- using.icon_state = "hand2"
- using.color = ui_color
- using.alpha = ui_alpha
- src.adding += using
- LAZYADD(swaphand_hud_objects, using)
-
- // Actual hand elems.
- rebuild_hands()
-
-/mob/verb/minimize_hud(full = FALSE as null)
- set name = "Minimize Hud"
- set hidden = TRUE
-
- if(!hud_used)
- to_chat(usr, "This mob type does not use a HUD.")
- return
-
- if(!ishuman(src))
- to_chat(usr, "Inventory hiding is currently only supported for human mobs, sorry.")
- return
-
- if(!client) return
- if(client.view != world.view)
- return
- if(hud_used.hud_shown)
- hud_used.hud_shown = 0
- if(src.hud_used.adding)
- src.client.screen -= src.hud_used.adding
- if(src.hud_used.other)
- src.client.screen -= src.hud_used.other
- if(src.hud_used.hotkeybuttons)
- src.client.screen -= src.hud_used.hotkeybuttons
-
- //Due to some poor coding some things need special treatment:
- //These ones are a part of 'adding', 'other' or 'hotkeybuttons' but we want them to stay
- if(!full)
- if(LAZYLEN(hud_used.hand_hud_objects))
- client.screen += hud_used.hand_hud_objects // we want the hands to be visible
- if(LAZYLEN(hud_used.swaphand_hud_objects))
- client.screen += hud_used.swaphand_hud_objects // we want the hands swap thingy to be visible
- src.client.screen += src.hud_used.action_intent // we want the intent swticher visible
- src.hud_used.action_intent.screen_loc = ui_acti_alt // move this to the alternative position, where zone_select usually is.
- else
- src.client.screen -= src.healths
- src.client.screen -= src.internals
- src.client.screen -= src.gun_setting_icon
-
- //These ones are not a part of 'adding', 'other' or 'hotkeybuttons' but we want them gone.
- src.client.screen -= src.zone_sel //zone_sel is a mob variable for some reason.
-
- else
- hud_used.hud_shown = 1
- if(src.hud_used.adding)
- src.client.screen += src.hud_used.adding
- if(src.hud_used.other && src.hud_used.inventory_shown)
- src.client.screen += src.hud_used.other
- if(src.hud_used.hotkeybuttons && !src.hud_used.hotkey_ui_hidden)
- src.client.screen += src.hud_used.hotkeybuttons
- if(src.healths)
- src.client.screen |= src.healths
- if(src.internals)
- src.client.screen |= src.internals
- if(src.gun_setting_icon)
- src.client.screen |= src.gun_setting_icon
-
- src.hud_used.action_intent.screen_loc = ui_acti //Restore intent selection to the original position
- src.client.screen += src.zone_sel //This one is a special snowflake
-
- hud_used.hidden_inventory_update()
- hud_used.persistant_inventory_update()
- update_action_buttons()
-
-//Similar to minimize_hud() but keeps zone_sel, gun_setting_icon, and healths.
-/mob/proc/toggle_zoom_hud()
- if(!hud_used)
- return
- if(!ishuman(src))
- return
- if(!client)
- return
- if(client.view != world.view)
- return
-
- if(hud_used.hud_shown)
- hud_used.hud_shown = 0
- if(src.hud_used.adding)
- src.client.screen -= src.hud_used.adding
- if(src.hud_used.other)
- src.client.screen -= src.hud_used.other
- if(src.hud_used.hotkeybuttons)
- src.client.screen -= src.hud_used.hotkeybuttons
- src.client.screen -= src.internals
- src.client.screen += src.hud_used.action_intent //we want the intent swticher visible
- else
- hud_used.hud_shown = 1
- if(src.hud_used.adding)
- src.client.screen += src.hud_used.adding
- if(src.hud_used.other && src.hud_used.inventory_shown)
- src.client.screen += src.hud_used.other
- if(src.hud_used.hotkeybuttons && !src.hud_used.hotkey_ui_hidden)
- src.client.screen += src.hud_used.hotkeybuttons
- if(src.internals)
- src.client.screen |= src.internals
- src.hud_used.action_intent.screen_loc = ui_acti //Restore intent selection to the original position
-
- hud_used.hidden_inventory_update()
- hud_used.persistant_inventory_update()
- update_action_buttons()
-
-/client/proc/reset_click_catchers()
-
- var/xmin = -(round(last_view_x_dim*0.5))
- var/xmax = last_view_x_dim - abs(xmin)
- var/ymin = -(round(last_view_y_dim*0.5))
- var/ymax = last_view_y_dim - abs(ymin)
-
- var/list/click_catchers = get_click_catchers()
- for(var/obj/screen/click_catcher/catcher in click_catchers)
- if(catcher.x_offset <= xmin || catcher.x_offset >= xmax || catcher.y_offset <= ymin || catcher.y_offset >= ymax)
- screen -= catcher
- else
- screen |= catcher
-
-/mob/proc/add_click_catcher()
- client.reset_click_catchers()
-
-/mob/new_player/add_click_catcher()
- return
-
-/obj/screen/stamina
- name = "stamina"
- icon = 'icons/effects/progressbar.dmi'
- icon_state = "prog_bar_100"
- invisibility = INVISIBILITY_MAXIMUM
- screen_loc = ui_stamina
diff --git a/code/_onclick/hud/hud_elements/_hud_element.dm b/code/_onclick/hud/hud_elements/_hud_element.dm
new file mode 100644
index 00000000000..4d091c58951
--- /dev/null
+++ b/code/_onclick/hud/hud_elements/_hud_element.dm
@@ -0,0 +1,49 @@
+/decl/hud_element
+ abstract_type = /decl/hud_element
+ var/screen_name
+ var/screen_icon
+ var/screen_icon_state
+ var/screen_loc
+ var/screen_object_type = /obj/screen
+
+ var/hidable = FALSE
+ var/apply_hud_color = TRUE
+ var/apply_hud_alpha = TRUE
+ var/apply_hud_icon = TRUE
+ var/apply_color_on_cooldown = FALSE
+
+ var/update_in_life = FALSE
+
+ var/hud_element_category
+
+/decl/hud_element/proc/refresh_screen_object(var/datum/hud/hud, var/obj/screen/elem, var/datum/gas_mixture/environment)
+ return
+
+/decl/hud_element/proc/create_screen_object(var/datum/hud/hud)
+ var/obj/screen/elem = new screen_object_type
+ if(screen_name)
+ elem.SetName(screen_name)
+ if(apply_hud_color)
+ elem.color = hud.get_ui_color()
+ if(apply_hud_alpha)
+ elem.alpha = hud.get_ui_alpha()
+ if(apply_hud_icon)
+ elem.icon = hud.get_ui_style()
+ else if(screen_icon)
+ elem.icon = screen_icon
+ if(screen_icon_state)
+ elem.icon_state = screen_icon_state
+ if(screen_loc)
+ elem.screen_loc = screen_loc
+ register_screen_object(elem, hud)
+ return elem
+
+/decl/hud_element/proc/register_screen_object(var/obj/screen/elem, var/datum/hud/hud)
+ hud.misc_hud_elements |= elem
+
+/decl/hud_element/condition
+ screen_icon = 'icons/mob/screen/condition.dmi'
+ apply_hud_icon = FALSE
+ apply_hud_alpha = FALSE
+ apply_hud_color = FALSE
+ update_in_life = TRUE
diff --git a/code/_onclick/hud/hud_elements/ability_master.dm b/code/_onclick/hud/hud_elements/ability_master.dm
new file mode 100644
index 00000000000..3f09c1f9f78
--- /dev/null
+++ b/code/_onclick/hud/hud_elements/ability_master.dm
@@ -0,0 +1,8 @@
+/decl/hud_element/ability_master
+ apply_hud_icon = FALSE
+ apply_hud_alpha = FALSE
+ apply_hud_color = FALSE
+ hud_element_category = /decl/hud_element/ability_master
+
+/decl/hud_element/ability_master/create_screen_object(datum/hud/hud)
+ return new /obj/screen/ability_master(null, hud?.mymob)
diff --git a/code/_onclick/hud/hud_elements/action_intent.dm b/code/_onclick/hud/hud_elements/action_intent.dm
new file mode 100644
index 00000000000..595ee131b57
--- /dev/null
+++ b/code/_onclick/hud/hud_elements/action_intent.dm
@@ -0,0 +1,29 @@
+/decl/hud_element/action_intent
+ screen_object_type = /obj/screen/intent
+ screen_icon = 'icons/mob/screen/intent.dmi'
+ hud_element_category = /decl/hud_element/action_intent
+
+/obj/screen/intent
+ name = "intent"
+ icon = 'icons/mob/screen/white.dmi'
+ icon_state = "intent_help"
+ screen_loc = ui_acti
+ var/intent = I_HELP
+
+/obj/screen/intent/Click(var/location, var/control, var/params)
+ var/list/P = params2list(params)
+ var/icon_x = text2num(P["icon-x"])
+ var/icon_y = text2num(P["icon-y"])
+ intent = I_DISARM
+ if(icon_x <= world.icon_size/2)
+ if(icon_y <= world.icon_size/2)
+ intent = I_HURT
+ else
+ intent = I_HELP
+ else if(icon_y <= world.icon_size/2)
+ intent = I_GRAB
+ update_icon()
+ usr.a_intent = intent
+
+/obj/screen/intent/on_update_icon()
+ icon_state = "intent_[intent]"
diff --git a/code/_onclick/hud/hud_elements/bodytemp.dm b/code/_onclick/hud/hud_elements/bodytemp.dm
new file mode 100644
index 00000000000..1854f103a56
--- /dev/null
+++ b/code/_onclick/hud/hud_elements/bodytemp.dm
@@ -0,0 +1,37 @@
+/decl/hud_element/condition/bodytemp
+ screen_name = "body temperature"
+ screen_object_type = /obj/screen/bodytemp
+ hud_element_category = /decl/hud_element/condition/bodytemp
+ screen_icon_state = "temp1"
+ screen_loc = ui_temp
+
+/decl/hud_element/condition/bodytemp/refresh_screen_object(var/datum/hud/hud, var/obj/screen/elem, var/datum/gas_mixture/environment)
+ //TODO: precalculate all of this stuff when the species datum is created
+ var/bodytemp = hud.mymob.bodytemperature
+ var/base_temperature = hud.mymob.get_ideal_bodytemp()
+ if (bodytemp >= base_temperature)
+ var/heat_level_1 = hud.mymob.get_temperature_threshold(HEAT_LEVEL_1)
+ var/temp_step = (heat_level_1 - base_temperature)/4
+ if (bodytemp >= heat_level_1)
+ elem.icon_state = "temp4"
+ else if (bodytemp >= base_temperature + temp_step*3)
+ elem.icon_state = "temp3"
+ else if (bodytemp >= base_temperature + temp_step*2)
+ elem.icon_state = "temp2"
+ else if (bodytemp >= base_temperature + temp_step*1)
+ elem.icon_state = "temp1"
+ else
+ elem.icon_state = "temp0"
+ else if (bodytemp < base_temperature)
+ var/cold_level_1 = hud.mymob.get_temperature_threshold(COLD_LEVEL_1)
+ var/temp_step = (base_temperature - cold_level_1)/4
+ if (bodytemp <= cold_level_1)
+ elem.icon_state = "temp-4"
+ else if (bodytemp <= base_temperature - temp_step*3)
+ elem.icon_state = "temp-3"
+ else if (bodytemp <= base_temperature - temp_step*2)
+ elem.icon_state = "temp-2"
+ else if (bodytemp <= base_temperature - temp_step*1)
+ elem.icon_state = "temp-1"
+ else
+ elem.icon_state = "temp0"
diff --git a/code/_onclick/hud/hud_elements/cells.dm b/code/_onclick/hud/hud_elements/cells.dm
new file mode 100644
index 00000000000..34aacb6d77e
--- /dev/null
+++ b/code/_onclick/hud/hud_elements/cells.dm
@@ -0,0 +1,21 @@
+/decl/hud_element/cells
+ screen_name = "cell"
+ screen_icon_state = "charge-empty"
+ screen_icon = 'icons/mob/screen/robot_charge.dmi'
+ screen_loc = ui_nutrition
+ update_in_life = TRUE
+
+/decl/hud_element/cells/refresh_screen_object(datum/hud/hud, obj/screen/elem, datum/gas_mixture/environment)
+ if(!isliving(hud?.mymob))
+ return
+ var/mob/living/user = hud.mymob
+ if(!user.isSynthetic())
+ elem.invisibility = INVISIBILITY_MAXIMUM
+ else
+ elem.invisibility = 0
+ var/obj/item/cell/cell = user.get_cell()
+ if(cell)
+ // 0-100 maps to 0-4, but give it a paranoid clamp just in case.
+ elem.icon_state = "charge[clamp(CEILING(cell.percent()/25), 0, 4)]"
+ else
+ elem.icon_state = "charge-empty"
diff --git a/code/_onclick/hud/hud_elements/drop.dm b/code/_onclick/hud/hud_elements/drop.dm
new file mode 100644
index 00000000000..d957a227b96
--- /dev/null
+++ b/code/_onclick/hud/hud_elements/drop.dm
@@ -0,0 +1,7 @@
+/decl/hud_element/drop
+ screen_name = "drop"
+ screen_icon_state = "act_drop"
+ screen_loc = ui_drop_throw
+
+/decl/hud_element/drop/register_screen_object(obj/screen/elem, datum/hud/hud)
+ hud.hotkey_hud_elements |= elem
diff --git a/code/_onclick/hud/hud_elements/fire.dm b/code/_onclick/hud/hud_elements/fire.dm
new file mode 100644
index 00000000000..706ee23b465
--- /dev/null
+++ b/code/_onclick/hud/hud_elements/fire.dm
@@ -0,0 +1,8 @@
+/decl/hud_element/condition/fire
+ screen_name = "fire"
+ screen_icon_state = "fire0"
+ screen_loc = ui_fire
+ hud_element_category = /decl/hud_element/condition/fire
+
+/decl/hud_element/condition/fire/refresh_screen_object(var/datum/hud/hud, var/obj/screen/elem, var/datum/gas_mixture/environment)
+ screen_icon_state = "fire[hud?.alerts ? (hud.alerts[hud_element_category] || 0) : 0]"
diff --git a/code/_onclick/hud/hud_elements/gun_mode.dm b/code/_onclick/hud/hud_elements/gun_mode.dm
new file mode 100644
index 00000000000..76f2d224d69
--- /dev/null
+++ b/code/_onclick/hud/hud_elements/gun_mode.dm
@@ -0,0 +1,95 @@
+// Omit the base gun_mode because it doesn't care about specific gun use flags
+var/global/list/gun_hud_flag_decl_types = list(
+ /decl/hud_element/gun_flag_move,
+ /decl/hud_element/gun_flag_item,
+ /decl/hud_element/gun_flag_radio
+)
+
+/// Root type for flag toggling in gun mode.
+/obj/screen/gun_flag
+ name = "gun"
+ master = null
+ dir = SOUTH
+
+ var/option_name
+ var/option_state
+ var/option_flag
+
+/obj/screen/gun_flag/proc/update_from_aiming_overlay(var/obj/aiming_overlay/aiming_overlay)
+ if(!aiming_overlay || !option_flag || !option_name || !option_state)
+ return
+ if(aiming_overlay.target_permissions & option_flag)
+ icon_state = "[option_state]1"
+ SetName("Disallow [option_name]]")
+ else
+ icon_state = "[option_state]0"
+ SetName("Allow [option_name]")
+
+/obj/screen/gun_flag/Click(location, control, params)
+ if(isliving(usr) && option_flag && option_name && option_state)
+ var/mob/living/user = usr
+ if(!user.aiming)
+ user.aiming = new(user)
+ user.aiming.toggle_permission(option_flag)
+ return TRUE
+ return FALSE
+
+/// Root gun mode type - toggles aiming mode off or on when ticked.
+/obj/screen/gun_mode
+ name = "Toggle Gun Mode"
+ icon_state = "gun0"
+ screen_loc = ui_gun_select
+ master = null
+ dir = SOUTH
+
+/decl/hud_element/gun_mode
+ screen_object_type = /obj/screen/gun_mode
+ hud_element_category = /decl/hud_element/gun_mode
+
+/// Element for dis/allowing gun mode target clicking.
+/obj/screen/gun_flag/item
+ name = "Allow Item Use"
+ icon_state = "no_item1"
+ screen_loc = ui_gun1
+ option_name = "Item Use"
+ option_state = "no_item"
+ option_flag = TARGET_CAN_CLICK
+
+/decl/hud_element/gun_flag_item
+ screen_object_type = /obj/screen/gun_flag/item
+ hud_element_category = /decl/hud_element/gun_flag_item
+
+/decl/hud_element/gun_flag_item/register_screen_object(obj/screen/elem, datum/hud/hud)
+ return
+
+/// Element for dis/allowing gun mode target movement.
+/obj/screen/gun_flag/move
+ name = "Allow Movement"
+ icon_state = "no_walk1"
+ screen_loc = ui_gun2
+ option_name = "Movement"
+ option_state = "no_walk"
+ option_flag = TARGET_CAN_MOVE
+
+/decl/hud_element/gun_flag_move
+ screen_object_type = /obj/screen/gun_flag/move
+ hud_element_category = /decl/hud_element/gun_flag_move
+
+/decl/hud_element/gun_flag_move/register_screen_object(obj/screen/elem, datum/hud/hud)
+ return
+
+/// Element for dis/allowing gun mode target radio use.
+/decl/hud_element/gun_flag_radio
+ screen_object_type = /obj/screen/gun_flag/radio
+ hud_element_category = /decl/hud_element/gun_flag_radio
+
+/decl/hud_element/gun_flag_radio/register_screen_object(obj/screen/elem, datum/hud/hud)
+ return
+
+/obj/screen/gun_flag/radio
+ name = "Disallow Radio Use"
+ icon_state = "no_radio1"
+ screen_loc = ui_gun4
+ option_name = "Radio Use"
+ option_state = "no_radio"
+ option_flag = TARGET_CAN_RADIO
diff --git a/code/_onclick/hud/hud_elements/health.dm b/code/_onclick/hud/hud_elements/health.dm
new file mode 100644
index 00000000000..2d84c53ccd1
--- /dev/null
+++ b/code/_onclick/hud/hud_elements/health.dm
@@ -0,0 +1,81 @@
+/decl/hud_element/health
+ screen_name = "health"
+ screen_icon = 'icons/mob/screen/health_human.dmi'
+ screen_icon_state = "health0"
+ apply_hud_icon = FALSE
+ apply_hud_alpha = FALSE
+ apply_hud_color = FALSE
+ var/health_states = 6
+ var/death_state = 7
+ var/numb_state = "_numb"
+
+/decl/hud_element/health/refresh_screen_object(datum/hud/hud, obj/screen/elem, datum/gas_mixture/environment)
+ if(!isliving(hud?.mymob))
+ return
+ var/mob/living/user = hud.mymob
+ reset_health_overlays(user, elem)
+ if(user.stat == DEAD)
+ elem.icon_state = "health[death_state]"
+ else if(user.has_chemical_effect(CE_PAINKILLER, 100))
+ elem.icon_state = "health[numb_state]"
+ else
+ update_health_overlays(user, elem)
+
+/decl/hud_element/health/proc/reset_health_overlays(mob/living/user, obj/screen/elem)
+ return
+
+/decl/hud_element/health/proc/update_health_overlays(mob/living/user, obj/screen/elem)
+ elem.icon_state = "health[health_states - round(user.get_health_ratio() * health_states)]"
+
+/decl/hud_element/health/human
+ screen_icon_state = "blank"
+ var/health_icon = 'icons/mob/screen/health_human.dmi'
+ var/burning_image
+ var/softcrit_image
+ var/hardcrit_image
+ var/fullhealth_image
+
+/decl/hud_element/health/human/Initialize()
+ . = ..()
+ burning_image = image(health_icon, "burning")
+ softcrit_image = image(health_icon, "softcrit")
+ hardcrit_image = image(health_icon, "hardcrit")
+ fullhealth_image = image(health_icon, "fullhealth")
+
+/decl/hud_element/health/human/reset_health_overlays(mob/living/user, obj/screen/elem)
+ elem.cut_overlays()
+ elem.icon_state = "blank"
+
+/decl/hud_element/health/human/update_health_overlays(mob/living/user, obj/screen/elem)
+
+ // Generate a by-limb health display.
+ // Pain modifies the effective pain level used to colour the limb.
+ var/no_damage = 1
+ var/trauma_val = 0 // Used in calculating softcrit/hardcrit indicators.
+ if(user.can_feel_pain() && ishuman(user))
+ var/mob/living/carbon/human/human = user
+ trauma_val = max(human.shock_stage, human.get_shock()) / (user.get_max_health()-100) // TODO: where is this 100 coming from?
+
+ for(var/obj/item/organ/external/E in user.get_external_organs())
+ if(no_damage && (E.brute_dam || E.burn_dam))
+ no_damage = 0
+ var/organ_image = E.get_damage_hud_image()
+ if(organ_image)
+ elem.add_overlay(organ_image)
+
+ // Apply a fire overlay if we're burning.
+ if(user.on_fire)
+ elem.add_overlay(burning_image)
+
+ // Show a general pain/crit indicator if needed.
+ if(user.is_asystole())
+ elem.add_overlay(hardcrit_image)
+ else if(trauma_val)
+ if(user.can_feel_pain())
+ if(trauma_val > 0.7)
+ elem.add_overlay(softcrit_image)
+ if(trauma_val >= 1)
+ elem.add_overlay(hardcrit_image)
+ else if(no_damage)
+ elem.add_overlay(fullhealth_image)
+ elem.compile_overlays()
diff --git a/code/_onclick/hud/hud_elements/hydration.dm b/code/_onclick/hud/hud_elements/hydration.dm
new file mode 100644
index 00000000000..cd6569f94cd
--- /dev/null
+++ b/code/_onclick/hud/hud_elements/hydration.dm
@@ -0,0 +1,21 @@
+/decl/hud_element/condition/hydration
+ screen_name = "hydration"
+ screen_object_type = /obj/screen/drink
+ screen_icon_state = "hydration1"
+ screen_loc = ui_nutrition_small
+ hud_element_category = /decl/hud_element/condition/hydration
+ var/hud_states = 4
+
+/decl/hud_element/condition/hydration/refresh_screen_object(datum/hud/hud, obj/screen/elem, datum/gas_mixture/environment)
+ if(!isliving(hud?.mymob))
+ return
+ var/mob/living/user = hud.mymob
+ var/max_hyd = user.get_max_hydration()
+ var/hyd = user.get_hydration()
+ var/hyd_offset = max_hyd * 0.2
+ if(hyd >= max_hyd - hyd_offset)
+ elem.icon_state = "hydration[hud_states]"
+ else if(hyd <= hyd_offset * 2)
+ elem.icon_state = "hydration"
+ else
+ elem.icon_state = "hydration[round(((hyd-(hyd_offset*2))/(max_hyd-hyd_offset))*(hud_states-2))+1]"
diff --git a/code/_onclick/hud/hud_elements/internals.dm b/code/_onclick/hud/hud_elements/internals.dm
new file mode 100644
index 00000000000..16eb2360536
--- /dev/null
+++ b/code/_onclick/hud/hud_elements/internals.dm
@@ -0,0 +1,8 @@
+/decl/hud_element/internals
+ screen_name = "internal"
+ screen_icon = 'icons/mob/screen/internals.dmi'
+ screen_icon_state = "internal0"
+ screen_loc = ui_internal
+ apply_hud_icon = FALSE
+ apply_hud_alpha = FALSE
+ apply_hud_color = FALSE
diff --git a/code/_onclick/hud/hud_elements/move_intent.dm b/code/_onclick/hud/hud_elements/move_intent.dm
new file mode 100644
index 00000000000..df79aeb7a99
--- /dev/null
+++ b/code/_onclick/hud/hud_elements/move_intent.dm
@@ -0,0 +1,9 @@
+/decl/hud_element/move_intent
+ screen_name = "movement method"
+ screen_object_type = /obj/screen/movement
+ screen_loc = ui_movi
+ hud_element_category = /decl/hud_element/move_intent
+
+/decl/hud_element/move_intent/create_screen_object(var/datum/hud/hud)
+ var/obj/screen/elem = ..()
+ elem.icon_state = hud.mymob.move_intent.hud_icon_state
diff --git a/code/_onclick/hud/hud_elements/nutrition.dm b/code/_onclick/hud/hud_elements/nutrition.dm
new file mode 100644
index 00000000000..46cfc164820
--- /dev/null
+++ b/code/_onclick/hud/hud_elements/nutrition.dm
@@ -0,0 +1,26 @@
+/decl/hud_element/condition/nutrition
+ screen_name = "nutrition"
+ screen_object_type = /obj/screen/food
+ screen_icon_state = "nutrition1"
+ screen_loc = ui_nutrition_small
+ hud_element_category = /decl/hud_element/condition/nutrition
+ var/hud_states = 4
+
+/decl/hud_element/condition/nutrition/create_screen_object(datum/hud/hud)
+ var/obj/screen/elem = ..()
+ elem.pixel_w = 8
+ return elem
+
+/decl/hud_element/condition/nutrition/refresh_screen_object(datum/hud/hud, obj/screen/elem, datum/gas_mixture/environment)
+ if(!isliving(hud?.mymob))
+ return
+ var/mob/living/user = hud.mymob
+ var/max_nut = user.get_max_nutrition()
+ var/nut = user.get_nutrition()
+ var/nut_offset = max_nut * 0.2
+ if(nut >= max_nut - nut_offset)
+ elem.icon_state = "nutrition[hud_states]"
+ else if(nut <= nut_offset * 2)
+ elem.icon_state = "nutrition0"
+ else
+ elem.icon_state = "nutrition[round(((nut-(nut_offset*2))/(max_nut-nut_offset))*(hud_states-2))+1]"
diff --git a/code/_onclick/hud/hud_elements/oxygen.dm b/code/_onclick/hud/hud_elements/oxygen.dm
new file mode 100644
index 00000000000..26603a2aabf
--- /dev/null
+++ b/code/_onclick/hud/hud_elements/oxygen.dm
@@ -0,0 +1,9 @@
+/decl/hud_element/condition/oxygen
+ screen_name = "oxygen"
+ screen_object_type = /obj/screen/oxygen
+ screen_loc = ui_temp
+ screen_icon_state = "oxy0"
+ hud_element_category = /decl/hud_element/condition/oxygen
+
+/decl/hud_element/condition/oxygen/refresh_screen_object(datum/hud/hud, obj/screen/elem, datum/gas_mixture/environment)
+ elem.icon_state = "oxy[hud?.alerts ? (LAZYACCESS(hud.alerts, hud_element_category) || 0) : 0]"
diff --git a/code/_onclick/hud/hud_elements/pain.dm b/code/_onclick/hud/hud_elements/pain.dm
new file mode 100644
index 00000000000..917fe3c8665
--- /dev/null
+++ b/code/_onclick/hud/hud_elements/pain.dm
@@ -0,0 +1,2 @@
+/decl/hud_element/pain
+ screen_object_type = /obj/screen/fullscreen/pain
diff --git a/code/_onclick/hud/hud_elements/pressure.dm b/code/_onclick/hud/hud_elements/pressure.dm
new file mode 100644
index 00000000000..0c6250cd567
--- /dev/null
+++ b/code/_onclick/hud/hud_elements/pressure.dm
@@ -0,0 +1,9 @@
+/decl/hud_element/condition/pressure
+ screen_name = "pressure"
+ screen_object_type = /obj/screen/pressure
+ screen_icon_state = "pressure0"
+ screen_loc = ui_temp
+ hud_element_category = /decl/hud_element/condition/pressure
+
+/decl/hud_element/condition/pressure/refresh_screen_object(datum/hud/hud, obj/screen/elem, datum/gas_mixture/environment)
+ elem.icon_state = "pressure[hud?.alerts ? (LAZYACCESS(hud.alerts, hud_element_category) || 0) : 0]"
diff --git a/code/_onclick/hud/hud_elements/resist.dm b/code/_onclick/hud/hud_elements/resist.dm
new file mode 100644
index 00000000000..35c2e12cc1a
--- /dev/null
+++ b/code/_onclick/hud/hud_elements/resist.dm
@@ -0,0 +1,7 @@
+/decl/hud_element/resist
+ screen_name = "resist"
+ screen_icon_state = "act_resist"
+ screen_loc = ui_pull_resist
+
+/decl/hud_element/resist/register_screen_object(obj/screen/elem, datum/hud/hud)
+ hud.hotkey_hud_elements |= elem
diff --git a/code/_onclick/hud/hud_elements/stamina.dm b/code/_onclick/hud/hud_elements/stamina.dm
new file mode 100644
index 00000000000..e2fd7b442ac
--- /dev/null
+++ b/code/_onclick/hud/hud_elements/stamina.dm
@@ -0,0 +1,12 @@
+/decl/hud_element/stamina_bar
+ screen_object_type = /obj/screen/stamina
+ apply_hud_alpha = FALSE
+ apply_hud_color = FALSE
+ apply_hud_icon = FALSE
+
+/obj/screen/stamina
+ name = "stamina"
+ icon = 'icons/effects/progressbar.dmi'
+ icon_state = "prog_bar_100"
+ invisibility = INVISIBILITY_MAXIMUM
+ screen_loc = ui_stamina
\ No newline at end of file
diff --git a/code/_onclick/hud/hud_elements/throwing.dm b/code/_onclick/hud/hud_elements/throwing.dm
new file mode 100644
index 00000000000..158dda5b0fe
--- /dev/null
+++ b/code/_onclick/hud/hud_elements/throwing.dm
@@ -0,0 +1,7 @@
+/decl/hud_element/throwing
+ screen_name = "throw"
+ screen_icon_state = "act_throw_off"
+ screen_loc = ui_drop_throw
+
+/decl/hud_element/throwing/register_screen_object(obj/screen/elem, datum/hud/hud)
+ hud.hotkey_hud_elements |= elem
diff --git a/code/_onclick/hud/hud_elements/toxins.dm b/code/_onclick/hud/hud_elements/toxins.dm
new file mode 100644
index 00000000000..5f42892c4b3
--- /dev/null
+++ b/code/_onclick/hud/hud_elements/toxins.dm
@@ -0,0 +1,9 @@
+/decl/hud_element/condition/toxins
+ screen_name = "toxin"
+ screen_object_type = /obj/screen/toxins
+ screen_icon_state = "tox0"
+ screen_loc = ui_temp
+ hud_element_category = /decl/hud_element/condition/toxins
+
+/decl/hud_element/condition/toxins/refresh_screen_object(datum/hud/hud, obj/screen/elem, datum/gas_mixture/environment)
+ elem.icon_state = "tox[hud?.alerts ? (LAZYACCESS(hud.alerts, hud_element_category) || 0) : 0]"
diff --git a/code/_onclick/hud/hud_elements/up_hint.dm b/code/_onclick/hud/hud_elements/up_hint.dm
new file mode 100644
index 00000000000..e845411cb1a
--- /dev/null
+++ b/code/_onclick/hud/hud_elements/up_hint.dm
@@ -0,0 +1,5 @@
+/decl/hud_element/up_hint
+ screen_name = "up hint"
+ screen_icon_state = "uphint0"
+ screen_loc = ui_up_hint
+
diff --git a/code/_onclick/hud/hud_elements/zone_selector.dm b/code/_onclick/hud/hud_elements/zone_selector.dm
new file mode 100644
index 00000000000..4776e0b8355
--- /dev/null
+++ b/code/_onclick/hud/hud_elements/zone_selector.dm
@@ -0,0 +1,3 @@
+/decl/hud_element/zone_selector
+ screen_object_type = /obj/screen/zone_selector
+ hud_element_category = /decl/hud_element/zone_selector
diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm
index f90bd824fde..54f91ae1012 100644
--- a/code/_onclick/hud/human.dm
+++ b/code/_onclick/hud/human.dm
@@ -1,202 +1,51 @@
/mob/living/carbon/human
- hud_type = /datum/hud/human
-
-/datum/hud/human/FinalizeInstantiation()
-
- var/ui_style = get_ui_style()
- var/ui_color = get_ui_color()
- var/ui_alpha = get_ui_alpha()
-
- var/mob/living/carbon/human/target = mymob
- var/datum/hud_data/hud_data = istype(target) ? target.species.hud : new()
- if(hud_data.icon)
- ui_style = hud_data.icon
-
- hotkeybuttons = list() //These can be disabled for hotkey usersx
-
- var/obj/screen/using
-
- stamina_bar = new
- adding += stamina_bar
-
- // Draw the attack intent dialogue.
- if(hud_data.has_a_intent)
- using = new /obj/screen/intent()
- src.adding += using
- action_intent = using
- hud_elements |= using
-
- if(hud_data.has_m_intent)
- using = new /obj/screen/movement()
- using.SetName("movement method")
- using.icon = ui_style
- using.icon_state = mymob.move_intent.hud_icon_state
- using.screen_loc = ui_movi
- using.color = ui_color
- using.alpha = ui_alpha
- src.adding += using
- move_intent = using
-
- if(hud_data.has_drop)
- using = new /obj/screen()
- using.SetName("drop")
- using.icon = ui_style
- using.icon_state = "act_drop"
- using.screen_loc = ui_drop_throw
- using.color = ui_color
- using.alpha = ui_alpha
- src.hotkeybuttons += using
-
- if(hud_data.has_hands)
- BuildHandsUI()
-
- if(hud_data.has_resist)
- using = new /obj/screen()
- using.SetName("resist")
- using.icon = ui_style
- using.icon_state = "act_resist"
- using.screen_loc = ui_pull_resist
- using.color = ui_color
- using.alpha = ui_alpha
- src.hotkeybuttons += using
-
- if(hud_data.has_throw)
- mymob.throw_icon = new /obj/screen()
- mymob.throw_icon.icon = ui_style
- mymob.throw_icon.icon_state = "act_throw_off"
- mymob.throw_icon.SetName("throw")
- mymob.throw_icon.screen_loc = ui_drop_throw
- mymob.throw_icon.color = ui_color
- mymob.throw_icon.alpha = ui_alpha
- src.hotkeybuttons += mymob.throw_icon
- hud_elements |= mymob.throw_icon
-
- if(hud_data.has_internals)
- mymob.internals = new /obj/screen()
- mymob.internals.icon = ui_style
- mymob.internals.icon_state = "internal0"
- mymob.internals.SetName("internal")
- mymob.internals.screen_loc = ui_internal
- hud_elements |= mymob.internals
-
- if(hud_data.has_warnings)
- mymob.healths = new /obj/screen()
- mymob.healths.icon = ui_style
- mymob.healths.icon_state = "health0"
- mymob.healths.SetName("health")
- mymob.healths.screen_loc = ui_health
- hud_elements |= mymob.healths
-
- mymob.oxygen = new /obj/screen/oxygen()
- mymob.oxygen.icon = 'icons/mob/status_indicators.dmi'
- mymob.oxygen.icon_state = "oxy0"
- mymob.oxygen.SetName("oxygen")
- mymob.oxygen.screen_loc = ui_temp
- hud_elements |= mymob.oxygen
-
- mymob.toxin = new /obj/screen/toxins()
- mymob.toxin.icon = 'icons/mob/status_indicators.dmi'
- mymob.toxin.icon_state = "tox0"
- mymob.toxin.SetName("toxin")
- mymob.toxin.screen_loc = ui_temp
- hud_elements |= mymob.toxin
-
- mymob.fire = new /obj/screen()
- mymob.fire.icon = ui_style
- mymob.fire.icon_state = "fire0"
- mymob.fire.SetName("fire")
- mymob.fire.screen_loc = ui_fire
- hud_elements |= mymob.fire
-
- if(hud_data.has_pressure)
- mymob.pressure = new /obj/screen/pressure()
- mymob.pressure.icon = 'icons/mob/status_indicators.dmi'
- mymob.pressure.icon_state = "pressure0"
- mymob.pressure.SetName("pressure")
- mymob.pressure.screen_loc = ui_temp
- hud_elements |= mymob.pressure
-
- if(hud_data.has_bodytemp)
- mymob.bodytemp = new /obj/screen/bodytemp()
- mymob.bodytemp.icon = 'icons/mob/status_indicators.dmi'
- mymob.bodytemp.icon_state = "temp1"
- mymob.bodytemp.SetName("body temperature")
- mymob.bodytemp.screen_loc = ui_temp
- hud_elements |= mymob.bodytemp
-
- if(target.isSynthetic())
- target.cells = new /obj/screen()
- target.cells.icon = 'icons/mob/screen1_robot.dmi'
- target.cells.icon_state = "charge-empty"
- target.cells.SetName("cell")
- target.cells.screen_loc = ui_nutrition
- hud_elements |= target.cells
-
- else if(hud_data.has_nutrition)
- mymob.nutrition_icon = new /obj/screen/food()
- mymob.nutrition_icon.icon = 'icons/mob/status_hunger.dmi'
- mymob.nutrition_icon.pixel_w = 8
- mymob.nutrition_icon.icon_state = "nutrition1"
- mymob.nutrition_icon.SetName("nutrition")
- mymob.nutrition_icon.screen_loc = ui_nutrition_small
- hud_elements |= mymob.nutrition_icon
-
- mymob.hydration_icon = new /obj/screen/drink()
- mymob.hydration_icon.icon = 'icons/mob/status_hunger.dmi'
- mymob.hydration_icon.icon_state = "hydration1"
- mymob.hydration_icon.SetName("hydration")
- mymob.hydration_icon.screen_loc = ui_nutrition_small
- hud_elements |= mymob.hydration_icon
-
- if(hud_data.has_up_hint)
- mymob.up_hint = new /obj/screen()
- mymob.up_hint.icon = ui_style
- mymob.up_hint.icon_state = "uphint0"
- mymob.up_hint.SetName("up hint")
- mymob.up_hint.screen_loc = ui_up_hint
- hud_elements |= mymob.up_hint
-
- mymob.pain = new /obj/screen/fullscreen/pain( null )
- hud_elements |= mymob.pain
-
- mymob.zone_sel = new
- mymob.zone_sel.icon = ui_style
- mymob.zone_sel.color = ui_color
- mymob.zone_sel.alpha = ui_alpha
- mymob.zone_sel.update_icon()
- hud_elements |= mymob.zone_sel
-
- target.attack_selector = new
- target.attack_selector.set_owner(target)
- target.attack_selector.icon = ui_style
- target.attack_selector.color = ui_color
- target.attack_selector.alpha = ui_alpha
- target.attack_selector.update_icon()
- hud_elements |= target.attack_selector
-
- //Handle the gun settings buttons
- mymob.gun_setting_icon = new /obj/screen/gun/mode(null)
- mymob.gun_setting_icon.icon = ui_style
- mymob.gun_setting_icon.color = ui_color
- mymob.gun_setting_icon.alpha = ui_alpha
- hud_elements |= mymob.gun_setting_icon
-
- mymob.item_use_icon = new /obj/screen/gun/item(null)
- mymob.item_use_icon.icon = ui_style
- mymob.item_use_icon.color = ui_color
- mymob.item_use_icon.alpha = ui_alpha
-
- mymob.gun_move_icon = new /obj/screen/gun/move(null)
- mymob.gun_move_icon.icon = ui_style
- mymob.gun_move_icon.color = ui_color
- mymob.gun_move_icon.alpha = ui_alpha
-
- mymob.radio_use_icon = new /obj/screen/gun/radio(null)
- mymob.radio_use_icon.icon = ui_style
- mymob.radio_use_icon.color = ui_color
- mymob.radio_use_icon.alpha = ui_alpha
-
- ..()
+ hud_used = /datum/hud/human
+
+/decl/hud_element/attack_selector
+ screen_object_type = /obj/screen/default_attack_selector
+ hud_element_category = /decl/hud_element/attack_selector
+
+/decl/hud_element/attack_selector/register_screen_object(var/obj/screen/elem, var/datum/hud/hud)
+ var/obj/screen/default_attack_selector/attack_selector = elem
+ if(istype(attack_selector) && ishuman(hud.mymob))
+ attack_selector.set_owner(hud.mymob)
+ attack_selector.update_icon()
+ return ..()
+
+/datum/hud/human
+ health_hud_type = /decl/hud_element/health/human
+ hud_elements = list(
+ /decl/hud_element/health/human,
+ /decl/hud_element/condition/bodytemp,
+ /decl/hud_element/attack_selector,
+ /decl/hud_element/zone_selector,
+ /decl/hud_element/move_intent,
+ /decl/hud_element/action_intent,
+ /decl/hud_element/condition/pressure,
+ /decl/hud_element/condition/fire,
+ /decl/hud_element/condition/toxins,
+ /decl/hud_element/condition/oxygen,
+ /decl/hud_element/condition/nutrition,
+ /decl/hud_element/condition/hydration,
+ /decl/hud_element/stamina_bar,
+ /decl/hud_element/drop,
+ /decl/hud_element/resist,
+ /decl/hud_element/throwing,
+ /decl/hud_element/up_hint,
+ /decl/hud_element/pain,
+ /decl/hud_element/internals,
+ /decl/hud_element/gun_mode,
+ /decl/hud_element/gun_flag_item,
+ /decl/hud_element/gun_flag_move,
+ /decl/hud_element/gun_flag_radio
+ )
+
+/datum/hud/human/get_ui_style()
+ var/decl/species/my_species = mymob?.get_species()
+ var/datum/hud_data/hud_data = my_species?.hud || new
+ if(hud_data?.icon)
+ return hud_data.icon
+ return ..()
/mob/living/carbon/human/verb/toggle_hotkey_verbs()
set category = "OOC"
@@ -204,17 +53,16 @@
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.hotkey_hud_elements
hud_used.hotkey_ui_hidden = 0
else
- client.screen -= hud_used.hotkeybuttons
+ client.screen -= hud_used.hotkey_hud_elements
hud_used.hotkey_ui_hidden = 1
// Yes, these use icon state. Yes, these are terrible. The alternative is duplicating
// a bunch of fairly blobby logic for every click override on these objects.
-
/obj/screen/food/Click(var/location, var/control, var/params)
- if(istype(usr) && usr.nutrition_icon == src)
+ if(usr.get_hud_element(/decl/hud_element/condition/nutrition) == src)
switch(icon_state)
if("nutrition0")
to_chat(usr, SPAN_WARNING("You are completely stuffed."))
@@ -228,7 +76,7 @@
to_chat(usr, SPAN_DANGER("You are starving!"))
/obj/screen/drink/Click(var/location, var/control, var/params)
- if(istype(usr) && usr.hydration_icon == src)
+ if(usr.get_hud_element(/decl/hud_element/condition/hydration) == src)
switch(icon_state)
if("hydration0")
to_chat(usr, SPAN_WARNING("You are overhydrated."))
@@ -242,7 +90,7 @@
to_chat(usr, SPAN_DANGER("You are dying of thirst!"))
/obj/screen/bodytemp/Click(var/location, var/control, var/params)
- if(istype(usr) && usr.bodytemp == src)
+ if(usr.get_hud_element(/decl/hud_element/condition/bodytemp) == src)
switch(icon_state)
if("temp4")
to_chat(usr, SPAN_DANGER("You are being cooked alive!"))
@@ -264,7 +112,7 @@
to_chat(usr, SPAN_NOTICE("Your body is at a comfortable temperature."))
/obj/screen/pressure/Click(var/location, var/control, var/params)
- if(istype(usr) && usr.pressure == src)
+ if(usr.get_hud_element(/decl/hud_element/condition/pressure) == src)
switch(icon_state)
if("pressure2")
to_chat(usr, SPAN_DANGER("The air pressure here is crushing!"))
@@ -278,14 +126,14 @@
to_chat(usr, SPAN_NOTICE("The local air pressure is comfortable."))
/obj/screen/toxins/Click(var/location, var/control, var/params)
- if(istype(usr) && usr.toxin == src)
+ if(usr.get_hud_element(/decl/hud_element/condition/toxins) == src)
if(icon_state == "tox0")
to_chat(usr, SPAN_NOTICE("The air is clear of toxins."))
else
to_chat(usr, SPAN_DANGER("The air is eating away at your skin!"))
/obj/screen/oxygen/Click(var/location, var/control, var/params)
- if(istype(usr) && usr.oxygen == src)
+ if(usr.get_hud_element(/decl/hud_element/condition/oxygen) == src)
if(icon_state == "oxy0")
to_chat(usr, SPAN_NOTICE("You are breathing easy."))
else
diff --git a/code/_onclick/hud/other_mobs.dm b/code/_onclick/hud/other_mobs.dm
deleted file mode 100644
index d7eb03aac29..00000000000
--- a/code/_onclick/hud/other_mobs.dm
+++ /dev/null
@@ -1,42 +0,0 @@
-/mob/living/simple_animal/construct
- hud_type = /datum/hud/construct
-
-/mob/living/simple_animal/construct
- var/hud_construct_type
-
-/mob/living/simple_animal/construct/armoured
- hud_construct_type = "juggernaut"
-
-/mob/living/simple_animal/construct/behemoth
- hud_construct_type = "juggernaut"
-
-/mob/living/simple_animal/construct/builder
- hud_construct_type = "artificer"
-
-/mob/living/simple_animal/construct/wraith
- hud_construct_type = "wraith"
-
-/mob/living/simple_animal/construct/harvester
- hud_construct_type = "harvester"
-
-/datum/hud/construct/FinalizeInstantiation()
- var/constructtype
- if(isconstruct(mymob))
- var/mob/living/simple_animal/construct/construct = mymob
- constructtype = construct.hud_construct_type
- if(constructtype)
- mymob.fire = new /obj/screen()
- mymob.fire.icon = 'icons/mob/screen1_construct.dmi'
- mymob.fire.icon_state = "fire0"
- mymob.fire.SetName("fire")
- mymob.fire.screen_loc = ui_construct_fire
- mymob.healths = new /obj/screen()
- mymob.healths.icon = 'icons/mob/screen1_construct.dmi'
- mymob.healths.icon_state = "[constructtype]_health0"
- mymob.healths.SetName("health")
- mymob.healths.screen_loc = ui_construct_health
- mymob.zone_sel = new
- mymob.zone_sel.icon = 'icons/mob/screen1_construct.dmi'
- mymob.zone_sel.update_icon()
- adding += list(mymob.fire, mymob.healths, mymob.zone_sel)
- ..()
diff --git a/code/_onclick/hud/pai.dm b/code/_onclick/hud/pai.dm
index c2926b006ff..67058ed29c3 100644
--- a/code/_onclick/hud/pai.dm
+++ b/code/_onclick/hud/pai.dm
@@ -2,21 +2,20 @@
var/obj/screen/using
using = new /obj/screen/pai/software()
using.SetName("Software Interface")
- adding += using
+ misc_hud_elements += using
using = new /obj/screen/pai/subsystems()
using.SetName("Subsystems")
- adding += using
+ misc_hud_elements += using
using = new /obj/screen/pai/shell()
using.SetName("Toggle Chassis")
- adding += using
+ misc_hud_elements += using
using = new /obj/screen/pai/rest()
using.SetName("Rest")
- adding += using
+ misc_hud_elements += using
using = new /obj/screen/pai/light()
using.SetName("Toggle Light")
- adding += using
- ..()
- hide_inventory()
+ misc_hud_elements += using
+ return ..()
/obj/screen/pai
icon = 'icons/mob/screen/pai.dmi'
diff --git a/code/_onclick/hud/robot.dm b/code/_onclick/hud/robot.dm
index 3a9c97bd923..88af6a84af5 100644
--- a/code/_onclick/hud/robot.dm
+++ b/code/_onclick/hud/robot.dm
@@ -1,179 +1,155 @@
-var/global/obj/screen/robot_inventory
-
-/obj/screen/robot_drop_grab
- name = "drop grab"
- icon = 'icons/mob/screen1_robot.dmi'
- icon_state = "drop_grab"
+/mob/living/silicon/robot
+ var/obj/screen/hands
+ hud_used = /datum/hud/robot
+
+/decl/hud_element/condition/fire/robot
+ screen_icon = 'icons/mob/screen/robot_conditions.dmi'
+
+/decl/hud_element/condition/oxygen/robot
+ screen_icon = 'icons/mob/screen/robot_conditions.dmi'
+
+/decl/hud_element/condition/bodytemp/robot
+ screen_icon = 'icons/mob/screen/robot_conditions.dmi'
+
+/decl/hud_element/module
+ screen_name = "module"
+ screen_icon = 'icons/mob/screen/robot_modules.dmi'
+ screen_icon_state = "nomod"
+ screen_loc = ui_borg_module
+
+/decl/hud_element/radio
+ screen_name = "radio"
+ screen_icon_state = "radio"
+ screen_loc = ui_movi
+
+/decl/hud_element/radio/create_screen_object(datum/hud/hud)
+ var/obj/screen/elem = ..()
+ elem.set_dir(SOUTHWEST)
+ return elem
+
+/decl/hud_element/drop_grab
+ screen_name = "drop grab"
+ screen_object_type = /obj/screen/robot_drop_grab
+ screen_icon = 'icons/mob/screen/robot_drop_grab.dmi'
+ screen_icon_state = "drop_grab"
screen_loc = ui_borg_drop_grab
- invisibility = INVISIBILITY_MAXIMUM
- alpha = 0
+ update_in_life = TRUE
+
+/decl/hud_element/drop_grab/create_screen_object(datum/hud/hud)
+ var/obj/screen/elem = ..()
+ if(length(hud?.mymob?.get_active_grabs()))
+ elem.invisibility = 0
+ elem.alpha = 255
+ else
+ elem.invisibility = INVISIBILITY_MAXIMUM
+ elem.alpha = 0
+ return elem
+
+/decl/hud_element/drop_grab/refresh_screen_object(datum/hud/hud, obj/screen/elem, datum/gas_mixture/environment)
+ . = ..()
+ if(length(hud?.mymob?.get_active_grabs()))
+ elem.invisibility = 0
+ elem.alpha = 255
+ else
+ elem.invisibility = INVISIBILITY_MAXIMUM
+ elem.alpha = 0
/obj/screen/robot_drop_grab/Click(location, control, params)
. = ..()
- if(isrobot(usr) && !usr.incapacitated())
- var/mob/living/silicon/robot/R = usr
- R.drop_item()
- set_invisibility(INVISIBILITY_MAXIMUM)
- alpha = 0
+ if(!isrobot(usr) || usr.incapacitated())
+ return
-/mob/living/silicon/robot
- hud_type = /datum/hud/robot
+ var/mob/living/silicon/robot/R = usr
+ R.drop_item()
+ invisibility = INVISIBILITY_MAXIMUM
+ alpha = 0
+
+/decl/hud_element/health/robot
+ screen_icon = 'icons/mob/screen/health_robot.dmi'
+ screen_loc = ui_borg_health
+
+/decl/hud_element/module_panel
+ screen_name = "panel"
+ screen_icon_state = "panel"
+ screen_loc = ui_borg_panel
+
+/decl/hud_element/robot_inventory
+ screen_name = "inventory"
+ screen_icon_state = "inventory"
+ screen_loc = ui_borg_inventory
+
+/datum/hud/robot
+ health_hud_type = /decl/hud_element/health/robot
+ hud_elements = list(
+ /decl/hud_element/health/robot,
+ /decl/hud_element/drop_grab,
+ /decl/hud_element/radio,
+ /decl/hud_element/module,
+ /decl/hud_element/module_panel,
+ /decl/hud_element/robot_inventory,
+ /decl/hud_element/condition/fire/robot,
+ /decl/hud_element/condition/oxygen/robot,
+ /decl/hud_element/condition/bodytemp/robot
+ )
+
+/datum/hud/robot/get_ui_color()
+ return COLOR_WHITE
+
+/datum/hud/robot/get_ui_alpha()
+ return 255
+
+/datum/hud/robot/get_ui_style()
+ return 'icons/mob/screen/robot.dmi'
/datum/hud/robot/FinalizeInstantiation()
var/mob/living/silicon/robot/R = mymob
if(!istype(R))
..()
- return
+ return ..()
+ var/mob/living/silicon/robot/R = mymob
var/obj/screen/using
-
- //Radio
- using = new /obj/screen()
- using.SetName("radio")
- using.set_dir(SOUTHWEST)
- using.icon = 'icons/mob/screen1_robot.dmi'
- using.icon_state = "radio"
- using.screen_loc = ui_movi
- adding += using
+ var/ui_style = get_ui_style()
//Module select
-
using = new /obj/screen()
using.SetName("module1")
using.set_dir(SOUTHWEST)
- using.icon = 'icons/mob/screen1_robot.dmi'
+ using.icon = ui_style
using.icon_state = "inv1"
using.screen_loc = ui_inv1
- adding += using
+ misc_hud_elements += using
R.inv1 = using
using = new /obj/screen()
using.SetName("module2")
using.set_dir(SOUTHWEST)
- using.icon = 'icons/mob/screen1_robot.dmi'
+ using.icon = ui_style
using.icon_state = "inv2"
using.screen_loc = ui_inv2
- adding += using
+ misc_hud_elements += using
R.inv2 = using
using = new /obj/screen()
using.SetName("module3")
using.set_dir(SOUTHWEST)
- using.icon = 'icons/mob/screen1_robot.dmi'
+ using.icon = ui_style
using.icon_state = "inv3"
using.screen_loc = ui_inv3
- adding += using
+ misc_hud_elements += using
R.inv3 = using
-
//End of module select
- // Drop UI
- R.ui_drop_grab = new
- adding += R.ui_drop_grab
-
- //Intent
- using = new /obj/screen()
- using.SetName("act_intent")
- using.set_dir(SOUTHWEST)
- using.icon = 'icons/mob/screen1_robot.dmi'
- using.icon_state = R.a_intent
- using.screen_loc = ui_acti
- adding += using
- action_intent = using
-
- //Cell
- R.cells = new /obj/screen()
- R.cells.icon = 'icons/mob/screen1_robot.dmi'
- R.cells.icon_state = "charge-empty"
- R.cells.SetName("cell")
- R.cells.screen_loc = ui_toxin
-
- //Health
- R.healths = new /obj/screen()
- R.healths.icon = 'icons/mob/screen1_robot.dmi'
- R.healths.icon_state = "health0"
- R.healths.SetName("health")
- R.healths.screen_loc = ui_borg_health
-
- //Installed Module
- R.hands = new /obj/screen()
- R.hands.icon = 'icons/mob/screen1_robot.dmi'
- R.hands.icon_state = "nomod"
- R.hands.SetName("module")
- R.hands.screen_loc = ui_borg_module
-
- //Module Panel
- using = new /obj/screen()
- using.SetName("panel")
- using.icon = 'icons/mob/screen1_robot.dmi'
- using.icon_state = "panel"
- using.screen_loc = ui_borg_panel
- adding += using
-
- //Store
- R.throw_icon = new /obj/screen()
- R.throw_icon.icon = 'icons/mob/screen1_robot.dmi'
- R.throw_icon.icon_state = "store"
- R.throw_icon.SetName("store")
- R.throw_icon.screen_loc = ui_borg_store
-
- //Inventory
- robot_inventory = new /obj/screen()
- robot_inventory.SetName("inventory")
- robot_inventory.icon = 'icons/mob/screen1_robot.dmi'
- robot_inventory.icon_state = "inventory"
- robot_inventory.screen_loc = ui_borg_inventory
-
- //Temp
- R.bodytemp = new /obj/screen()
- R.bodytemp.icon = 'icons/mob/status_indicators.dmi'
- R.bodytemp.icon_state = "temp0"
- R.bodytemp.SetName("body temperature")
- R.bodytemp.screen_loc = ui_temp
-
-
- R.oxygen = new /obj/screen()
- R.oxygen.icon = 'icons/mob/screen1_robot.dmi'
- R.oxygen.icon_state = "oxy0"
- R.oxygen.SetName("oxygen")
- R.oxygen.screen_loc = ui_oxygen
-
- R.fire = new /obj/screen()
- R.fire.icon = 'icons/mob/screen1_robot.dmi'
- R.fire.icon_state = "fire0"
- R.fire.SetName("fire")
- R.fire.screen_loc = ui_fire
-
- R.up_hint = new /obj/screen()
- R.up_hint.icon = 'icons/mob/screen1_robot.dmi'
- R.up_hint.icon_state = "uphint0"
- R.up_hint.SetName("up hint")
- R.up_hint.screen_loc = ui_up_hint
-
- R.zone_sel = new
- R.zone_sel.icon = 'icons/mob/screen1_robot.dmi'
- R.zone_sel.update_icon()
-
- //Handle the gun settings buttons
- R.gun_setting_icon = new /obj/screen/gun/mode(null)
- R.item_use_icon = new /obj/screen/gun/item(null)
- R.gun_move_icon = new /obj/screen/gun/move(null)
- R.radio_use_icon = new /obj/screen/gun/radio(null)
-
- hud_elements = list(R.throw_icon, R.zone_sel, R.oxygen, R.fire, R.up_hint, R.hands, R.healths, R.cells, robot_inventory, R.gun_setting_icon)
- ..()
+ return ..()
/datum/hud/proc/toggle_show_robot_modules()
if(!isrobot(mymob))
return
-
var/mob/living/silicon/robot/r = mymob
-
r.shown_robot_modules = !r.shown_robot_modules
update_robot_modules_display()
-
/datum/hud/proc/update_robot_modules_display()
if(!isrobot(mymob) || !mymob.client)
return
@@ -183,8 +159,6 @@ var/global/obj/screen/robot_inventory
if(R.shown_robot_modules)
if(R.active_storage)
R.active_storage.close(R) //Closes the inventory ui.
- //Modules display is shown
- //R.client.screen += robot_inventory //"store" icon
if(!R.module)
to_chat(usr, "No module selected")
@@ -231,7 +205,6 @@ var/global/obj/screen/robot_inventory
else
//Modules display is hidden
- //R.client.screen -= robot_inventory //"store" icon
for(var/atom/A in R.module.equipment)
if( (A != R.module_state_1) && (A != R.module_state_2) && (A != R.module_state_3) )
//Module is not currently active
diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm
index 4662c1fdc8d..a5f2f6dea72 100644
--- a/code/_onclick/hud/screen_objects.dm
+++ b/code/_onclick/hud/screen_objects.dm
@@ -8,7 +8,7 @@
*/
/obj/screen
name = ""
- icon = 'icons/mob/screen1.dmi'
+ icon = 'icons/mob/screen/midnight.dmi'
plane = HUD_PLANE
layer = HUD_BASE_LAYER
appearance_flags = NO_CLIENT_COLOR
@@ -138,10 +138,7 @@
return TRUE
/obj/screen/default_attack_selector/Destroy()
- if(owner)
- if(owner.attack_selector == src)
- owner.attack_selector = null
- owner = null
+ owner = null
. = ..()
/obj/screen/default_attack_selector/proc/set_owner(var/mob/living/carbon/human/_owner)
@@ -203,6 +200,10 @@
screen_loc = ui_zonesel
var/selecting = BP_CHEST
+/obj/screen/zone_selector/Initialize(mapload)
+ . = ..()
+ update_icon()
+
/obj/screen/zone_selector/Click(location, control,params)
var/list/PL = params2list(params)
var/icon_x = text2num(PL["icon-x"])
@@ -278,42 +279,20 @@
/obj/screen/zone_selector/on_update_icon()
set_overlays(image('icons/mob/zone_sel.dmi', "[selecting]"))
-
-/obj/screen/intent
- name = "intent"
- icon = 'icons/mob/screen/white.dmi'
- icon_state = "intent_help"
- screen_loc = ui_acti
- var/intent = I_HELP
-
-/obj/screen/intent/Click(var/location, var/control, var/params)
- var/list/P = params2list(params)
- var/icon_x = text2num(P["icon-x"])
- var/icon_y = text2num(P["icon-y"])
- intent = I_DISARM
- if(icon_x <= world.icon_size/2)
- if(icon_y <= world.icon_size/2)
- intent = I_HURT
- else
- intent = I_HELP
- else if(icon_y <= world.icon_size/2)
- intent = I_GRAB
- update_icon()
- usr.a_intent = intent
-
-/obj/screen/intent/on_update_icon()
- icon_state = "intent_[intent]"
+ compile_overlays()
/obj/screen/Click(location, control, params)
- if(!usr) return 1
+ if(!usr?.client)
+ return 1
switch(name)
if("toggle")
if(usr.hud_used.inventory_shown)
- usr.client.screen -= usr.hud_used.other
+ usr.client.screen -= usr.hud_used.hidable_hud_elements
usr.hud_used.hide_inventory()
else
- usr.client.screen += usr.hud_used.other
+ if(length(usr.hud_used.hidable_hud_elements))
+ usr.client.screen |= usr.hud_used.hidable_hud_elements
usr.hud_used.show_inventory()
if("equip")
@@ -339,9 +318,6 @@
var/mob/living/M = usr
M.ui_toggle_internals()
- if("act_intent")
- usr.a_intent_change("right")
-
if("throw")
if(!usr.stat && isturf(usr.loc) && !usr.restrained())
usr.toggle_throw_mode()
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index 73d45a5f65b..13269ecbb7d 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -703,30 +703,18 @@
if(M.lying) return //No spamming this on people.
SET_STATUS_MAX(M, STAT_WEAK, 3)
- to_chat(M, "You topple as \the [src] moves under you!")
-
+ to_chat(M, SPAN_DANGER("You topple as \the [src] moves under you!"))
if(prob(25))
-
var/damage = rand(15,30)
- var/mob/living/carbon/human/H = M
- if(!istype(H))
- to_chat(H, "You land heavily!")
- M.adjustBruteLoss(damage)
- return
-
- var/obj/item/organ/external/affecting = pick(H.get_external_organs())
- if(affecting)
- to_chat(M, "You land heavily on your [affecting.name]!")
+ var/obj/item/organ/external/affecting = SAFEPICK(M.get_external_organs())
+ if(!affecting)
+ to_chat(M, SPAN_DANGER("You land heavily!"))
+ M.adjustBruteLoss(damage, do_update_health = TRUE)
+ else
+ to_chat(M, SPAN_DANGER("You land heavily on your [affecting.name]!"))
affecting.take_external_damage(damage, 0)
if(affecting.parent)
affecting.parent.add_autopsy_data("Misadventure", damage)
- else
- to_chat(H, "You land heavily!")
- H.adjustBruteLoss(damage)
-
- H.UpdateDamageIcon()
- H.updatehealth()
- return
/// Get the current color of this atom.
/atom/proc/get_color()
diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm
index 5a82cc55e3a..a33ee1e8b9d 100644
--- a/code/game/machinery/alarm.dm
+++ b/code/game/machinery/alarm.dm
@@ -146,7 +146,8 @@
return // spawned in nullspace, presumably as a prototype for construction purposes.
area_uid = alarm_area.uid
- // breathable air according to human/Life()
+ // breathable air according to default human species
+ // TODO: make it use map default species?
var/decl/material/gas_mat = GET_DECL(/decl/material/gas/oxygen)
TLV[gas_mat.gas_name] = list(16, 19, 135, 140) // Partial pressure, kpa
gas_mat = GET_DECL(/decl/material/gas/carbon_dioxide)
diff --git a/code/game/machinery/mech_recharger.dm b/code/game/machinery/mech_recharger.dm
index 1738984bce3..bd9e8be6936 100644
--- a/code/game/machinery/mech_recharger.dm
+++ b/code/game/machinery/mech_recharger.dm
@@ -68,14 +68,17 @@
var/remaining_energy = active_power_usage
if(repair && !fully_repaired())
+ var/repaired = FALSE
for(var/obj/item/mech_component/MC in charging)
if(MC)
MC.repair_brute_damage(repair)
MC.repair_burn_damage(repair)
remaining_energy -= repair * repair_power_usage
+ repaired = TRUE
if(remaining_energy <= 0)
break
- charging.updatehealth()
+ if(repaired)
+ charging.update_health() // TODO: do this during component repair.
if(fully_repaired())
charging.show_message(SPAN_NOTICE("Exosuit integrity has been fully restored."))
@@ -90,7 +93,7 @@
// An ugly proc, but apparently mechs don't have maxhealth var of any kind.
/obj/machinery/mech_recharger/proc/fully_repaired()
- return charging && (charging.health == charging.maxHealth)
+ return charging && (charging.current_health >= charging.get_max_health())
/obj/machinery/mech_recharger/proc/start_charging(var/mob/living/exosuit/M)
if(stat & (NOPOWER | BROKEN))
diff --git a/code/game/machinery/oxygen_pump.dm b/code/game/machinery/oxygen_pump.dm
index ccd515bcfe8..45f66bcab2b 100644
--- a/code/game/machinery/oxygen_pump.dm
+++ b/code/game/machinery/oxygen_pump.dm
@@ -89,8 +89,9 @@
visible_message(SPAN_NOTICE("\The [user] detaches \the [contained] and it rapidly retracts back into \the [src]!"))
else
visible_message(SPAN_NOTICE("\The [contained] rapidly retracts back into \the [src]!"))
- if(breather.internals)
- breather.internals.icon_state = "internal0"
+ var/obj/screen/internals = breather?.get_hud_element(/decl/hud_element/internals)
+ if(internals)
+ internals.icon_state = "internal0"
breather = null
update_use_power(POWER_USE_IDLE)
diff --git a/code/game/objects/effects/bump_teleporter.dm b/code/game/objects/effects/bump_teleporter.dm
index 715a720efe3..1da47e8147e 100644
--- a/code/game/objects/effects/bump_teleporter.dm
+++ b/code/game/objects/effects/bump_teleporter.dm
@@ -2,7 +2,7 @@ var/global/list/BUMP_TELEPORTERS = list()
/obj/effect/bump_teleporter
name = "bump-teleporter"
- icon = 'icons/mob/screen1.dmi'
+ icon = 'icons/mob/screen/crosses.dmi'
icon_state = "x2"
var/id = null //id of this bump_teleporter.
var/id_target = null //id of bump_teleporter which this moves you to.
diff --git a/code/game/objects/effects/decals/misc.dm b/code/game/objects/effects/decals/misc.dm
index 0af5221fd2d..e56b075206b 100644
--- a/code/game/objects/effects/decals/misc.dm
+++ b/code/game/objects/effects/decals/misc.dm
@@ -1,7 +1,7 @@
/obj/effect/decal/point
name = "arrow"
desc = "It's an arrow hanging in mid-air. There may be a wizard about."
- icon = 'icons/mob/screen1.dmi'
+ icon = 'icons/mob/screen/arrow.dmi'
icon_state = "arrow"
layer = POINTER_LAYER
anchored = TRUE
diff --git a/code/game/objects/effects/effect_system.dm b/code/game/objects/effects/effect_system.dm
index 960cb4c0827..d8620773efb 100644
--- a/code/game/objects/effects/effect_system.dm
+++ b/code/game/objects/effects/effect_system.dm
@@ -291,8 +291,6 @@ steam.start() -- spawns the effect
R.emote("gasp")
spawn (20)
R.coughedtime = 0
- R.updatehealth()
- return
/////////////////////////////////////////////
// Smoke spread
diff --git a/code/game/objects/effects/landmarks.dm b/code/game/objects/effects/landmarks.dm
index 542dd7c36d4..c8b639bc815 100644
--- a/code/game/objects/effects/landmarks.dm
+++ b/code/game/objects/effects/landmarks.dm
@@ -18,7 +18,7 @@
/obj/abstract/landmark/start
name = "start"
- icon = 'icons/mob/screen1.dmi'
+ icon = 'icons/mob/screen/crosses.dmi'
icon_state = "x"
anchored = TRUE
invisibility = INVISIBILITY_ABSTRACT
diff --git a/code/game/objects/effects/manifest.dm b/code/game/objects/effects/manifest.dm
index 4215dd086c5..dd5c7fc999f 100644
--- a/code/game/objects/effects/manifest.dm
+++ b/code/game/objects/effects/manifest.dm
@@ -1,6 +1,6 @@
/obj/effect/manifest
name = "manifest"
- icon = 'icons/mob/screen1.dmi'
+ icon = 'icons/mob/screen/crosses.dmi'
icon_state = "x"
/obj/effect/manifest/Initialize()
diff --git a/code/game/objects/effects/spawners/bombspawner.dm b/code/game/objects/effects/spawners/bombspawner.dm
index e3e71c4accf..84f31a33862 100644
--- a/code/game/objects/effects/spawners/bombspawner.dm
+++ b/code/game/objects/effects/spawners/bombspawner.dm
@@ -20,7 +20,7 @@
/obj/effect/spawner/newbomb
name = "TTV bomb"
- icon = 'icons/mob/screen1.dmi'
+ icon = 'icons/mob/screen/crosses.dmi'
icon_state = "x"
var/filler_type = /decl/material/gas/carbon_dioxide
@@ -102,7 +102,7 @@
/obj/effect/spawner/onetankbomb
name = "Single-tank bomb"
- icon = 'icons/mob/screen1.dmi'
+ icon = 'icons/mob/screen/crosses.dmi'
icon_state = "x"
/obj/effect/spawner/onetankbomb/Initialize()
diff --git a/code/game/objects/item.dm b/code/game/objects/item.dm
index 53c1208e531..49e09bf947d 100644
--- a/code/game/objects/item.dm
+++ b/code/game/objects/item.dm
@@ -647,7 +647,7 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out.
return
if(user.hud_used.hud_shown)
- user.toggle_zoom_hud() // If the user has already limited their HUD this avoids them having a HUD when they zoom in
+ user.minimize_hud(zoom = TRUE) // If the user has already limited their HUD this avoids them having a HUD when they zoom in
user.client.view = viewsize
zoom = 1
@@ -695,7 +695,7 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out.
user.client.view = world.view
if(!user.hud_used.hud_shown)
- user.toggle_zoom_hud()
+ user.minimize_hud(zoom = TRUE)
user.client.pixel_x = 0
user.client.pixel_y = 0
user.client.OnResize()
diff --git a/code/game/objects/items/devices/aicard.dm b/code/game/objects/items/devices/aicard.dm
index 7e14954938a..d66875cf4ac 100644
--- a/code/game/objects/items/devices/aicard.dm
+++ b/code/game/objects/items/devices/aicard.dm
@@ -22,7 +22,7 @@
data["has_ai"] = carded_ai != null
if(carded_ai)
data["name"] = carded_ai.name
- data["hardware_integrity"] = carded_ai.hardware_integrity()
+ data["hardware_integrity"] = carded_ai.get_health_percent()
data["backup_capacitor"] = carded_ai.backup_capacitor()
data["radio"] = !carded_ai.ai_radio.disabledAi
data["wireless"] = !carded_ai.control_disabled
@@ -57,8 +57,7 @@
flush = 1
to_chat(carded_ai, "Your core files are being wiped!")
while (carded_ai && carded_ai.stat != DEAD)
- carded_ai.adjustOxyLoss(2)
- carded_ai.updatehealth()
+ carded_ai.adjustOxyLoss(2, do_update_health = TRUE)
sleep(10)
flush = 0
if (href_list["radio"])
diff --git a/code/game/objects/items/robot/robot_items.dm b/code/game/objects/items/robot/robot_items.dm
index ee950f3b5c7..14483d7ac6c 100644
--- a/code/game/objects/items/robot/robot_items.dm
+++ b/code/game/objects/items/robot/robot_items.dm
@@ -17,7 +17,7 @@
icon = 'icons/obj/decals.dmi'
icon_state = "securearea"
var/sight_mode = null
- var/hud_type
+ var/borg_hud_type
/obj/item/borg/sight/xray
@@ -51,7 +51,7 @@
name = "medical hud"
icon_state = ICON_STATE_WORLD
icon = 'icons/clothing/eyes/hud_medical.dmi'
- hud_type = HUD_MEDICAL
+ borg_hud_type = HUD_MEDICAL
/obj/item/borg/sight/hud/med/Initialize()
. = ..()
@@ -61,7 +61,7 @@
name = "security hud"
icon_state = ICON_STATE_WORLD
icon = 'icons/clothing/eyes/hud_security.dmi'
- hud_type = HUD_SECURITY
+ borg_hud_type = HUD_SECURITY
/obj/item/borg/sight/hud/Initialize()
. = ..()
@@ -72,7 +72,7 @@
name = "janitor hud"
icon_state = ICON_STATE_WORLD
icon = 'icons/clothing/eyes/hud_janitor.dmi'
- hud_type = HUD_JANITOR
+ borg_hud_type = HUD_JANITOR
/obj/item/borg/sight/hud/jani/Initialize()
. = ..()
diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm
index de9e82f0a8a..035d0b22238 100644
--- a/code/game/objects/items/robot/robot_upgrades.dm
+++ b/code/game/objects/items/robot/robot_upgrades.dm
@@ -106,7 +106,7 @@
matter = list(/decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT)
/obj/item/borg/upgrade/restart/action(var/mob/living/silicon/robot/R)
- if(R.health < 0)
+ if(R.current_health < 0)
to_chat(usr, "You have to repair the robot before using this module!")
return 0
@@ -194,18 +194,18 @@
origin_tech = "{'materials':2,'engineering':3,'programming':3,'magnets':3}"
/obj/item/borg/upgrade/jetpack/action(var/mob/living/silicon/robot/R)
- if(..()) return 0
+ if(..())
+ return FALSE
if(!R.module || !(type in R.module.supported_upgrades))
to_chat(R, "Upgrade mounting error! No suitable hardpoint detected!")
to_chat(usr, "There's no mounting point for the module!")
- return 0
- else
- R.module.equipment += new/obj/item/tank/jetpack/carbondioxide
- for(var/obj/item/tank/jetpack/carbondioxide in R.module.equipment)
- R.internals = src
- //R.icon_state="Miner+j"
- return 1
+ return FALSE
+
+ var/jetpack = new /obj/item/tank/jetpack/carbondioxide(R.module)
+ R.module.equipment += jetpack
+ R.set_internals(jetpack)
+ return TRUE
/obj/item/borg/upgrade/rcd
name = "engineering robot RCD"
diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm
index ebc4aab7307..dba4e398b27 100644
--- a/code/game/objects/items/stacks/medical.dm
+++ b/code/game/objects/items/stacks/medical.dm
@@ -54,9 +54,7 @@
if(istype(suit))
to_chat(user, SPAN_WARNING("You can't apply [src] through [suit]!"))
return 1
-
- H.UpdateDamageIcon()
-
+ H.update_health() // TODO: readd the actual healing logic that goes here, or check that it's applied in afterattack or something
else
M.heal_organ_damage((src.heal_brute/2), (src.heal_burn/2))
@@ -66,7 +64,6 @@
)
use(1)
- M.updatehealth()
/obj/item/stack/medical/bruise_pack
name = "roll of gauze"
singular_name = "gauze length"
diff --git a/code/game/objects/items/stacks/nanopaste.dm b/code/game/objects/items/stacks/nanopaste.dm
index bf8fa4c6dbc..7a01f895507 100644
--- a/code/game/objects/items/stacks/nanopaste.dm
+++ b/code/game/objects/items/stacks/nanopaste.dm
@@ -18,8 +18,7 @@
if (R.getBruteLoss() || R.getFireLoss() )
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
R.adjustBruteLoss(-15)
- R.adjustFireLoss(-15)
- R.updatehealth()
+ R.adjustFireLoss(-15, do_update_health = TRUE)
use(1)
user.visible_message("\The [user] applied some [src] on [R]'s damaged areas.",\
"You apply some [src] at [R]'s damaged areas.")
@@ -44,7 +43,6 @@
else if(can_use(1))
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
S.heal_damage(15, 15, robo_repair = 1)
- H.updatehealth()
use(1)
user.visible_message("\The [user] applies some nanite paste on [user != M ? "[M]'s [S.name]" : "[S]"] with [src].",\
"You apply some nanite paste on [user == M ? "your" : "[M]'s"] [S.name].")
diff --git a/code/game/objects/items/weapons/defib.dm b/code/game/objects/items/weapons/defib.dm
index 19abe1cc01d..5c6e522873d 100644
--- a/code/game/objects/items/weapons/defib.dm
+++ b/code/game/objects/items/weapons/defib.dm
@@ -435,14 +435,13 @@
M.switch_from_dead_to_living_mob_list()
M.timeofdeath = 0
- M.set_stat(UNCONSCIOUS) //Life() can bring them back to consciousness if it needs to.
+ M.set_stat(UNCONSCIOUS)
M.try_refresh_visible_overlays()
M.failed_last_breath = 0 //So mobs that died of oxyloss don't revive and have perpetual out of breath.
M.reload_fullscreen()
M.emote("gasp")
SET_STATUS_MAX(M, STAT_WEAK, rand(10,25))
- M.updatehealth()
apply_brain_damage(M, deadtime)
/obj/item/shockpaddles/proc/apply_brain_damage(mob/living/carbon/human/H, var/deadtime)
diff --git a/code/game/objects/items/weapons/implants/implantchair.dm b/code/game/objects/items/weapons/implants/implantchair.dm
index 1b4890ac51c..85008df6d66 100644
--- a/code/game/objects/items/weapons/implants/implantchair.dm
+++ b/code/game/objects/items/weapons/implants/implantchair.dm
@@ -29,12 +29,12 @@
user.set_machine(src)
var/health_text = ""
if(src.occupant)
- if(src.occupant.health <= -100)
+ if(src.occupant.current_health <= -100)
health_text = "Dead"
- else if(src.occupant.health < 0)
- health_text = "[round(src.occupant.health,0.1)]"
+ else if(src.occupant.current_health < 0)
+ health_text = "[round(src.occupant.current_health,0.1)]"
else
- health_text = "[round(src.occupant.health,0.1)]"
+ health_text = "[round(src.occupant.current_health,0.1)]"
var/dat ="Implanter Status
"
diff --git a/code/game/objects/items/weapons/material/shards.dm b/code/game/objects/items/weapons/material/shards.dm
index ece9cec1069..79cb11faedb 100644
--- a/code/game/objects/items/weapons/material/shards.dm
+++ b/code/game/objects/items/weapons/material/shards.dm
@@ -120,7 +120,6 @@
continue
to_chat(M, SPAN_DANGER("You step on \the [src]!"))
affecting.take_external_damage(5, 0)
- M.updatehealth()
if(affecting.can_feel_pain())
SET_STATUS_MAX(M, STAT_WEAK, 3)
return
diff --git a/code/game/objects/structures/crates_lockers/closets/statue.dm b/code/game/objects/structures/crates_lockers/closets/statue.dm
index 548a0f3fc3f..d0c2447dd90 100644
--- a/code/game/objects/structures/crates_lockers/closets/statue.dm
+++ b/code/game/objects/structures/crates_lockers/closets/statue.dm
@@ -23,7 +23,7 @@
L.client.eye = src
L.forceMove(src)
L.set_sdisability(MUTED)
- health = L.health + 100 //stoning damaged mobs will result in easier to shatter statues
+ health = L.current_health + 100 //stoning damaged mobs will result in easier to shatter statues
intialTox = L.getToxLoss()
intialFire = L.getFireLoss()
intialBrute = L.getBruteLoss()
@@ -65,7 +65,7 @@
for(var/mob/living/M in src)
M.dropInto(loc)
M.unset_sdisability(MUTED)
- M.take_overall_damage((M.health - health - 100),0) //any new damage the statue incurred is transfered to the mob
+ M.take_overall_damage((M.current_health - health - 100),0) //any new damage the statue incurred is transfered to the mob
if(M.client)
M.client.eye = M.client.mob
M.client.perspective = MOB_PERSPECTIVE
diff --git a/code/modules/ZAS/Contaminants.dm b/code/modules/ZAS/Contaminants.dm
index 4d99a5c6c09..e428d1c5fb8 100644
--- a/code/modules/ZAS/Contaminants.dm
+++ b/code/modules/ZAS/Contaminants.dm
@@ -78,9 +78,9 @@ var/global/image/contamination_overlay = image('icons/effects/contamination.dmi'
//Burn skin if exposed.
if(vsc.contaminant_control.SKIN_BURNS)
if(!contaminant_head_protected() || !contaminant_suit_protected())
+ if(prob(20))
+ to_chat(src, "Your skin burns!")
take_overall_damage(0, 0.75)
- if(prob(20)) to_chat(src, "Your skin burns!")
- updatehealth()
//Burn eyes if exposed.
if(vsc.contaminant_control.EYE_BURNS)
diff --git a/code/modules/admin/admin_attack_log.dm b/code/modules/admin/admin_attack_log.dm
index 6367b996d3c..a55de2390de 100644
--- a/code/modules/admin/admin_attack_log.dm
+++ b/code/modules/admin/admin_attack_log.dm
@@ -51,8 +51,7 @@
var/target_zone = "(ZONE_SEL: N/A)"
if(attacker)
intent = "(INTENT: [uppertext(attacker.a_intent)])"
- if (attacker.get_target_zone())
- target_zone = "(ZONE_SEL: [uppertext(attacker.get_target_zone())])"
+ target_zone = "(ZONE_SEL: [uppertext(attacker.get_target_zone())])"
if(victim)
attacker.attack_logs_ += text("\[[time_stamp()]\] [key_name(victim)] - [attacker_message] [intent] [target_zone]")
else
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index 85aa0b7a70d..87f72445b7a 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -992,10 +992,10 @@
if(prob(80)) T.break_tile_to_plating()
else T.break_tile()
- if(M.health == 1)
+ if(M.current_health == 1)
M.gib()
else
- M.adjustBruteLoss( min( 99 , (M.health - 1) ) )
+ M.adjustBruteLoss( min( 99 , (M.current_health - 1) ) )
SET_STATUS_MAX(M, STAT_STUN, 20)
SET_STATUS_MAX(M, STAT_WEAK, 20)
M.set_status(STAT_STUTTER, 20)
diff --git a/code/modules/assembly/mousetrap.dm b/code/modules/assembly/mousetrap.dm
index af049899f8c..4eda3b4fc35 100644
--- a/code/modules/assembly/mousetrap.dm
+++ b/code/modules/assembly/mousetrap.dm
@@ -42,7 +42,7 @@
SET_STATUS_MAX(H, STAT_STUN, 3)
if(affecting)
affecting.take_external_damage(1, 0)
- H.updatehealth()
+
else if(ismouse(target))
var/mob/living/simple_animal/mouse/M = target
visible_message("SPLAT!")
diff --git a/code/modules/awaymissions/loot.dm b/code/modules/awaymissions/loot.dm
index d2ebad954c9..bc91c3c46ac 100644
--- a/code/modules/awaymissions/loot.dm
+++ b/code/modules/awaymissions/loot.dm
@@ -1,5 +1,5 @@
/obj/effect/spawner/lootdrop
- icon = 'icons/mob/screen1.dmi'
+ icon = 'icons/mob/screen/crosses.dmi'
icon_state = "x2"
var/lootcount = 1 //how many items will be spawned
var/lootdoubles = 0 //if the same item can be spawned twice
diff --git a/code/modules/blob/blob.dm b/code/modules/blob/blob.dm
index 1922422afa3..f5c8ded119e 100644
--- a/code/modules/blob/blob.dm
+++ b/code/modules/blob/blob.dm
@@ -12,7 +12,7 @@
layer = BLOB_SHIELD_LAYER
- var/maxHealth = 30
+ var/blob_max_health = 30
var/health
var/regen_rate = 5
var/brute_resist = 4.3
@@ -28,7 +28,7 @@
/obj/effect/blob/Initialize()
. = ..()
- health = maxHealth
+ health = blob_max_health
update_icon()
START_PROCESSING(SSblob, src)
@@ -36,6 +36,9 @@
STOP_PROCESSING(SSblob, src)
. = ..()
+/obj/effect/blob/proc/get_max_health()
+ return blob_max_health
+
/obj/effect/blob/CanPass(var/atom/movable/mover, var/turf/target, var/height = 0, var/air_group = 0)
if(air_group || height == 0)
return 1
@@ -46,7 +49,7 @@
take_damage(rand(140 - (severity * 40), 140 - (severity * 20)) / brute_resist)
/obj/effect/blob/on_update_icon()
- if(health > maxHealth / 2)
+ if(health > blob_max_health / 2)
icon_state = "blob"
else
icon_state = "blob_damaged"
@@ -66,7 +69,7 @@
update_icon()
/obj/effect/blob/proc/regen()
- health = min(health + regen_rate, maxHealth)
+ health = min(health + regen_rate, blob_max_health)
update_icon()
/obj/effect/blob/proc/expand(var/turf/T)
@@ -196,7 +199,7 @@
name = "master nucleus"
desc = "A massive, fragile nucleus guarded by a shield of thick tendrils."
icon_state = "blob_core"
- maxHealth = 450
+ blob_max_health = 450
damage_min = 30
damage_max = 40
expandType = /obj/effect/blob/shield
@@ -210,7 +213,7 @@
var/times_to_pulse = 0
/obj/effect/blob/core/proc/get_health_percent()
- return ((health / maxHealth) * 100)
+ return ((health / get_max_health()) * 100)
/*
the master core becomes more vulnereable to damage as it weakens,
@@ -282,7 +285,7 @@ regen() will cover update_icon() for this proc
name = "auxiliary nucleus"
desc = "An interwoven mass of tendrils. A glowing nucleus pulses at its center."
icon_state = "blob_node"
- maxHealth = 125
+ blob_max_health = 125
regen_rate = 1
damage_min = 15
damage_max = 20
@@ -294,13 +297,13 @@ regen() will cover update_icon() for this proc
return
/obj/effect/blob/core/secondary/on_update_icon()
- icon_state = (health / maxHealth >= 0.5) ? "blob_node" : "blob_factory"
+ icon_state = (health / get_max_health() >= 0.5) ? "blob_node" : "blob_factory"
/obj/effect/blob/shield
name = "shielding mass"
desc = "A pulsating mass of interwoven tendrils. These seem particularly robust, but not quite as active."
icon_state = "blob_idle"
- maxHealth = 120
+ blob_max_health = 120
damage_min = 13
damage_max = 25
attack_freq = 7
@@ -318,9 +321,10 @@ regen() will cover update_icon() for this proc
return ..()
/obj/effect/blob/shield/on_update_icon()
- if(health > maxHealth * 2 / 3)
+ var/max_health = get_max_health()
+ if(health > max_health * 2 / 3)
icon_state = "blob_idle"
- else if(health > maxHealth / 3)
+ else if(health > max_health / 3)
icon_state = "blob"
else
icon_state = "blob_damaged"
@@ -331,7 +335,7 @@ regen() will cover update_icon() for this proc
/obj/effect/blob/ravaging
name = "ravaging mass"
desc = "A mass of interwoven tendrils. They thrash around haphazardly at anything in reach."
- maxHealth = 20
+ blob_max_health = 20
damage_min = 27
damage_max = 36
attack_freq = 3
diff --git a/code/modules/client/ui_style.dm b/code/modules/client/ui_style.dm
index f20646370b6..6b0c4c5f47e 100644
--- a/code/modules/client/ui_style.dm
+++ b/code/modules/client/ui_style.dm
@@ -29,6 +29,9 @@ var/global/all_tooltip_styles = list(
set desc = "Configure your user interface"
set category = "OOC"
+ if(!mob.hud_used)
+ return
+
if(!ishuman(mob))
to_chat(src, SPAN_WARNING("You must be human to use this verb."))
return
@@ -47,18 +50,15 @@ var/global/all_tooltip_styles = list(
UI_style_alpha_new = clamp(UI_style_alpha_new, 50, 255)
- var/list/icons = mob.hud_used.adding + mob.hud_used.other + mob.hud_used.hotkeybuttons
-
- icons.Add(
- mob.zone_sel,
- mob.gun_setting_icon,
- mob.item_use_icon,
- mob.gun_move_icon,
- mob.radio_use_icon
- )
+ var/list/icons = list()
+ if(length(mob.hud_used.misc_hud_elements))
+ icons |= mob.hud_used.misc_hud_elements
+ if(length(mob.hud_used.hidable_hud_elements))
+ icons |= mob.hud_used.hidable_hud_elements
+ if(length(mob.hud_used.hotkey_hud_elements))
+ icons |= mob.hud_used.hotkey_hud_elements
var/icon/UI_style_icon_new = all_ui_styles[UI_style_new]
-
apply_ui_style(icons, UI_style_icon_new, UI_style_color_new, UI_style_alpha_new)
if(alert("Like it? Save changes?",,"Yes", "No") == "Yes")
diff --git a/code/modules/clothing/_clothing.dm b/code/modules/clothing/_clothing.dm
index 2cb413e41d0..06eca0e8542 100644
--- a/code/modules/clothing/_clothing.dm
+++ b/code/modules/clothing/_clothing.dm
@@ -59,7 +59,7 @@
// End placeholder.
// Updates the vision of the mob wearing the clothing item, if any
-/obj/item/clothing/proc/update_vision()
+/obj/item/clothing/proc/update_wearer_vision()
if(isliving(src.loc))
var/mob/living/L = src.loc
L.handle_vision()
@@ -147,7 +147,7 @@
/obj/item/clothing/equipped(var/mob/user)
if(needs_vision_update())
- update_vision()
+ update_wearer_vision()
return ..()
/obj/item/clothing/proc/refit_for_bodytype(var/target_bodytype)
diff --git a/code/modules/clothing/glasses/_glasses.dm b/code/modules/clothing/glasses/_glasses.dm
index 6cf4c26780b..c994979f26f 100644
--- a/code/modules/clothing/glasses/_glasses.dm
+++ b/code/modules/clothing/glasses/_glasses.dm
@@ -17,7 +17,7 @@
var/active = TRUE
var/electric = FALSE //if the glasses should be disrupted by EMP
- var/hud_type
+ var/glasses_hud_type
var/obj/screen/overlay
var/obj/item/clothing/glasses/hud/hud // Hud glasses, if any
var/activation_sound = 'sound/items/goggles_charge.ogg'
@@ -69,7 +69,7 @@
active = _active
update_icon()
update_clothing_icon()
- update_vision()
+ update_wearer_vision()
/obj/item/clothing/glasses/on_update_icon()
. = ..()
diff --git a/code/modules/clothing/glasses/eyepatch.dm b/code/modules/clothing/glasses/eyepatch.dm
index e660806e603..52c63948ada 100644
--- a/code/modules/clothing/glasses/eyepatch.dm
+++ b/code/modules/clothing/glasses/eyepatch.dm
@@ -90,7 +90,7 @@
/obj/item/clothing/glasses/eyepatch/hud/science
name = "SCIpatch"
desc = "A Science-type heads-up display that connects directly to the ocular nerve of the user, replacing the need for that useless eyeball."
- hud_type = HUD_SCIENCE
+ glasses_hud_type = HUD_SCIENCE
eye_color = COLOR_PINK
/obj/item/clothing/glasses/eyepatch/hud/meson/Initialize()
diff --git a/code/modules/clothing/glasses/glasses.dm b/code/modules/clothing/glasses/glasses.dm
index 2766c94ee05..35b023ef2b1 100644
--- a/code/modules/clothing/glasses/glasses.dm
+++ b/code/modules/clothing/glasses/glasses.dm
@@ -24,7 +24,7 @@
name = "science goggles"
desc = "Goggles fitted with a portable analyzer capable of determining the fabricator training potential of an item or components of a machine. Sensitive to EMP."
icon = 'icons/clothing/eyes/goggles_science.dmi'
- hud_type = HUD_SCIENCE
+ glasses_hud_type = HUD_SCIENCE
toggleable = TRUE
electric = TRUE
anomaly_shielding = 0.1
diff --git a/code/modules/clothing/glasses/hud.dm b/code/modules/clothing/glasses/hud.dm
index 4a4b6dc75a4..cc5acc5c08e 100644
--- a/code/modules/clothing/glasses/hud.dm
+++ b/code/modules/clothing/glasses/hud.dm
@@ -33,7 +33,7 @@
name = "health scanner HUD"
desc = "A heads-up display that scans the humans in view and provides accurate data about their health status."
icon = 'icons/clothing/eyes/hud_medical.dmi'
- hud_type = HUD_MEDICAL
+ glasses_hud_type = HUD_MEDICAL
body_parts_covered = 0
/obj/item/clothing/glasses/hud/health/process_hud(var/mob/M)
@@ -55,7 +55,7 @@
name = "security HUD"
desc = "A heads-up display that scans the humans in view and provides accurate data about their ID status and security records."
icon = 'icons/clothing/eyes/hud_security.dmi'
- hud_type = HUD_SECURITY
+ glasses_hud_type = HUD_SECURITY
body_parts_covered = 0
/obj/item/clothing/glasses/hud/security/prescription
@@ -82,7 +82,7 @@
desc = "A heads-up display that scans for messes and alerts the user. Good for finding puddles hiding under catwalks."
icon = 'icons/clothing/eyes/hud_janitor.dmi'
body_parts_covered = 0
- hud_type = HUD_JANITOR
+ glasses_hud_type = HUD_JANITOR
/obj/item/clothing/glasses/hud/janitor/prescription
name = "prescription janiHUD"
diff --git a/code/modules/clothing/head/misc_special.dm b/code/modules/clothing/head/misc_special.dm
index 8e1a1901d64..090b5d0ff48 100644
--- a/code/modules/clothing/head/misc_special.dm
+++ b/code/modules/clothing/head/misc_special.dm
@@ -60,7 +60,7 @@
flags_inv &= ~(HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE)
to_chat(usr, "You push the [src] up out of your face.")
update_icon()
- update_vision()
+ update_wearer_vision()
usr.update_action_buttons()
/obj/item/clothing/head/welding/on_update_icon()
diff --git a/code/modules/clothing/spacesuits/rig/rig.dm b/code/modules/clothing/spacesuits/rig/rig.dm
index f752dd8294f..d96b4abb6e8 100644
--- a/code/modules/clothing/spacesuits/rig/rig.dm
+++ b/code/modules/clothing/spacesuits/rig/rig.dm
@@ -200,7 +200,7 @@
LAZYSET(chest.slowdown_per_slot, slot_wear_suit_str, (active? online_slowdown : offline_slowdown))
if(helmet)
helmet.tint = (active? vision_restriction : offline_vision_restriction)
- helmet.update_vision()
+ helmet.update_wearer_vision()
/obj/item/rig/proc/suit_is_deployed()
if(!istype(wearer) || src.loc != wearer || wearer.get_equipped_item(slot_back_str) != src)
diff --git a/code/modules/events/carp_migration.dm b/code/modules/events/carp_migration.dm
index fde3b27d545..c44eeda8814 100644
--- a/code/modules/events/carp_migration.dm
+++ b/code/modules/events/carp_migration.dm
@@ -74,7 +74,7 @@ var/global/list/carp_count = list() // a list of Z levels (string), associated w
break
/datum/event/carp_migration/proc/check_gib(var/mob/living/simple_animal/hostile/carp/M) //awesome road kills
- if(M.health <= 0 && prob(60))
+ if(M.current_health <= 0 && prob(60))
M.gib()
/proc/get_random_edge_turf(var/direction, var/clearance = TRANSITIONEDGE + 1, var/Z)
diff --git a/code/modules/hydroponics/seed.dm b/code/modules/hydroponics/seed.dm
index 3a359e1582e..c3b8e583319 100644
--- a/code/modules/hydroponics/seed.dm
+++ b/code/modules/hydroponics/seed.dm
@@ -270,7 +270,7 @@
origin_turf.visible_message(SPAN_DANGER("\The [thrown] splatters against [target]!"))
splatter(origin_turf,thrown)
-/datum/seed/proc/handle_environment(var/turf/current_turf, var/datum/gas_mixture/environment, var/light_supplied, var/check_only)
+/datum/seed/proc/handle_plant_environment(var/turf/current_turf, var/datum/gas_mixture/environment, var/light_supplied, var/check_only)
var/health_change = 0
// Handle gas consumption.
diff --git a/code/modules/hydroponics/spreading/spreading_growth.dm b/code/modules/hydroponics/spreading/spreading_growth.dm
index 770a7b64168..6125017277d 100644
--- a/code/modules/hydroponics/spreading/spreading_growth.dm
+++ b/code/modules/hydroponics/spreading/spreading_growth.dm
@@ -43,10 +43,10 @@
return
//Take damage from bad environment if any
- adjust_health(-seed.handle_environment(T,T.return_air(),null,1))
+ adjust_health(-seed.handle_plant_environment(T,T.return_air(),null,1))
if(health <= 0)
return
-
+
//Vine fight!
for(var/obj/effect/vine/other in T)
if(other.seed != seed)
@@ -76,7 +76,7 @@
var/list/neighbors = get_neighbors()
if(neighbors.len)
spread_to(pick(neighbors))
-
+
//Try to settle down
if(can_spawn_plant())
plant = new(T,seed)
diff --git a/code/modules/hydroponics/trays/tray_process.dm b/code/modules/hydroponics/trays/tray_process.dm
index b308e466061..5065d15e7eb 100644
--- a/code/modules/hydroponics/trays/tray_process.dm
+++ b/code/modules/hydroponics/trays/tray_process.dm
@@ -84,9 +84,9 @@
// Seed datum handles gasses, light and pressure.
if(mechanical && closed_system)
- plant_health -= seed.handle_environment(T,environment,tray_light)
+ plant_health -= seed.handle_plant_environment(T,environment,tray_light)
else
- plant_health -= seed.handle_environment(T,environment)
+ plant_health -= seed.handle_plant_environment(T,environment)
// If we're attached to a pipenet, then we should let the pipenet know we might have modified some gasses
if (closed_system && get_port())
diff --git a/code/modules/integrated_electronics/subtypes/input.dm b/code/modules/integrated_electronics/subtypes/input.dm
index eca6e1289c2..1c6b4d186f1 100644
--- a/code/modules/integrated_electronics/subtypes/input.dm
+++ b/code/modules/integrated_electronics/subtypes/input.dm
@@ -197,15 +197,15 @@
return
if(H in view(get_turf(src))) // Like medbot's analyzer it can be used in range..
-
+ var/current_max_health = H.get_max_health()
var/obj/item/organ/internal/brain = GET_INTERNAL_ORGAN(H, BP_BRAIN)
set_pin_data(IC_OUTPUT, 1, (brain && H.stat != DEAD))
set_pin_data(IC_OUTPUT, 2, (H.stat == CONSCIOUS))
- set_pin_data(IC_OUTPUT, 3, damage_to_severity(100 * H.getBruteLoss() / H.maxHealth))
- set_pin_data(IC_OUTPUT, 4, damage_to_severity(100 * H.getFireLoss() / H.maxHealth))
- set_pin_data(IC_OUTPUT, 5, damage_to_severity(100 * H.getToxLoss() / H.maxHealth))
- set_pin_data(IC_OUTPUT, 6, damage_to_severity(100 * H.getOxyLoss() / H.maxHealth))
- set_pin_data(IC_OUTPUT, 7, damage_to_severity(100 * H.getCloneLoss() / H.maxHealth))
+ set_pin_data(IC_OUTPUT, 3, damage_to_severity(100 * H.getBruteLoss() / current_max_health))
+ set_pin_data(IC_OUTPUT, 4, damage_to_severity(100 * H.getFireLoss() / current_max_health))
+ set_pin_data(IC_OUTPUT, 5, damage_to_severity(100 * H.getToxLoss() / current_max_health))
+ set_pin_data(IC_OUTPUT, 6, damage_to_severity(100 * H.getOxyLoss() / current_max_health))
+ set_pin_data(IC_OUTPUT, 7, damage_to_severity(100 * H.getCloneLoss() / current_max_health))
set_pin_data(IC_OUTPUT, 8, H.get_pulse_as_number())
set_pin_data(IC_OUTPUT, 9, H.get_blood_oxygenation())
set_pin_data(IC_OUTPUT, 10, damage_to_severity(H.get_shock()))
diff --git a/code/modules/materials/definitions/gasses/material_gas_mundane.dm b/code/modules/materials/definitions/gasses/material_gas_mundane.dm
index a4bc989ec7c..4d55d71770c 100644
--- a/code/modules/materials/definitions/gasses/material_gas_mundane.dm
+++ b/code/modules/materials/definitions/gasses/material_gas_mundane.dm
@@ -68,20 +68,12 @@
warning_message = pick("extremely dizzy","short of breath","faint","confused")
warning_prob = 15
M.adjustOxyLoss(10,20)
- if(istype(H))
- H.co2_alert = 1
else if(dosage >= 1.5)
warning_message = pick("dizzy","short of breath","faint","momentarily confused")
M.adjustOxyLoss(3,5)
- if(istype(H))
- H.co2_alert = 1
else if(dosage >= 0.25)
warning_message = pick("a little dizzy","short of breath")
warning_prob = 10
- if(istype(H))
- H.co2_alert = 0
- else if(istype(H))
- H.co2_alert = 0
if(istype(H) && dosage > 1 && H.ticks_since_last_successful_breath < 15)
H.ticks_since_last_successful_breath++
if(warning_message && prob(warning_prob))
diff --git a/code/modules/mechs/components/_components.dm b/code/modules/mechs/components/_components.dm
index 76866925803..fa8ae476b26 100644
--- a/code/modules/mechs/components/_components.dm
+++ b/code/modules/mechs/components/_components.dm
@@ -55,7 +55,7 @@
user.visible_message(SPAN_NOTICE("\The [user] installs \the [thing] in \the [src]."))
return 1
-/obj/item/mech_component/proc/update_health()
+/obj/item/mech_component/proc/update_component_health()
total_damage = brute_damage + burn_damage
if(total_damage > max_damage) total_damage = max_damage
var/prev_state = damage_state
@@ -77,13 +77,13 @@
/obj/item/mech_component/proc/take_brute_damage(var/amt)
brute_damage = max(0, brute_damage + amt)
- update_health()
+ update_component_health()
if(total_damage == max_damage)
take_component_damage(amt,0)
/obj/item/mech_component/proc/take_burn_damage(var/amt)
burn_damage = max(0, burn_damage + amt)
- update_health()
+ update_component_health()
if(total_damage == max_damage)
take_component_damage(0,amt)
diff --git a/code/modules/mechs/interface/_interface.dm b/code/modules/mechs/interface/_interface.dm
index 38535387f41..45945a7b49a 100644
--- a/code/modules/mechs/interface/_interface.dm
+++ b/code/modules/mechs/interface/_interface.dm
@@ -23,7 +23,7 @@
client.screen |= hud_elements
/mob/living/exosuit/InitializeHud()
- zone_sel = new
+
if(!LAZYLEN(hud_elements))
var/i = 1
for(var/hardpoint in hardpoints)
@@ -58,6 +58,13 @@
refresh_hud()
+/mob/living/exosuit/should_do_hud_updates()
+ . = ..()
+ if(!. && length(pilots))
+ for(var/mob/living/pilot in pilots)
+ if(pilot.should_do_hud_updates())
+ return TRUE
+
/mob/living/exosuit/handle_hud_icons()
for(var/hardpoint in hardpoint_hud_elements)
var/obj/screen/exosuit/hardpoint/H = hardpoint_hud_elements[hardpoint]
diff --git a/code/modules/mechs/mech.dm b/code/modules/mechs/mech.dm
index 02a0acef775..72b1d5f5d50 100644
--- a/code/modules/mechs/mech.dm
+++ b/code/modules/mechs/mech.dm
@@ -21,6 +21,7 @@
bone_material = null
bone_amount = 0
+ var/zone_tracker
var/emp_damage = 0
var/obj/item/radio/exosuit/radio
@@ -67,6 +68,7 @@
// Interface stuff.
var/list/hud_elements = list()
var/list/hardpoint_hud_elements = list()
+ // TODO: /datum/hud/exosuit
var/obj/screen/exosuit/health/hud_health
var/obj/screen/exosuit/toggle/hatch_open/hud_open
var/obj/screen/exosuit/power/hud_power
@@ -119,8 +121,6 @@
if(source_frame.material)
material = source_frame.material
- updatehealth()
-
// Generate hardpoint list.
var/list/component_descriptions
for(var/obj/item/mech_component/comp in list(arms, legs, head, body))
diff --git a/code/modules/mechs/mech_damage.dm b/code/modules/mechs/mech_damage.dm
index 84e74389446..1e3c2e2a5fa 100644
--- a/code/modules/mechs/mech_damage.dm
+++ b/code/modules/mechs/mech_damage.dm
@@ -80,19 +80,22 @@
if(body_armor)
. += body_armor
-/mob/living/exosuit/updatehealth()
- maxHealth = body ? body.mech_health : 0
- health = maxHealth-(getFireLoss()+getBruteLoss())
+/mob/living/exosuit/get_max_health()
+ return (body ? body.mech_health : 0)
-/mob/living/exosuit/adjustFireLoss(var/amount, var/obj/item/mech_component/MC = pick(list(arms, legs, body, head)))
+/mob/living/exosuit/get_total_life_damage()
+ return (getFireLoss()+getBruteLoss())
+
+/mob/living/exosuit/adjustFireLoss(var/amount, var/obj/item/mech_component/MC = pick(list(arms, legs, body, head)), var/do_update_health)
if(MC)
MC.take_burn_damage(amount)
- MC.update_health()
+ if(do_update_health)
+ update_health() // TODO: unify these procs somehow instead of having weird brute-wrapping behavior as the default.
-/mob/living/exosuit/adjustBruteLoss(var/amount, var/obj/item/mech_component/MC = pick(list(arms, legs, body, head)))
+/mob/living/exosuit/adjustBruteLoss(var/amount, var/obj/item/mech_component/MC = pick(list(arms, legs, body, head)), var/do_update_health)
if(MC)
MC.take_brute_damage(amount)
- MC.update_health()
+ ..()
/mob/living/exosuit/proc/zoneToComponent(var/zone)
switch(zone)
@@ -142,9 +145,9 @@
//Only 3 types of damage concern mechs and vehicles
switch(damagetype)
if(BRUTE)
- adjustBruteLoss(damage, target)
+ adjustBruteLoss(damage, target, do_update_health = TRUE)
if(BURN)
- adjustFireLoss(damage, target)
+ adjustFireLoss(damage, target, do_update_health = TRUE)
if(IRRADIATE)
for(var/mob/living/pilot in pilots)
pilot.apply_damage(damage, IRRADIATE, def_zone, damage_flags, used_weapon)
@@ -152,8 +155,6 @@
if((damagetype == BRUTE || damagetype == BURN) && prob(25+(damage*2)))
sparks.set_up(3,0,src)
sparks.start()
- updatehealth()
-
return 1
/mob/living/exosuit/rad_act(var/severity)
@@ -164,7 +165,7 @@
if(!hatch_closed || (body.pilot_coverage < 100)) //Open, environment is the source
return .
var/list/after_armor = modify_damage_by_armor(null, ., IRRADIATE, DAM_DISPERSED, src, 0, TRUE)
- return after_armor[1]
+ return after_armor[1]
/mob/living/exosuit/getFireLoss()
var/total = 0
@@ -200,6 +201,6 @@
for(var/thing in pilots)
var/mob/pilot = thing
pilot.emp_act(severity)
-
+
/mob/living/exosuit/get_bullet_impact_effect_type(def_zone)
return BULLET_IMPACT_METAL
diff --git a/code/modules/mechs/mech_damage_immunity.dm b/code/modules/mechs/mech_damage_immunity.dm
index 23a69ffd596..6a425c5a07c 100644
--- a/code/modules/mechs/mech_damage_immunity.dm
+++ b/code/modules/mechs/mech_damage_immunity.dm
@@ -14,7 +14,8 @@
/mob/living/exosuit/setOxyLoss()
return 0
-/mob/living/exosuit/adjustOxyLoss()
+/mob/living/exosuit/adjustOxyLoss(var/damage, var/do_update_health)
+ SHOULD_CALL_PARENT(FALSE)
return 0
/mob/living/exosuit/getToxLoss()
@@ -23,7 +24,7 @@
/mob/living/exosuit/setToxLoss()
return 0
-/mob/living/exosuit/adjustToxLoss()
+/mob/living/exosuit/adjustToxLoss(var/amount, var/do_update_health)
return 0
/mob/living/exosuit/getBrainLoss()
@@ -32,7 +33,8 @@
/mob/living/exosuit/setBrainLoss()
return 0
-/mob/living/exosuit/adjustBrainLoss()
+/mob/living/exosuit/adjustBrainLoss(var/amount, var/do_update_health)
+ SHOULD_CALL_PARENT(FALSE)
return 0
/mob/living/exosuit/getCloneLoss()
diff --git a/code/modules/mechs/mech_interaction.dm b/code/modules/mechs/mech_interaction.dm
index 2268f62713d..9361de6fcaa 100644
--- a/code/modules/mechs/mech_interaction.dm
+++ b/code/modules/mechs/mech_interaction.dm
@@ -81,7 +81,7 @@
if(!hatch_closed)
return max(shared_living_nano_distance(src_object), .) //Either visible to mech(outside) or visible to user (inside)
-/mob/living/exosuit/exosuit/CanUseTopic(mob/user, datum/topic_state/state, href_list)
+/mob/living/exosuit/CanUseTopic(mob/user, datum/topic_state/state, href_list)
if(user in pilots)
return STATUS_INTERACTIVE
return ..()
@@ -89,6 +89,15 @@
/mob/living/exosuit/get_dexterity(var/silent = FALSE)
return DEXTERITY_FULL
+// Override as mechs will usually not have clients and therefore not have HUDs.
+/mob/living/exosuit/get_target_zone()
+ if(!istype(hud_used))
+ return
+ var/obj/screen/zone_selector/zone_selector = get_hud_element(/decl/hud_element/zone_selector)
+ if(istype(zone_selector))
+ return zone_selector.selecting
+ return zone_tracker
+
/mob/living/exosuit/ClickOn(var/atom/A, var/params, var/mob/user)
if(!user || incapacitated() || user.incapacitated())
@@ -134,10 +143,13 @@
// User is not necessarily the exosuit, or the same person, so update intent.
if(user != src)
a_intent = user.a_intent
- if(user.zone_sel)
- zone_sel.set_selected_zone(user.get_target_zone())
+ var/obj/screen/zone_selector/zone_selector = get_hud_element(/decl/hud_element/zone_selector)
+ var/set_zone = user.get_target_zone() || BP_CHEST
+ if(istype(zone_selector))
+ zone_selector.set_selected_zone(set_zone)
else
- zone_sel.set_selected_zone(BP_CHEST)
+ zone_tracker = set_zone
+
// You may attack the target with your exosuit FIST if you're malfunctioning.
var/atom/movable/AM = A
var/fail_prob = (user != src && istype(AM) && AM.loc != src) ? (user.skill_check(SKILL_MECH, HAS_PERK) ? 0: 15 ) : 0
diff --git a/code/modules/mechs/mech_life.dm b/code/modules/mechs/mech_life.dm
index c000678ca65..ad1964eb516 100644
--- a/code/modules/mechs/mech_life.dm
+++ b/code/modules/mechs/mech_life.dm
@@ -1,7 +1,16 @@
/mob/living/exosuit/handle_disabilities()
return
-/mob/living/exosuit/Life()
+/mob/living/exosuit/update_lying()
+ lying = FALSE // Prevent carp from proning us
+
+/mob/living/exosuit/handle_regular_status_updates()
+
+ if(!body && !QDELETED(src))
+ physically_destroyed()
+ return FALSE
+
+ . = ..()
for(var/thing in pilots)
var/mob/pilot = thing
@@ -12,20 +21,10 @@
UNSETEMPTY(pilots)
update_pilots()
- if(!body && !QDELETED(src))
- qdel(src)
- return
-
if(radio)
radio.on = (head && head.radio && head.radio.is_functional() && get_cell())
- body.update_air(hatch_closed && use_air)
-
- var/powered = FALSE
- if(get_cell())
- powered = get_cell().drain_power(0, 0, calc_power_draw()) > 0
-
- if(!powered)
+ if(!is_suit_powered())
//Shut down all systems
if(head)
head.active_sensors = FALSE
@@ -35,18 +34,11 @@
if(istype(M) && M.active && M.passive_power_use)
M.deactivate()
- updatehealth()
- if(health <= 0 && stat != DEAD)
- death()
-
if(emp_damage > 0)
emp_damage -= min(1, emp_damage) //Reduce emp accumulation over time
- ..() //Handles stuff like environment
-
- handle_hud_icons()
- lying = FALSE // Fuck off, carp.
- handle_vision(powered)
+/mob/living/exosuit/proc/is_suit_powered()
+ return (get_cell()?.drain_power(0, 0, calc_power_draw())) > 0
/mob/living/exosuit/get_cell(force)
RETURN_TYPE(/obj/item/cell)
@@ -73,7 +65,13 @@
/mob/living/exosuit/handle_environment(var/datum/gas_mixture/environment)
..()
- if(!environment) return
+
+ if(body)
+ body.update_air(hatch_closed && use_air)
+
+ if(!environment)
+ return
+
//Mechs and vehicles in general can be assumed to just tend to whatever ambient temperature
if(abs(environment.temperature - bodytemperature) > 0 )
bodytemperature += ((environment.temperature - bodytemperature) / 6)
@@ -125,14 +123,14 @@
qdel(src)
return
-/mob/living/exosuit/handle_vision(powered)
+/mob/living/exosuit/handle_vision()
var/was_blind = sight & BLIND
if(head)
+ var/powered = is_suit_powered()
sight = head.get_sight(powered)
see_invisible = head.get_invisible(powered)
if(body && (body.pilot_coverage < 100 || body.transparent_cabin) || !hatch_closed)
sight &= ~BLIND
-
if(sight & BLIND && !was_blind)
for(var/mob/pilot in pilots)
to_chat(pilot, SPAN_WARNING("The sensors are not operational and you cannot see a thing!"))
diff --git a/code/modules/mechs/mech_movement.dm b/code/modules/mechs/mech_movement.dm
index 6f926046cfa..b7847041cbc 100644
--- a/code/modules/mechs/mech_movement.dm
+++ b/code/modules/mechs/mech_movement.dm
@@ -14,10 +14,10 @@
var/turf/B = GetAbove(src)
- for(var/thing in pilots)
- var/mob/pilot = thing
- if(pilot.up_hint)
- pilot.up_hint.icon_state = "uphint[!!(B && TURF_IS_MIMICKING(B))]"
+ for(var/mob/pilot in pilots)
+ var/obj/screen/up_hint = pilot.get_hud_element(/decl/hud_element/up_hint)
+ if(up_hint)
+ up_hint.icon_state = "uphint[!!(B && TURF_IS_MIMICKING(B))]"
/mob/living/exosuit/can_ztravel()
if(Process_Spacemove(1)) //Handle here
diff --git a/code/modules/mob/death.dm b/code/modules/mob/death.dm
index 35f46d326c7..c6fd39d4bbc 100644
--- a/code/modules/mob/death.dm
+++ b/code/modules/mob/death.dm
@@ -1,7 +1,9 @@
//This is the proc for gibbing a mob. Cannot gib ghosts.
//added different sort of gibs and animations. N
/mob/proc/gib(anim="gibbed-m",do_gibs)
+
set waitfor = FALSE
+
death(1)
ADD_TRANSFORMATION_MOVEMENT_HANDLER(src)
icon = null
@@ -72,14 +74,8 @@
SSstatistics.report_death(src)
- //TODO: Change death state to health_dead for all these icon files. This is a stop gap.
- if(healths)
- healths.overlays.Cut() // This is specific to humans but the relevant code is here; shouldn't mess with other mobs.
- if("health7" in icon_states(healths.icon))
- healths.icon_state = "health7"
- else
- healths.icon_state = "health6"
- log_debug("[src] ([src.type]) died but does not have a valid health7 icon_state (using health6 instead). report this error to Ccomp5950 or your nearest Developer")
+ if(hud_used)
+ hud_used.update_icons()
timeofdeath = world.time
if(mind)
diff --git a/code/modules/mob/examine.dm b/code/modules/mob/examine.dm
index 1026da99b4d..2b8f7db8b9f 100644
--- a/code/modules/mob/examine.dm
+++ b/code/modules/mob/examine.dm
@@ -62,8 +62,9 @@
/mob/living/examine(mob/user, distance, infix, suffix)
. = ..()
// Update our target dolly.
- if(user.zone_sel)
+ var/obj/screen/zone_selector = user.get_hud_element(/decl/hud_element/zone_selector)
+ if(zone_selector)
if(should_have_limb(BP_TAIL))
- user.zone_sel.icon_state = "zone_sel_tail"
+ zone_selector.icon_state = "zone_sel_tail"
else
- user.zone_sel.icon_state = "zone_sel"
+ zone_selector.icon_state = "zone_sel"
diff --git a/code/modules/mob/grab/grab_object.dm b/code/modules/mob/grab/grab_object.dm
index 4f8977cca2b..b8ff4e72e92 100644
--- a/code/modules/mob/grab/grab_object.dm
+++ b/code/modules/mob/grab/grab_object.dm
@@ -54,8 +54,9 @@
update_icon()
events_repository.register(/decl/observ/moved, affecting, src, .proc/on_affecting_move)
- if(assailant.zone_sel)
- events_repository.register(/decl/observ/zone_selected, assailant.zone_sel, src, .proc/on_target_change)
+ var/obj/screen/zone_selector = assailant.get_hud_element(/decl/hud_element/zone_selector)
+ if(zone_selector)
+ events_repository.register(/decl/observ/zone_selected, zone_selector, src, .proc/on_target_change)
var/obj/item/organ/O = get_targeted_organ()
var/decl/pronouns/G = assailant.get_pronouns()
@@ -129,8 +130,9 @@
affecting.reset_plane_and_layer()
affecting = null
if(assailant)
- if(assailant.zone_sel)
- events_repository.unregister(/decl/observ/zone_selected, assailant.zone_sel, src)
+ var/obj/screen/zone_selector = assailant.get_hud_element(/decl/hud_element/zone_selector)
+ if(zone_selector)
+ events_repository.unregister(/decl/observ/zone_selected, zone_selector, src)
assailant = null
. = ..()
if(old_affecting)
diff --git a/code/modules/mob/grab/normal/grab_normal.dm b/code/modules/mob/grab/normal/grab_normal.dm
index 0bcdc241be9..03ac58d1bbe 100644
--- a/code/modules/mob/grab/normal/grab_normal.dm
+++ b/code/modules/mob/grab/normal/grab_normal.dm
@@ -1,6 +1,6 @@
/decl/grab/normal
name = "grab"
- icon = 'icons/mob/screen1.dmi'
+ icon = 'icons/mob/screen/grabs.dmi'
help_action = "inspect"
disarm_action = "pin"
grab_action = "jointlock"
diff --git a/code/modules/mob/living/bot/bot.dm b/code/modules/mob/living/bot/bot.dm
index f6108bc649d..8761be38674 100644
--- a/code/modules/mob/living/bot/bot.dm
+++ b/code/modules/mob/living/bot/bot.dm
@@ -1,7 +1,6 @@
/mob/living/bot
name = "Bot"
- health = 20
- maxHealth = 20
+ mob_default_max_health = 20
icon = 'icons/mob/bot/placeholder.dmi'
universal_speak = TRUE
density = FALSE
@@ -55,33 +54,26 @@
access_scanner = new /obj(src)
access_scanner.req_access = req_access?.Copy()
-/mob/living/bot/Initialize()
- . = ..()
+
if(on)
turn_on() // Update lights and other stuff
else
turn_off()
-/mob/living/bot/Life()
- ..()
- if(health <= 0)
- death()
- return
- set_status(STAT_WEAK, 0)
- set_status(STAT_STUN, 0)
- set_status(STAT_PARA, 0)
-
- if(on && !client && !busy)
- handleAI()
+/mob/living/bot/handle_regular_status_updates()
+ . = ..()
+ if(.)
+ set_status(STAT_WEAK, 0)
+ set_status(STAT_STUN, 0)
+ set_status(STAT_PARA, 0)
-/mob/living/bot/updatehealth()
- if(status_flags & GODMODE)
- health = maxHealth
- set_stat(CONSCIOUS)
- else
- health = maxHealth - getFireLoss() - getBruteLoss()
+/mob/living/bot/get_total_life_damage()
+ return getFireLoss() + getBruteLoss()
/mob/living/bot/death()
+ if(stat == DEAD)
+ return
+ set_stat(DEAD)
explode()
/mob/living/bot/attackby(var/obj/item/O, var/mob/user)
@@ -104,9 +96,9 @@
to_chat(user, "You need to unlock the controls first.")
return
else if(IS_WELDER(O))
- if(health < maxHealth)
+ if(current_health < get_max_health())
if(open)
- health = min(maxHealth, health + 10)
+ heal_overall_damage(10)
user.visible_message("\The [user] repairs \the [src].","You repair \the [src].")
else
to_chat(user, "Unable to repair with the maintenance panel closed.")
@@ -209,7 +201,12 @@
/mob/living/bot/emag_act(var/remaining_charges, var/mob/user)
return 0
-/mob/living/bot/proc/handleAI()
+/mob/living/bot/handle_legacy_ai()
+ . = ..()
+ if(on && !busy)
+ handle_async_ai()
+
+/mob/living/bot/proc/handle_async_ai()
set waitfor = FALSE
if(ignore_list.len)
for(var/atom/A in ignore_list)
diff --git a/code/modules/mob/living/bot/ed209bot.dm b/code/modules/mob/living/bot/ed209bot.dm
index 178b5cd51ac..2cb63993c64 100644
--- a/code/modules/mob/living/bot/ed209bot.dm
+++ b/code/modules/mob/living/bot/ed209bot.dm
@@ -6,8 +6,7 @@
attack_state = "ed209-c"
layer = MOB_LAYER
density = TRUE
- health = 100
- maxHealth = 100
+ mob_default_max_health = 100
preparing_arrest_sounds = new()
diff --git a/code/modules/mob/living/bot/farmbot.dm b/code/modules/mob/living/bot/farmbot.dm
index 6dea16be17b..05772f8f8e3 100644
--- a/code/modules/mob/living/bot/farmbot.dm
+++ b/code/modules/mob/living/bot/farmbot.dm
@@ -8,8 +8,7 @@
desc = "The botanist's best friend."
icon = 'icons/mob/bot/farmbot.dmi'
icon_state = "farmbot0"
- health = 50
- maxHealth = 50
+ mob_default_max_health = 50
req_access = list(list(access_hydroponics, access_robotics))
var/action = "" // Used to update icon
diff --git a/code/modules/mob/living/bot/mulebot.dm b/code/modules/mob/living/bot/mulebot.dm
index 818d8a95f59..2d064cbc155 100644
--- a/code/modules/mob/living/bot/mulebot.dm
+++ b/code/modules/mob/living/bot/mulebot.dm
@@ -15,8 +15,7 @@
layer = MOB_LAYER
anchored = TRUE
density = TRUE
- health = 150
- maxHealth = 150
+ mob_default_max_health = 150
mob_bump_flag = HEAVY
min_target_dist = 0
diff --git a/code/modules/mob/living/bot/remotebot.dm b/code/modules/mob/living/bot/remotebot.dm
index 88698d91de4..2b7d9019360 100644
--- a/code/modules/mob/living/bot/remotebot.dm
+++ b/code/modules/mob/living/bot/remotebot.dm
@@ -3,8 +3,7 @@
desc = "A remote controlled robot used by lazy people to switch channels and get pizza."
icon = 'icons/mob/bot/fetchbot.dmi'
icon_state = "fetchbot1"
- health = 15
- maxHealth = 15
+ mob_default_max_health = 15
var/working = 0
var/speed = 10 //lower = better
diff --git a/code/modules/mob/living/bot/secbot.dm b/code/modules/mob/living/bot/secbot.dm
index b33a7665cc9..a244b5410f4 100644
--- a/code/modules/mob/living/bot/secbot.dm
+++ b/code/modules/mob/living/bot/secbot.dm
@@ -7,10 +7,8 @@
desc = "A little security robot. He looks less than thrilled."
icon = 'icons/mob/bot/secbot.dmi'
icon_state = "secbot0"
- var/attack_state = "secbot-c"
layer = MOB_LAYER
- maxHealth = 50
- health = 50
+ mob_default_max_health = 50
req_access = list(list(access_security, access_forensics_lockers))
botcard_access = list(access_security, access_sec_doors, access_forensics_lockers, access_morgue, access_maint_tunnels)
@@ -20,6 +18,7 @@
RequiresAccessToToggle = 1 // Haha no
+ var/attack_state = "secbot-c"
var/idcheck = 0 // If true, arrests for having weapons without authorization.
var/check_records = 0 // If true, arrests people without a record.
var/check_arrest = 1 // If true, arrests people who are set to arrest.
@@ -108,9 +107,9 @@
emagged = !emagged
/mob/living/bot/secbot/attackby(var/obj/item/O, var/mob/user)
- var/curhealth = health
+ var/curhealth = current_health
. = ..()
- if(health < curhealth)
+ if(current_health < curhealth)
react_to_attack(user)
/mob/living/bot/secbot/emag_act(var/remaining_charges, var/mob/user)
@@ -123,11 +122,11 @@
return 1
/mob/living/bot/secbot/bullet_act(var/obj/item/projectile/P)
- var/curhealth = health
+ var/curhealth = current_health
var/mob/shooter = P.firer
. = ..()
//if we already have a target just ignore to avoid lots of checking
- if(!target && health < curhealth && istype(shooter) && (shooter in view(world.view, src)))
+ if(!target && current_health < curhealth && istype(shooter) && (shooter in view(world.view, src)))
react_to_attack(shooter)
/mob/living/bot/secbot/proc/begin_arrest(mob/target, var/threat)
diff --git a/code/modules/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm
index 2ef856b10ea..9a959c07e7b 100644
--- a/code/modules/mob/living/carbon/alien/alien.dm
+++ b/code/modules/mob/living/carbon/alien/alien.dm
@@ -2,8 +2,7 @@
name = "alien"
desc = "What IS that?"
pass_flags = PASS_FLAG_TABLE
- health = 100
- maxHealth = 100
+ mob_default_max_health = 100
mob_size = MOB_SIZE_TINY
mob_sort_value = 8
var/dead_icon
diff --git a/code/modules/mob/living/carbon/alien/alien_attacks.dm b/code/modules/mob/living/carbon/alien/alien_attacks.dm
index dd556813f6e..0d8325a5a3b 100644
--- a/code/modules/mob/living/carbon/alien/alien_attacks.dm
+++ b/code/modules/mob/living/carbon/alien/alien_attacks.dm
@@ -19,8 +19,7 @@
if (damage > 4.9)
SET_STATUS_MAX(src, STAT_WEAK, rand(10,15))
user.visible_message(SPAN_DANGER("\The [user] has weakened \the [src]!"), 1, SPAN_WARNING("You hear someone fall."), 2)
- adjustBruteLoss(damage)
- updatehealth()
+ adjustBruteLoss(damage, do_update_health = TRUE)
else
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
visible_message(SPAN_DANGER("\The [user] has attempted to punch \the [src]!"), 1)
diff --git a/code/modules/mob/living/carbon/alien/alien_damage.dm b/code/modules/mob/living/carbon/alien/alien_damage.dm
index e75135ae6a6..5d24ca9b6ca 100644
--- a/code/modules/mob/living/carbon/alien/alien_damage.dm
+++ b/code/modules/mob/living/carbon/alien/alien_damage.dm
@@ -18,5 +18,4 @@
SET_STATUS_MAX(src, STAT_TINNITUS, 15)
SET_STATUS_MAX(src, STAT_DEAF, 60)
adjustBruteLoss(b_loss)
- adjustFireLoss(f_loss)
- updatehealth()
+ adjustFireLoss(f_loss, do_update_health = TRUE)
diff --git a/code/modules/mob/living/carbon/alien/life.dm b/code/modules/mob/living/carbon/alien/life.dm
index e30e596790e..8224dafcaed 100644
--- a/code/modules/mob/living/carbon/alien/life.dm
+++ b/code/modules/mob/living/carbon/alien/life.dm
@@ -1,13 +1,3 @@
-// Alien larva are quite simple.
-/mob/living/carbon/alien/Life()
- set invisibility = FALSE
- set background = TRUE
- if (HAS_TRANSFORMATION_MOVEMENT_HANDLER(src)) return
- if(!loc) return
- ..()
- //Status updates, death etc.
- update_icon()
-
/mob/living/carbon/alien/handle_mutations_and_radiation()
..()
if(radiation)
@@ -20,81 +10,41 @@
/mob/living/carbon/alien/handle_regular_status_updates()
- if(status_flags & GODMODE) return 0
+ . = ..()
if(stat == DEAD)
SET_STATUS_MAX(src, STAT_BLIND, 2)
set_status(STAT_SILENCE, 0)
- else
- updatehealth()
- if(health <= 0)
- death()
- SET_STATUS_MAX(src, STAT_BLIND, 2)
- set_status(STAT_SILENCE, 0)
- return 1
-
- if(HAS_STATUS(src, STAT_PARA))
- SET_STATUS_MAX(src, STAT_BLIND, 2)
- set_stat(UNCONSCIOUS)
- if(getHalLoss() > 0)
- adjustHalLoss(-3)
-
- if(HAS_STATUS(src, STAT_ASLEEP))
+ else if(HAS_STATUS(src, STAT_PARA))
+ SET_STATUS_MAX(src, STAT_BLIND, 2)
+ set_stat(UNCONSCIOUS)
+ if(getHalLoss() > 0)
adjustHalLoss(-3)
- SET_STATUS_MAX(src, STAT_BLIND, 2)
- set_stat(UNCONSCIOUS)
- else if(resting)
- if(getHalLoss() > 0)
- adjustHalLoss(-3)
-
- else
- set_stat(CONSCIOUS)
- if(getHalLoss() > 0)
- adjustHalLoss(-1)
-
- // Eyes and blindness.
- if(!check_has_eyes())
- SET_STATUS_MAX(src, STAT_BLIND, 2)
- SET_STATUS_MAX(src, STAT_BLURRY, 1)
-
- update_icon()
-
- return 1
-
-/mob/living/carbon/alien/handle_regular_hud_updates()
- update_sight()
- if (healths)
- if(stat != DEAD)
- switch(health)
- if(100 to INFINITY)
- healths.icon_state = "health0"
- if(80 to 100)
- healths.icon_state = "health1"
- if(60 to 80)
- healths.icon_state = "health2"
- if(40 to 60)
- healths.icon_state = "health3"
- if(20 to 40)
- healths.icon_state = "health4"
- if(0 to 20)
- healths.icon_state = "health5"
- else
- healths.icon_state = "health6"
- else
- healths.icon_state = "health7"
+ if(HAS_STATUS(src, STAT_ASLEEP))
+ adjustHalLoss(-3)
+ if (mind)
+ if(mind.active && client != null)
+ ADJ_STATUS(src, STAT_ASLEEP, -1)
+ SET_STATUS_MAX(src, STAT_BLIND, 2)
+ set_stat(UNCONSCIOUS)
+ else if(resting)
+ if(getHalLoss() > 0)
+ adjustHalLoss(-3)
+ else
+ set_stat(CONSCIOUS)
+ if(getHalLoss() > 0)
+ adjustHalLoss(-1)
- if(stat != DEAD)
- if(is_blind())
- overlay_fullscreen("blind", /obj/screen/fullscreen/blind)
- else
- clear_fullscreen("blind")
- set_fullscreen(disabilities & NEARSIGHTED, "impaired", /obj/screen/fullscreen/impaired, 1)
- set_fullscreen(GET_STATUS(src, STAT_BLURRY), "blurry", /obj/screen/fullscreen/blurry)
- set_fullscreen(GET_STATUS(src, STAT_DRUGGY), "high", /obj/screen/fullscreen/high)
- if(machine)
- if(machine.check_eye(src) < 0)
- reset_view(null)
- return 1
+ // Eyes and blindness.
+ if(!check_has_eyes())
+ set_status(STAT_BLIND, 1)
+ SET_STATUS_MAX(src, STAT_BLIND, 2)
+ set_status(STAT_BLURRY, 1)
+ else if(GET_STATUS(src, STAT_BLIND))
+ ADJ_STATUS(src, STAT_BLIND, -1)
+ SET_STATUS_MAX(src, STAT_BLIND, 2)
+ update_icon()
+ return TRUE
/mob/living/carbon/alien/handle_environment(var/datum/gas_mixture/environment)
..()
@@ -102,11 +52,8 @@
// so I'll just define this once, for both (see radiation comment above)
if(environment && environment.temperature > (T0C+66))
adjustFireLoss((environment.temperature - (T0C+66))/5) // Might be too high, check in testing.
- if (fire) fire.icon_state = "fire2"
if(prob(20))
to_chat(src, "You feel a searing heat!")
- else
- if (fire) fire.icon_state = "fire0"
/mob/living/carbon/alien/handle_fire()
if(..())
diff --git a/code/modules/mob/living/carbon/brain/brain.dm b/code/modules/mob/living/carbon/brain/brain.dm
index 6c61b5d061a..9380fd3eef7 100644
--- a/code/modules/mob/living/carbon/brain/brain.dm
+++ b/code/modules/mob/living/carbon/brain/brain.dm
@@ -9,14 +9,15 @@
icon_state = "brain1"
mob_sort_value = 7
+/mob/living/carbon/brain/can_emote()
+ return stat == CONSCIOUS && istype(loc, /obj/item/mmi)
+
/mob/living/carbon/brain/Initialize()
create_reagents(1000)
. = ..()
/mob/living/carbon/brain/Destroy()
if(key) //If there is a mob connected to this thing. Have to check key twice to avoid false death reporting.
- if(stat!=DEAD) //If not dead.
- death(1) //Brains can die again. AND THEY SHOULD AHA HA HA HA HA HA
ghostize() //Ghostize checks for key so nothing else is necessary.
. = ..()
diff --git a/code/modules/mob/living/carbon/brain/life.dm b/code/modules/mob/living/carbon/brain/life.dm
index 98fd99f1e2b..e69d66c6b22 100644
--- a/code/modules/mob/living/carbon/brain/life.dm
+++ b/code/modules/mob/living/carbon/brain/life.dm
@@ -17,25 +17,21 @@
if(1 to 49)
radiation--
if(prob(25))
- adjustToxLoss(1)
- updatehealth()
+ adjustToxLoss(1, do_update_health = TRUE)
if(50 to 74)
radiation -= 2
- adjustToxLoss(1)
+ adjustToxLoss(1, do_update_health = TRUE)
if(prob(5))
radiation -= 5
if(!container)
to_chat(src, "You feel weak.")
else
to_chat(src, "STATUS: DANGEROUS LEVELS OF RADIATION DETECTED.")
- updatehealth()
if(75 to 100)
radiation -= 3
- adjustToxLoss(3)
- updatehealth()
-
+ adjustToxLoss(3, do_update_health = TRUE)
/mob/living/carbon/brain/handle_environment(datum/gas_mixture/environment)
..()
@@ -54,16 +50,11 @@
/mob/living/carbon/brain/proc/handle_temperature_damage(body_part, exposed_temperature, exposed_intensity)
if(status_flags & GODMODE) return
-
if(exposed_temperature > bodytemperature)
var/discomfort = min( abs(exposed_temperature - bodytemperature)*(exposed_intensity)/2000000, 1.0)
- //adjustFireLoss(2.5*discomfort)
- //adjustFireLoss(5.0*discomfort)
adjustFireLoss(20.0*discomfort)
-
else
var/discomfort = min( abs(exposed_temperature - bodytemperature)*(exposed_intensity)/2000000, 1.0)
- //adjustFireLoss(2.5*discomfort)
adjustFireLoss(5.0*discomfort)
/mob/living/carbon/brain/apply_chemical_effects()
@@ -72,106 +63,17 @@
ADJ_STATUS(src, STAT_DIZZY, -4)
return TRUE
-/mob/living/carbon/brain/handle_regular_status_updates() //TODO: comment out the unused bits >_>
- updatehealth()
-
- if(stat == DEAD) //DEAD. BROWN BREAD. SWIMMING WITH THE SPESS CARP
- SET_STATUS_MAX(src, STAT_BLIND, 2)
- set_status(STAT_SILENCE, 0)
- else //ALIVE. LIGHTS ARE ON
- if( !container && (health < config.health_threshold_dead || (config.revival_brain_life >= 0 && (world.time - timeofhostdeath) > config.revival_brain_life)) )
- death()
- SET_STATUS_MAX(src, STAT_BLIND, 2)
- set_status(STAT_SILENCE, 0)
- return 1
+/mob/living/carbon/brain/is_blind()
+ return !container || ..()
- //Handling EMP effect in the Life(), it's made VERY simply, and has some additional effects handled elsewhere
- if(emp_damage) //This is pretty much a damage type only used by MMIs, dished out by the emp_act
- if(!(container && istype(container, /obj/item/mmi)))
- emp_damage = 0
- else
- emp_damage = round(emp_damage,1)//Let's have some nice numbers to work with
- switch(emp_damage)
- if(31 to INFINITY)
- emp_damage = 30//Let's not overdo it
- if(21 to 30)//High level of EMP damage, unable to see, hear, or speak
- SET_STATUS_MAX(src, STAT_BLIND, 2)
- SET_STATUS_MAX(src, STAT_DEAF, 2)
- SET_STATUS_MAX(src, STAT_SILENCE, 2)
- if(!alert)//Sounds an alarm, but only once per 'level'
- emote("alarm")
- to_chat(src, "Major electrical distruption detected: System rebooting.")
- alert = 1
- if(prob(75))
- emp_damage -= 1
- if(20)
- alert = 0
- set_status(STAT_BLIND, 0)
- set_status(STAT_DEAF, 0)
- set_status(STAT_SILENCE, 0)
- emp_damage -= 1
- if(11 to 19)//Moderate level of EMP damage, resulting in nearsightedness and ear damage
- set_status(STAT_BLURRY, 2)
- set_status(STAT_TINNITUS, 2)
- if(!alert)
- emote("alert")
- to_chat(src, "Primary systems are now online.")
- alert = 1
- if(prob(50))
- emp_damage -= 1
- if(10)
- alert = 0
- set_status(STAT_BLURRY, 0)
- set_status(STAT_TINNITUS, 0)
- emp_damage -= 1
- if(2 to 9)//Low level of EMP damage, has few effects(handled elsewhere)
- if(!alert)
- emote("notice")
- to_chat(src, "System reboot nearly complete.")
- alert = 1
- if(prob(25))
- emp_damage -= 1
- if(1)
- alert = 0
- to_chat(src, "All systems restored.")
- emp_damage -= 1
+/mob/living/carbon/brain/should_be_dead()
+ return !container && (current_health < config.health_threshold_dead || (config.revival_brain_life >= 0 && (world.time - timeofhostdeath) > config.revival_brain_life))
- return 1
+/mob/living/carbon/brain/handle_regular_status_updates()
-/mob/living/carbon/brain/handle_regular_hud_updates()
- update_sight()
- if (healths)
- if (stat != DEAD)
- switch(health)
- if(100 to INFINITY)
- healths.icon_state = "health0"
- if(80 to 100)
- healths.icon_state = "health1"
- if(60 to 80)
- healths.icon_state = "health2"
- if(40 to 60)
- healths.icon_state = "health3"
- if(20 to 40)
- healths.icon_state = "health4"
- if(0 to 20)
- healths.icon_state = "health5"
- else
- healths.icon_state = "health6"
- else
- healths.icon_state = "health7"
-
- if(stat != DEAD)
- if(is_blind())
- overlay_fullscreen("blind", /obj/screen/fullscreen/blind)
- else
- clear_fullscreen("blind")
- set_fullscreen(disabilities & NEARSIGHTED, "impaired", /obj/screen/fullscreen/impaired, 1)
- set_fullscreen(GET_STATUS(src, STAT_BLURRY), "blurry", /obj/screen/fullscreen/blurry)
- set_fullscreen(GET_STATUS(src, STAT_DRUGGY), "high", /obj/screen/fullscreen/high)
- if (machine)
- if (!( machine.check_eye(src) ))
- reset_view(null)
- return 1
+ . = ..()
+ if(!. || stat == DEAD || !emp_damage || !container)
+ return
/mob/living/carbon/brain/can_change_intent()
return TRUE
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index 5116b4d629a..84b09cae19c 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -61,7 +61,6 @@
var/obj/item/organ/external/organ = GET_EXTERNAL_ORGAN(src, BP_CHEST)
if(istype(organ))
organ.take_external_damage(d, 0)
- updatehealth()
else
take_organ_damage(d)
if(prob(getBruteLoss() - 50))
diff --git a/code/modules/mob/living/carbon/carbon_organs.dm b/code/modules/mob/living/carbon/carbon_organs.dm
index 9e3bcd0efdb..4fd1c5d27c1 100644
--- a/code/modules/mob/living/carbon/carbon_organs.dm
+++ b/code/modules/mob/living/carbon/carbon_organs.dm
@@ -26,7 +26,7 @@
internal_organs = null
external_organs = null
-/mob/living/carbon/add_organ(obj/item/organ/O, obj/item/organ/external/affected, in_place, update_icon, detached)
+/mob/living/carbon/add_organ(obj/item/organ/O, obj/item/organ/external/affected, in_place, update_icon, detached, skip_health_update = FALSE)
var/obj/item/organ/existing = LAZYACCESS(organs_by_tag, O.organ_tag)
if(existing && O != existing)
CRASH("mob/living/carbon/add_organ(): '[O]' tried to overwrite [src]'s existing organ '[existing]' in slot '[O.organ_tag]'!")
@@ -43,7 +43,7 @@
LAZYDISTINCTADD(external_organs, O)
. = ..()
-/mob/living/carbon/remove_organ(var/obj/item/organ/O, var/drop_organ = TRUE, var/detach = TRUE, var/ignore_children = FALSE, var/in_place = FALSE, var/update_icon = TRUE)
+/mob/living/carbon/remove_organ(var/obj/item/organ/O, var/drop_organ = TRUE, var/detach = TRUE, var/ignore_children = FALSE, var/in_place = FALSE, var/update_icon = TRUE, var/skip_health_update = FALSE)
if(istype(O) && !in_place && O.is_vital_to_owner() && usr)
admin_attack_log(usr, src, "Removed a vital organ ([src]).", "Had a vital organ ([src]) removed.", "removed a vital organ ([src]) from")
if(!(. = ..()))
diff --git a/code/modules/mob/living/carbon/damage_procs.dm b/code/modules/mob/living/carbon/damage_procs.dm
index 0329801ad70..891e8791597 100644
--- a/code/modules/mob/living/carbon/damage_procs.dm
+++ b/code/modules/mob/living/carbon/damage_procs.dm
@@ -8,6 +8,5 @@ Specifically made to do radiation burns.
..()
if(!isSynthetic() && !ignore_rads)
damage = 0.25 * damage * (species ? species.get_radiation_mod(src) : 1)
- adjustFireLoss(damage)
- updatehealth()
+ adjustFireLoss(damage, do_update_health = TRUE)
return TRUE
diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm
index b68d1e52ac0..bdb626d7779 100644
--- a/code/modules/mob/living/carbon/human/examine.dm
+++ b/code/modules/mob/living/carbon/human/examine.dm
@@ -243,14 +243,14 @@
var/obj/item/clothing/glasses/G = get_equipped_item(slot_glasses_str)
if(!istype(G))
return
- if(G.hud_type & hudtype)
+ if(G.glasses_hud_type & hudtype)
return G
- if(G.hud && (G.hud.hud_type & hudtype))
+ if(G.hud && (G.hud.glasses_hud_type & hudtype))
return G.hud
/mob/living/silicon/robot/getHUDsource(hudtype)
for(var/obj/item/borg/sight/sight in list(module_state_1, module_state_2, module_state_3))
- if(istype(sight) && (sight.hud_type & hudtype))
+ if(istype(sight) && (sight.borg_hud_type & hudtype))
return sight
//Gets the computer network M's source of hudtype is using
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index cff72d41d5a..7da6742bd45 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -6,12 +6,14 @@
icon_state = "body_m_s"
mob_sort_value = 6
dna = new /datum/dna()
+ mob_default_max_health = 150
var/list/hud_list[10]
var/embedded_flag //To check if we've need to roll for damage on movement while an item is imbedded in us.
var/step_count
/mob/living/carbon/human/Initialize(mapload, species_name = null, datum/dna/new_dna = null, decl/bodytype/new_bodytype = null)
+ current_health = mob_default_max_health
setup_hud_overlays()
var/list/newargs = args.Copy(2)
setup(arglist(newargs))
@@ -36,7 +38,6 @@
global.human_mob_list -= src
regenerate_body_icon = FALSE // don't bother regenerating if we happen to be queued to update icon
worn_underwear = null
- QDEL_NULL(attack_selector)
QDEL_NULL(vessel)
LAZYCLEARLIST(smell_cooldown)
. = ..()
@@ -552,7 +553,7 @@
holder_type = null
if(species.holder_type)
holder_type = species.holder_type
- maxHealth = species.total_health
+ set_max_health(species.total_health, skip_health_update = TRUE) // Health update is handled later.
remove_extension(src, /datum/extension/armor)
if(species.natural_armour_values)
set_extension(src, /datum/extension/armor, species.natural_armour_values)
@@ -597,6 +598,7 @@
else if(has_extension(src, /datum/extension/scannable))
remove_extension(src, /datum/extension/scannable)
+ update_health()
return TRUE
//Syncs cultural tokens to the currently set species, and may trigger a language update
@@ -947,7 +949,7 @@
//Point at which you dun breathe no more. Separate from asystole crit, which is heart-related.
/mob/living/carbon/human/nervous_system_failure()
- return getBrainLoss() >= maxHealth * 0.75
+ return getBrainLoss() >= get_max_health() * 0.75
/mob/living/carbon/human/melee_accuracy_mods()
. = ..()
diff --git a/code/modules/mob/living/carbon/human/human_attackhand.dm b/code/modules/mob/living/carbon/human/human_attackhand.dm
index 50172253223..ce39adf3b83 100644
--- a/code/modules/mob/living/carbon/human/human_attackhand.dm
+++ b/code/modules/mob/living/carbon/human/human_attackhand.dm
@@ -354,4 +354,7 @@
var/summary = default_attack.summarize()
if(summary)
to_chat(src, SPAN_NOTICE(summary))
- attack_selector?.update_icon()
\ No newline at end of file
+
+ var/obj/screen/default_attack_selector/attack_selector = get_hud_element(/decl/hud_element/attack_selector)
+ if(istype(attack_selector))
+ attack_selector.update_icon()
diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm
index 7ac0f60acec..fd3d85ef6d8 100644
--- a/code/modules/mob/living/carbon/human/human_damage.dm
+++ b/code/modules/mob/living/carbon/human/human_damage.dm
@@ -1,24 +1,19 @@
-//Updates the mob's health from organs and mob damage variables
-/mob/living/carbon/human/updatehealth()
-
- if(status_flags & GODMODE)
- health = maxHealth
- set_stat(CONSCIOUS)
- return
-
- health = maxHealth - getBrainLoss()
+/mob/living/carbon/human/get_total_life_damage()
+ return getBrainLoss()
+//Updates the mob's health from organs and mob damage variables
+/mob/living/carbon/human/update_health()
+ ..()
//TODO: fix husking
- if(((maxHealth - getFireLoss()) < config.health_threshold_dead) && stat == DEAD)
+ if(stat == DEAD && (get_max_health() - getFireLoss()) < config.health_threshold_dead)
make_husked()
- return
-/mob/living/carbon/human/adjustBrainLoss(var/amount)
- if(status_flags & GODMODE) return 0 //godmode
- if(should_have_organ(BP_BRAIN))
+/mob/living/carbon/human/adjustBrainLoss(var/amount, var/do_update_health)
+ if(!(status_flags & GODMODE) && should_have_organ(BP_BRAIN))
var/obj/item/organ/internal/sponge = GET_INTERNAL_ORGAN(src, BP_BRAIN)
if(sponge)
sponge.take_internal_damage(amount)
+ ..()
/mob/living/carbon/human/setBrainLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
@@ -26,7 +21,7 @@
var/obj/item/organ/internal/sponge = GET_INTERNAL_ORGAN(src, BP_BRAIN)
if(sponge)
sponge.damage = min(max(amount, 0),sponge.species.total_health)
- updatehealth()
+ update_health()
/mob/living/carbon/human/getBrainLoss()
if(status_flags & GODMODE) return 0 //godmode
@@ -87,14 +82,15 @@
amount += O.burn_dam
return amount
-/mob/living/carbon/human/adjustBruteLoss(var/amount)
+/mob/living/carbon/human/adjustBruteLoss(var/amount, var/do_update_health)
+ SHOULD_CALL_PARENT(FALSE) // take/heal overall call update_health regardless of arg
if(amount > 0)
take_overall_damage(amount, 0)
else
heal_overall_damage(-amount, 0)
BITSET(hud_updateflag, HEALTH_HUD)
-/mob/living/carbon/human/adjustFireLoss(var/amount)
+/mob/living/carbon/human/adjustFireLoss(var/amount, var/do_update_health)
if(amount > 0)
take_overall_damage(0, amount)
else
@@ -137,14 +133,15 @@
/mob/living/carbon/human/setOxyLoss(var/amount)
adjustOxyLoss(amount - getOxyLoss())
-/mob/living/carbon/human/adjustOxyLoss(var/amount)
+/mob/living/carbon/human/adjustOxyLoss(var/damage, var/do_update_health)
+ . = FALSE
if(need_breathe())
var/obj/item/organ/internal/lungs/breathe_organ = get_organ(get_bodytype().breathing_organ, /obj/item/organ/internal/lungs)
if(breathe_organ)
- breathe_organ.adjust_oxygen_deprivation(amount)
+ breathe_organ.adjust_oxygen_deprivation(damage)
BITSET(hud_updateflag, HEALTH_HUD)
- return TRUE
- return FALSE
+ . = TRUE
+ ..(do_update_health = FALSE) // Oxyloss cannot directly kill humans
/mob/living/carbon/human/getToxLoss()
if((species.species_flags & SPECIES_FLAG_NO_POISON) || isSynthetic())
@@ -159,7 +156,7 @@
adjustToxLoss(getToxLoss()-amount)
// TODO: better internal organ damage procs.
-/mob/living/carbon/human/adjustToxLoss(var/amount)
+/mob/living/carbon/human/adjustToxLoss(var/amount, var/do_update_health)
if((species.species_flags & SPECIES_FLAG_NO_POISON) || isSynthetic())
return
@@ -212,6 +209,9 @@
I.take_internal_damage(amount, silent=TRUE)
amount = 0
+ if(do_update_health)
+ update_health()
+
/mob/living/carbon/human/proc/can_autoheal(var/dam_type)
if(!species || !dam_type) return FALSE
@@ -248,7 +248,7 @@
var/obj/item/organ/external/picked = pick(parts)
if(picked.heal_damage(brute,burn,robo_repair = affect_robo))
BITSET(hud_updateflag, HEALTH_HUD)
- updatehealth()
+ update_health()
//TODO reorganize damage procs so that there is a clean API for damaging living mobs
@@ -261,11 +261,12 @@ In most cases it makes more sense to use apply_damage() instead! And make sure t
//It automatically updates health status
/mob/living/carbon/human/take_organ_damage(var/brute = 0, var/burn = 0, var/bypass_armour = FALSE, var/override_droplimb)
var/list/parts = get_damageable_organs()
- if(length(parts))
- var/obj/item/organ/external/picked = pick(parts)
- if(picked.take_external_damage(brute, burn, override_droplimb = override_droplimb))
- BITSET(hud_updateflag, HEALTH_HUD)
- updatehealth()
+ if(!length(parts))
+ return
+ var/obj/item/organ/external/picked = pick(parts)
+ if(picked.take_external_damage(brute, burn, override_droplimb = override_droplimb))
+ BITSET(hud_updateflag, HEALTH_HUD)
+ update_health()
//Heal MANY external organs, in random order
/mob/living/carbon/human/heal_overall_damage(var/brute, var/burn)
@@ -283,14 +284,17 @@ In most cases it makes more sense to use apply_damage() instead! And make sure t
burn -= (burn_was-picked.burn_dam)
parts -= picked
- updatehealth()
+ update_health()
BITSET(hud_updateflag, HEALTH_HUD)
// damage MANY external organs, in random order
/mob/living/carbon/human/take_overall_damage(var/brute, var/burn, var/sharp = 0, var/edge = 0, var/used_weapon = null)
- if(status_flags & GODMODE) return //godmode
+ if(status_flags & GODMODE)
+ return //godmode
+
var/list/obj/item/organ/external/parts = get_damageable_organs()
- if(!parts.len) return
+ if(!parts.len)
+ return
var/dam_flags = (sharp? DAM_SHARP : 0)|(edge? DAM_EDGE : 0)
var/brute_avg = brute / parts.len
@@ -306,7 +310,7 @@ In most cases it makes more sense to use apply_damage() instead! And make sure t
if(burn_avg)
apply_damage(damage = burn_avg, damagetype = BURN, damage_flags = dam_flags, used_weapon = used_weapon, silent = TRUE, given_organ = E)
- updatehealth()
+ update_health()
BITSET(hud_updateflag, HEALTH_HUD)
/*
@@ -380,7 +384,7 @@ This function restores all organs.
organ.add_genetic_damage(damage)
// Will set our damageoverlay icon to the next level, which will then be set back to the normal level the next mob.Life().
- updatehealth()
+ update_health()
BITSET(hud_updateflag, HEALTH_HUD)
return created_wound
diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm
index 7f9ce538e1c..91d11aa891c 100644
--- a/code/modules/mob/living/carbon/human/human_defines.dm
+++ b/code/modules/mob/living/carbon/human/human_defines.dm
@@ -22,8 +22,6 @@
var/list/cultural_info = list()
- var/obj/screen/default_attack_selector/attack_selector
-
var/icon/stand_icon = null
var/voice = "" //Instead of new say code calling GetVoice() over and over and over, we're just going to ask this variable, which gets updated in Life()
diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm
index 77ed36f7740..f5baf81a4d5 100644
--- a/code/modules/mob/living/carbon/human/human_movement.dm
+++ b/code/modules/mob/living/carbon/human/human_movement.dm
@@ -18,7 +18,7 @@
tally -= GET_CHEMICAL_EFFECT(src, CE_SPEEDBOOST)
tally += GET_CHEMICAL_EFFECT(src, CE_SLOWDOWN)
- var/health_deficiency = (maxHealth - health)
+ var/health_deficiency = (get_max_health() - current_health)
if(health_deficiency >= 40) tally += (health_deficiency / 25)
if(can_feel_pain())
@@ -118,9 +118,6 @@
handle_leg_damage()
species.handle_post_move(src)
- if(client)
- var/turf/B = GetAbove(src)
- up_hint.icon_state = "uphint[!!(B && TURF_IS_MIMICKING(B))]"
/mob/living/carbon/human/proc/handle_leg_damage()
if(!can_feel_pain())
diff --git a/code/modules/mob/living/carbon/human/human_organs.dm b/code/modules/mob/living/carbon/human/human_organs.dm
index 6e57fb48c2c..2573c969a20 100644
--- a/code/modules/mob/living/carbon/human/human_organs.dm
+++ b/code/modules/mob/living/carbon/human/human_organs.dm
@@ -272,7 +272,7 @@
//Registers an organ and setup the organ hierachy properly.
//affected : Parent organ if applicable.
//in_place : If true, we're performing an in-place replacement, without triggering anything related to adding the organ in-game as part of surgery or else.
-/mob/living/carbon/human/add_organ(obj/item/organ/O, obj/item/organ/external/affected, in_place, update_icon, detached)
+/mob/living/carbon/human/add_organ(obj/item/organ/O, obj/item/organ/external/affected, in_place, update_icon, detached, skip_health_update = FALSE)
if(!(. = ..()))
return
if(!O.is_internal())
@@ -283,7 +283,7 @@
update_inhand_overlays(FALSE)
update_body(FALSE)
update_bandages(FALSE)
- UpdateDamageIcon(FALSE)
+ update_damage_icon(FALSE)
hud_reset()
queue_icon_update() //Avoids calling icon updates 50 times when adding multiple organs
@@ -293,7 +293,7 @@
//ignore_children: Skips recursively removing this organ's child organs.
//in_place : If true we remove only the organ (no children items or implants) and avoid triggering mob changes and parent organs changes as much as possible.
// Meant to be used for init and species transforms, without triggering any updates to mob state or anything related to losing a limb as part of surgery or combat.
-/mob/living/carbon/human/remove_organ(obj/item/organ/O, drop_organ, detach, ignore_children, in_place, update_icon)
+/mob/living/carbon/human/remove_organ(obj/item/organ/O, drop_organ, detach, ignore_children, in_place, update_icon, skip_health_update = FALSE)
if(!(. = ..()))
return
if(!O.is_internal())
diff --git a/code/modules/mob/living/carbon/human/human_species.dm b/code/modules/mob/living/carbon/human/human_species.dm
index 97a3a514c60..5a4481d923b 100644
--- a/code/modules/mob/living/carbon/human/human_species.dm
+++ b/code/modules/mob/living/carbon/human/human_species.dm
@@ -29,8 +29,9 @@
if(mind)
mind.name = real_name
- adjustOxyLoss(maxHealth)//cease life functions
- setBrainLoss(maxHealth)
+ var/current_max_health = get_max_health()
+ adjustOxyLoss(current_max_health)//cease life functions
+ setBrainLoss(current_max_health)
var/obj/item/organ/internal/heart/corpse_heart = get_organ(BP_HEART, /obj/item/organ/internal/heart)
if(corpse_heart)
corpse_heart.pulse = PULSE_NONE//actually stops heart to make worried explorers not care too much
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index 89966468fb8..c1f044061a8 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -29,43 +29,15 @@
#define COLD_GAS_DAMAGE_LEVEL_3 3 //Amount of damage applied when the current breath's temperature passes the 120K point
/mob/living/carbon/human
- var/oxygen_alert = 0
- var/toxins_alert = 0
- var/co2_alert = 0
- var/fire_alert = 0
- var/pressure_alert = 0
var/stamina = 100
-/mob/living/carbon/human/Life()
- set invisibility = FALSE
- set background = BACKGROUND_ENABLED
-
- if (HAS_TRANSFORMATION_MOVEMENT_HANDLER(src))
- return
-
- fire_alert = 0 //Reset this here, because both breathe() and handle_environment() have a chance to set it.
-
- ..()
-
- if(life_tick%30==15)
- hud_updateflag = 1022
-
- voice = GetVoice()
-
- //No need to update all of these procs if the guy is dead.
- if(stat != DEAD && !is_in_stasis())
- last_pain = null // Clear the last cached pain value so further getHalloss() calls won't use an old value.
- //Organs and blood
- handle_organs()
- handle_shock()
- handle_pain()
- handle_stamina()
-
- if(!handle_some_updates())
- return //We go ahead and process them 5 times for HUD images and other stuff though.
-
- //Update our name based on whether our face is obscured/disfigured
- SetName(get_visible_name())
+/mob/living/carbon/human/handle_living_non_stasis_processes()
+ last_pain = null // Clear the last cached pain value so further getHalloss() calls won't use an old value.
+ //Organs and blood
+ handle_organs()
+ handle_shock()
+ handle_pain()
+ handle_stamina()
/mob/living/carbon/human/get_stamina()
return stamina
@@ -144,7 +116,11 @@
return ONE_ATMOSPHERE + pressure_difference
/mob/living/carbon/human/handle_impaired_vision()
- ..()
+
+ . = ..()
+ if(!.)
+ return
+
//Vision
var/obj/item/organ/vision
var/decl/bodytype/root_bodytype = get_bodytype()
@@ -163,10 +139,9 @@
/mob/living/carbon/human/handle_disabilities()
..()
- if(stat != DEAD)
- if ((disabilities & COUGHING) && prob(5) && GET_STATUS(src, STAT_PARA) <= 1)
- drop_held_items()
- cough()
+ if(stat != DEAD && (disabilities & COUGHING) && prob(5) && GET_STATUS(src, STAT_PARA) <= 1)
+ drop_held_items()
+ cough()
/mob/living/carbon/human/handle_mutations_and_radiation()
if(getFireLoss())
@@ -220,7 +195,7 @@
var/loc_temp = environment.temperature
if(adjusted_pressure < species.warning_high_pressure && adjusted_pressure > species.warning_low_pressure && abs(loc_temp - bodytemperature) < 20 && bodytemperature < get_temperature_threshold(HEAT_LEVEL_1) && bodytemperature > get_temperature_threshold(COLD_LEVEL_1) && species.body_temperature)
- pressure_alert = 0
+ SET_HUD_ALERT(src, /decl/hud_element/condition/pressure, 0)
return // Temperatures are within normal ranges, fuck all this processing. ~Ccomp
//Body temperature adjusts depending on surrounding atmosphere based on your thermal protection (convection)
@@ -240,8 +215,8 @@
// +/- 50 degrees from 310.15K is the 'safe' zone, where no damage is dealt.
if(bodytemperature >= get_temperature_threshold(HEAT_LEVEL_1))
//Body temperature is too hot.
- fire_alert = max(fire_alert, 1)
- if(status_flags & GODMODE) return 1 //godmode
+ if(status_flags & GODMODE)
+ return 1 //godmode
var/burn_dam = 0
if(bodytemperature < get_temperature_threshold(HEAT_LEVEL_2))
burn_dam = HEAT_DAMAGE_LEVEL_1
@@ -250,12 +225,11 @@
else
burn_dam = HEAT_DAMAGE_LEVEL_3
take_overall_damage(burn=burn_dam, used_weapon = "High Body Temperature")
- fire_alert = max(fire_alert, 2)
+ SET_HUD_ALERT_MAX(src, /decl/hud_element/condition/fire, 2)
else if(bodytemperature <= get_temperature_threshold(COLD_LEVEL_1))
- fire_alert = max(fire_alert, 1)
- if(status_flags & GODMODE) return 1 //godmode
-
+ if(status_flags & GODMODE)
+ return 1 //godmode
var/burn_dam = 0
if(bodytemperature > get_temperature_threshold(COLD_LEVEL_2))
@@ -267,7 +241,7 @@
set_stasis(get_cryogenic_factor(bodytemperature), STASIS_COLD)
if(!has_chemical_effect(CE_CRYO, 1))
take_overall_damage(burn=burn_dam, used_weapon = "Low Body Temperature")
- fire_alert = max(fire_alert, 1)
+ SET_HUD_ALERT_MAX(src, /decl/hud_element/condition/fire, 1)
// Account for massive pressure differences. Done by Polymorph
// Made it possible to actually have something that can protect against high pressure... Done by Errorage. Polymorph now has an axe sticking from his head for his previous hardcoded nonsense!
@@ -276,13 +250,13 @@
if(adjusted_pressure >= species.hazard_high_pressure)
var/pressure_damage = min( ( (adjusted_pressure / species.hazard_high_pressure) -1 )*PRESSURE_DAMAGE_COEFFICIENT , MAX_HIGH_PRESSURE_DAMAGE)
take_overall_damage(brute=pressure_damage, used_weapon = "High Pressure")
- pressure_alert = 2
+ SET_HUD_ALERT(src, /decl/hud_element/condition/pressure, 2)
else if(adjusted_pressure >= species.warning_high_pressure)
- pressure_alert = 1
+ SET_HUD_ALERT(src, /decl/hud_element/condition/pressure, 1)
else if(adjusted_pressure >= species.warning_low_pressure)
- pressure_alert = 0
+ SET_HUD_ALERT(src, /decl/hud_element/condition/pressure, 0)
else if(adjusted_pressure >= species.hazard_low_pressure)
- pressure_alert = -1
+ SET_HUD_ALERT(src, /decl/hud_element/condition/pressure, -1)
else
var/list/obj/item/organ/external/parts = get_damageable_organs()
for(var/obj/item/organ/external/O in parts)
@@ -292,7 +266,7 @@
O.take_external_damage(brute = LOW_PRESSURE_DAMAGE, used_weapon = "Low Pressure")
if(getOxyLossPercent() < 55) // 11 OxyLoss per 4 ticks when wearing internals; unconsciousness in 16 ticks, roughly half a minute
adjustOxyLoss(4) // 16 OxyLoss per 4 ticks when no internals present; unconsciousness in 13 ticks, roughly twenty seconds
- pressure_alert = -2
+ SET_HUD_ALERT(src, /decl/hud_element/condition/pressure, -2)
return
@@ -382,103 +356,87 @@
return TRUE
/mob/living/carbon/human/handle_regular_status_updates()
- if(!handle_some_updates())
- return 0
- if(status_flags & GODMODE) return 0
+ voice = GetVoice()
+ SetName(get_visible_name())
- //SSD check, if a logged player is awake put them back to sleep!
- if(stat == DEAD) //DEAD. BROWN BREAD. SWIMMING WITH THE SPESS CARP
- SET_STATUS_MAX(src, STAT_BLIND, 2)
- set_status(STAT_SILENCE, 0)
- else //ALIVE. LIGHTS ARE ON
- updatehealth() //TODO
-
- if(hallucination_power)
- handle_hallucinations()
-
- if(get_shock() >= species.total_health)
- if(!stat)
- to_chat(src, "[species.halloss_message_self]")
- src.visible_message("[src] [species.halloss_message]")
- SET_STATUS_MAX(src, STAT_PARA, 10)
-
- if(HAS_STATUS(src, STAT_PARA) ||HAS_STATUS(src, STAT_ASLEEP))
- SET_STATUS_MAX(src, STAT_BLIND, 2)
- set_stat(UNCONSCIOUS)
- animate_tail_reset()
- adjustHalLoss(-3)
-
- if(prob(2) && is_asystole() && isSynthetic())
- visible_message("[src] [pick("emits low pitched whirr","beeps urgently")].")
- //CONSCIOUS
- else
- set_stat(CONSCIOUS)
-
- // Check everything else.
-
- //Periodically double-check embedded_flag
- if(embedded_flag && !(life_tick % 10))
- if(!embedded_needs_process())
- embedded_flag = 0
-
- //Resting
- if(resting)
- if(HAS_STATUS(src, STAT_DIZZY))
- ADJ_STATUS(src, STAT_DIZZY, -15)
- if(HAS_STATUS(src, STAT_JITTER))
- ADJ_STATUS(src, STAT_JITTER, -15)
- adjustHalLoss(-3)
- else
- if(HAS_STATUS(src, STAT_DIZZY))
- ADJ_STATUS(src, STAT_DIZZY, -3)
- if(HAS_STATUS(src, STAT_JITTER))
- ADJ_STATUS(src, STAT_JITTER, -3)
- adjustHalLoss(-1)
+ if(status_flags & GODMODE)
+ return FALSE
+
+ if(vsc.contaminant_control.CONTAMINATION_LOSS)
+ var/total_contamination= 0
+ for(var/obj/item/I in src)
+ if(I.contaminated)
+ total_contamination += vsc.contaminant_control.CONTAMINATION_LOSS
+ adjustToxLoss(total_contamination)
+
+ . = ..()
+ if(!.)
+ return
+
+ if(hallucination_power)
+ handle_hallucinations()
+
+ if(get_shock() >= species.total_health)
+ if(!stat)
+ to_chat(src, "[species.halloss_message_self]")
+ src.visible_message("[src] [species.halloss_message]")
+ SET_STATUS_MAX(src, STAT_PARA, 10)
+
+ if(HAS_STATUS(src, STAT_PARA) || HAS_STATUS(src, STAT_ASLEEP))
+ set_stat(UNCONSCIOUS)
+ animate_tail_reset()
+ adjustHalLoss(-3)
+ if(prob(2) && is_asystole() && isSynthetic())
+ visible_message("[src] [pick("emits low pitched whirr","beeps urgently")].")
+ else
+ set_stat(CONSCIOUS)
+
+ // Check everything else.
+ //Periodically double-check embedded_flag
+ if(embedded_flag && !(life_tick % 10))
+ if(!embedded_needs_process())
+ embedded_flag = 0
+
+ //Resting
+ if(resting)
+ if(HAS_STATUS(src, STAT_DIZZY))
+ ADJ_STATUS(src, STAT_DIZZY, -15)
+ if(HAS_STATUS(src, STAT_JITTER))
+ ADJ_STATUS(src, STAT_JITTER, -15)
+ adjustHalLoss(-3)
+ else
+ if(HAS_STATUS(src, STAT_DIZZY))
+ ADJ_STATUS(src, STAT_DIZZY, -3)
+ if(HAS_STATUS(src, STAT_JITTER))
+ ADJ_STATUS(src, STAT_JITTER, -3)
+ adjustHalLoss(-1)
+
+ if(HAS_STATUS(src, STAT_DROWSY))
+ SET_STATUS_MAX(src, STAT_BLURRY, 2)
+ var/sleepy = GET_STATUS(src, STAT_DROWSY)
+ if(sleepy > 10)
+ var/zzzchance = min(5, 5*sleepy/30)
+ if((prob(zzzchance) || sleepy >= 60))
+ if(stat == CONSCIOUS)
+ to_chat(src, SPAN_NOTICE("You are about to fall asleep..."))
+ SET_STATUS_MAX(src, STAT_ASLEEP, 5)
- if(HAS_STATUS(src, STAT_DROWSY))
- SET_STATUS_MAX(src, STAT_BLURRY, 2)
- var/sleepy = GET_STATUS(src, STAT_DROWSY)
- if(sleepy > 10)
- var/zzzchance = min(5, 5*sleepy/30)
- if((prob(zzzchance) || sleepy >= 60))
- if(stat == CONSCIOUS)
- to_chat(src, "You are about to fall asleep...")
- SET_STATUS_MAX(src, STAT_ASLEEP, 5)
-
- // If you're dirty, your gloves will become dirty, too.
- var/obj/item/gloves = get_equipped_item(slot_gloves_str)
- if(gloves && germ_level > gloves.germ_level && prob(10))
- gloves.germ_level += 1
-
- if(vsc.contaminant_control.CONTAMINATION_LOSS)
- var/total_contamination= 0
- for(var/obj/item/I in src)
- if(I.contaminated)
- total_contamination += vsc.contaminant_control.CONTAMINATION_LOSS
- adjustToxLoss(total_contamination)
-
- if(stasis_value > 1 && GET_STATUS(src, STAT_DROWSY) < stasis_value * 4)
- ADJ_STATUS(src, STAT_DROWSY, min(stasis_value, 3))
- if(!stat && prob(1))
- to_chat(src, "You feel slow and sluggish...")
-
- return 1
/mob/living/carbon/human/handle_regular_hud_updates()
+ if(life_tick%30==15)
+ hud_updateflag = 1022
if(hud_updateflag) // update our mob's hud overlays, AKA what others see flaoting above our head
handle_hud_list()
-
- // now handle what we see on our screen
-
- if(!..())
+ . = ..()
+ if(!.)
return
-
if(stat != DEAD)
- if(stat == UNCONSCIOUS && health < maxHealth/2)
+ var/half_health = get_max_health()/2
+ if(stat == UNCONSCIOUS && current_health < half_health)
//Critical damage passage overlay
var/severity = 0
- switch(health - maxHealth/2)
+ switch(current_health - half_health)
if(-20 to -10) severity = 1
if(-30 to -20) severity = 2
if(-40 to -30) severity = 3
@@ -506,7 +464,6 @@
overlay_fullscreen("oxy", /obj/screen/fullscreen/oxy, severity)
else
clear_fullscreen("oxy")
-
//Fire and Brute damage overlay (BSSR)
var/hurtdamage = src.getBruteLoss() + src.getFireLoss() + damageoverlaytemp
damageoverlaytemp = 0 // We do this so we can detect if someone hits us or not.
@@ -522,128 +479,7 @@
overlay_fullscreen("brute", /obj/screen/fullscreen/brute, severity)
else
clear_fullscreen("brute")
-
- if(healths)
-
- var/mutable_appearance/healths_ma = new(healths)
- healths_ma.icon_state = "blank"
- healths_ma.overlays = null
-
- if(has_chemical_effect(CE_PAINKILLER, 100))
- healths_ma.icon_state = "health_numb"
- else
- // Generate a by-limb health display.
- var/no_damage = 1
- var/trauma_val = 0 // Used in calculating softcrit/hardcrit indicators.
- if(can_feel_pain())
- trauma_val = max(shock_stage,get_shock())/(species.total_health-100)
- // Collect and apply the images all at once to avoid appearance churn.
- var/list/health_images = list()
- for(var/obj/item/organ/external/E in get_external_organs())
- if(no_damage && (E.brute_dam || E.burn_dam))
- no_damage = 0
- health_images += E.get_damage_hud_image()
-
- // Apply a fire overlay if we're burning.
- if(on_fire)
- health_images += image('icons/mob/screen1_health.dmi',"burning")
-
- // Show a general pain/crit indicator if needed.
- if(is_asystole())
- health_images += image('icons/mob/screen1_health.dmi',"hardcrit")
- else if(trauma_val)
- if(can_feel_pain())
- if(trauma_val > 0.7)
- health_images += image('icons/mob/screen1_health.dmi',"softcrit")
- if(trauma_val >= 1)
- health_images += image('icons/mob/screen1_health.dmi',"hardcrit")
- else if(no_damage)
- health_images += image('icons/mob/screen1_health.dmi',"fullhealth")
- healths_ma.overlays += health_images
- healths.appearance = healths_ma
-
- if(nutrition_icon)
- switch(nutrition)
- if(450 to INFINITY) nutrition_icon.icon_state = "nutrition0"
- if(350 to 450) nutrition_icon.icon_state = "nutrition1"
- if(250 to 350) nutrition_icon.icon_state = "nutrition2"
- if(150 to 250) nutrition_icon.icon_state = "nutrition3"
- else nutrition_icon.icon_state = "nutrition4"
-
- if(hydration_icon)
- switch(hydration)
- if(450 to INFINITY) hydration_icon.icon_state = "hydration0"
- if(350 to 450) hydration_icon.icon_state = "hydration1"
- if(250 to 350) hydration_icon.icon_state = "hydration2"
- if(150 to 250) hydration_icon.icon_state = "hydration3"
- else hydration_icon.icon_state = "hydration4"
-
- if(isSynthetic())
- var/obj/item/organ/internal/cell/C = get_organ(BP_CELL, /obj/item/organ/internal/cell)
- if(C)
- var/chargeNum = clamp(CEILING(C.percent()/25), 0, 4) //0-100 maps to 0-4, but give it a paranoid clamp just in case.
- cells.icon_state = "charge[chargeNum]"
- else
- cells.icon_state = "charge-empty"
-
- if(pressure)
- pressure.icon_state = "pressure[pressure_alert]"
- if(toxin)
- toxin.icon_state = "tox[toxins_alert ? "1" : "0"]"
- if(oxygen)
- oxygen.icon_state = "oxy[oxygen_alert ? "1" : "0"]"
- if(fire)
- fire.icon_state = "fire[fire_alert ? fire_alert : 0]"
-
- if(bodytemp)
- if (!species)
- switch(bodytemperature) //310.055 optimal body temp
- if(370 to INFINITY) bodytemp.icon_state = "temp4"
- if(350 to 370) bodytemp.icon_state = "temp3"
- if(335 to 350) bodytemp.icon_state = "temp2"
- if(320 to 335) bodytemp.icon_state = "temp1"
- if(300 to 320) bodytemp.icon_state = "temp0"
- if(295 to 300) bodytemp.icon_state = "temp-1"
- if(280 to 295) bodytemp.icon_state = "temp-2"
- if(260 to 280) bodytemp.icon_state = "temp-3"
- else bodytemp.icon_state = "temp-4"
- else
- var/heat_1 = get_temperature_threshold(HEAT_LEVEL_1)
- var/cold_1 = get_temperature_threshold(COLD_LEVEL_1)
- //TODO: precalculate all of this stuff when the species datum is created
- var/base_temperature = species.body_temperature
- if(base_temperature == null) //some species don't have a set metabolic temperature
- base_temperature = (heat_1 + cold_1)/2
-
- var/temp_step
- if (bodytemperature >= base_temperature)
- temp_step = (heat_1 - base_temperature)/4
-
- if (bodytemperature >= heat_1)
- bodytemp.icon_state = "temp4"
- else if (bodytemperature >= base_temperature + temp_step*3)
- bodytemp.icon_state = "temp3"
- else if (bodytemperature >= base_temperature + temp_step*2)
- bodytemp.icon_state = "temp2"
- else if (bodytemperature >= base_temperature + temp_step*1)
- bodytemp.icon_state = "temp1"
- else
- bodytemp.icon_state = "temp0"
-
- else if (bodytemperature < base_temperature)
- temp_step = (base_temperature - cold_1)/4
-
- if (bodytemperature <= cold_1)
- bodytemp.icon_state = "temp-4"
- else if (bodytemperature <= base_temperature - temp_step*3)
- bodytemp.icon_state = "temp-3"
- else if (bodytemperature <= base_temperature - temp_step*2)
- bodytemp.icon_state = "temp-2"
- else if (bodytemperature <= base_temperature - temp_step*1)
- bodytemp.icon_state = "temp-1"
- else
- bodytemp.icon_state = "temp0"
- return 1
+ return TRUE
/mob/living/carbon/human/handle_random_events()
// Puke if toxloss is too high
diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm
index e98e620a571..75804962e5f 100644
--- a/code/modules/mob/living/carbon/human/update_icons.dm
+++ b/code/modules/mob/living/carbon/human/update_icons.dm
@@ -65,7 +65,7 @@ There are several things that need to be remembered:
> There are also these special cases:
update_mutations() //handles updating your appearance for certain mutations. e.g TK head-glows
- UpdateDamageIcon() //handles damage overlays for brute/burn damage //(will rename this when I geta round to it)
+ update_damage_icon() //handles damage overlays for brute/burn damage //(will rename this when I geta round to it)
update_body() //Handles updating your mob's icon to reflect their gender/race/complexion etc
update_hair() //Handles updating your hair overlay (used to be update_face, but mouth and
...eyes were merged into update_body)
@@ -112,7 +112,7 @@ Please contact me on #coderbus IRC. ~Carn x
update_fire(FALSE)
update_surgery(FALSE)
update_bandages(FALSE)
- UpdateDamageIcon(FALSE)
+ update_damage_icon(FALSE)
return ..()
/mob/living/carbon/human/on_update_icon()
@@ -214,7 +214,7 @@ var/global/list/damage_icon_parts = list()
//DAMAGE OVERLAYS
//constructs damage icon for each organ from mask * damage field and saves it in our overlays_ lists
-/mob/living/carbon/human/UpdateDamageIcon(var/update_icons=1)
+/mob/living/carbon/human/update_damage_icon(var/update_icons=1)
// first check whether something actually changed about damage appearance
var/damage_appearance = ""
@@ -562,6 +562,8 @@ var/global/list/damage_icon_parts = list()
hud_used.hidden_inventory_update()
hud_used.persistant_inventory_update()
update_action_buttons()
- if(internals && internal)
- internals.icon_state = "internal1"
+ if(internal)
+ var/obj/screen/internals = get_hud_element(/decl/hud_element/internals)
+ if(internals)
+ internals.icon_state = "internal1"
queue_hand_rebuild()
diff --git a/code/modules/mob/living/carbon/internals.dm b/code/modules/mob/living/carbon/internals.dm
index c21f82f68b0..53912f7fbfe 100644
--- a/code/modules/mob/living/carbon/internals.dm
+++ b/code/modules/mob/living/carbon/internals.dm
@@ -4,5 +4,6 @@
/mob/living/carbon/set_internals(obj/item/tank/source, source_string)
..()
internal = source
+ var/obj/screen/internals = get_hud_element(/decl/hud_element/internals)
if(internals)
internals.icon_state = "internal[!!internal]"
diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm
deleted file mode 100644
index ff3b7588e00..00000000000
--- a/code/modules/mob/living/carbon/life.dm
+++ /dev/null
@@ -1,22 +0,0 @@
-/mob/living/carbon/Life()
- if(!..())
- return
-
- // Increase germ_level regularly
- if(germ_level < GERM_LEVEL_AMBIENT && prob(30)) //if you're just standing there, you shouldn't get more germs beyond an ambient level
- germ_level++
-
- if(stat != DEAD && !is_in_stasis())
- //Mutations and radiation
- handle_mutations_and_radiation()
-
- //Chemicals in the body
- handle_chemicals_in_body()
-
- //Random events (vomiting etc)
- handle_random_events()
-
- // eye, ear, brain damages
- handle_disabilities()
-
- . = 1
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/resist.dm b/code/modules/mob/living/carbon/resist.dm
index 0e7af051b09..5014bbb010d 100644
--- a/code/modules/mob/living/carbon/resist.dm
+++ b/code/modules/mob/living/carbon/resist.dm
@@ -33,6 +33,7 @@
return 1
/mob/living/carbon/proc/escape_handcuffs()
+
//This line represent a significant buff to grabs...
// We don't have to check the click cooldown because /mob/living/verb/resist() has done it for us, we can simply set the delay
setClickCooldown(100)
diff --git a/code/modules/mob/living/damage_procs.dm b/code/modules/mob/living/damage_procs.dm
index f3ad31eec72..c9e0c9064f7 100644
--- a/code/modules/mob/living/damage_procs.dm
+++ b/code/modules/mob/living/damage_procs.dm
@@ -24,15 +24,15 @@
switch(damagetype)
if(BRUTE)
- adjustBruteLoss(damage)
+ adjustBruteLoss(damage, do_update_health = TRUE)
if(BURN)
if(MUTATION_COLD_RESISTANCE in mutations)
- damage = 0
- adjustFireLoss(damage)
+ return
+ adjustFireLoss(damage, do_update_health = TRUE)
if(TOX)
- adjustToxLoss(damage)
+ adjustToxLoss(damage, do_update_health = TRUE)
if(OXY)
- adjustOxyLoss(damage)
+ adjustOxyLoss(damage, do_update_health = TRUE)
if(CLONE)
adjustCloneLoss(damage)
if(PAIN)
@@ -41,8 +41,6 @@
electrocute_act(damage, used_weapon, 1, def_zone)
if(IRRADIATE)
apply_radiation(damage)
-
- updatehealth()
return TRUE
@@ -64,7 +62,6 @@
/mob/living/apply_effect(var/effect = 0,var/effecttype = STUN, var/blocked = 0)
if(!effect || (blocked >= 100)) return FALSE
-
switch(effecttype)
if(STUN)
SET_STATUS_MAX(src, STAT_STUN, effect * blocked_mult(blocked))
@@ -81,7 +78,6 @@
SET_STATUS_MAX(src, STAT_BLURRY, effect * blocked_mult(blocked))
if(DROWSY)
SET_STATUS_MAX(src, STAT_DROWSY, effect * blocked_mult(blocked))
- updatehealth()
return TRUE
/mob/living/proc/apply_effects(var/stun = 0, var/weaken = 0, var/paralyze = 0, var/stutter = 0, var/eyeblur = 0, var/drowsy = 0, var/agony = 0, var/blocked = 0)
diff --git a/code/modules/mob/living/deity/deity.dm b/code/modules/mob/living/deity/deity.dm
index f3a5f2ff9dd..7a4ca607b43 100644
--- a/code/modules/mob/living/deity/deity.dm
+++ b/code/modules/mob/living/deity/deity.dm
@@ -5,8 +5,7 @@
icon_state = "egg"
pixel_x = -128
pixel_y = -128
- health = 100
- maxHealth = 100 //I dunno what to do with health at this point.
+ mob_default_max_health = 100
universal_understand = TRUE
mob_sort_value = 5
diff --git a/code/modules/mob/living/deity/deity_items.dm b/code/modules/mob/living/deity/deity_items.dm
index 9245a8dbbd0..967d973e0a4 100644
--- a/code/modules/mob/living/deity/deity_items.dm
+++ b/code/modules/mob/living/deity/deity_items.dm
@@ -34,11 +34,13 @@
/mob/living/deity/Destroy()
- for(var/cat in items_by_category)
- var/list/L = items_by_category[cat]
- L.Cut()
- items_by_category.Cut()
- for(var/i in items)
- qdel(items[i])
- items.Cut()
+ if(islist(items_by_category))
+ for(var/cat in items_by_category)
+ var/list/L = items_by_category[cat]
+ L.Cut()
+ items_by_category.Cut()
+ if(islist(items))
+ for(var/i in items)
+ qdel(items[i])
+ items.Cut()
. = ..()
\ No newline at end of file
diff --git a/code/modules/mob/living/deity/deity_phenomena.dm b/code/modules/mob/living/deity/deity_phenomena.dm
index 02533e6186c..b339a27cbc8 100644
--- a/code/modules/mob/living/deity/deity_phenomena.dm
+++ b/code/modules/mob/living/deity/deity_phenomena.dm
@@ -18,25 +18,27 @@
/mob/living/deity/proc/silence(var/amount)
if(!silenced)
to_chat(src, "You've been silenced! Your phenomenas are disabled!")
- var/obj/screen/intent/deity/SD = hud_used.action_intent
- SD.color = "#ff0000"
+ var/obj/screen/intent/deity/SD = get_hud_element(/decl/hud_element/action_intent)
+ if(istype(SD))
+ SD.color = "#ff0000"
silenced += amount
for(var/phenom in phenomenas) //Also make it so that you don't do cooldowns.
var/datum/phenomena/P = phenomenas[phenom]
if(P.refresh_time)
P.refresh_time += amount
-/mob/living/deity/Life()
+/mob/living/deity/handle_regular_status_updates()
. = ..()
if(.)
if(silenced > 0)
silenced--
if(!silenced)
to_chat(src, "You are no longer silenced.")
- var/obj/screen/intent/deity/SD = hud_used.action_intent
- SD.color = null
- if(power_per_regen < 0 || power < power_min)
- adjust_power(power_per_regen)
+ var/obj/screen/intent/deity/SD = get_hud_element(/decl/hud_element/action_intent)
+ if(istype(SD))
+ SD.color = null
+ if(power_per_regen < 0 || power < power_min)
+ adjust_power(power_per_regen)
/mob/living/deity/Destroy()
for(var/phenom in phenomenas)
@@ -67,8 +69,9 @@
for(var/mod in intent_list)
if(intent_list[mod] == P)
intent_list[mod] = null
- var/obj/screen/intent/deity/SD = hud_used.action_intent
- SD.update_text()
+ var/obj/screen/intent/deity/SD = get_hud_element(/decl/hud_element/action_intent)
+ if(istype(SD))
+ SD.update_text()
update_phenomenas()
update_phenomena_bindings()
if(selected == to_remove)
diff --git a/code/modules/mob/living/deity/menu/deity_nano.dm b/code/modules/mob/living/deity/menu/deity_nano.dm
index 63053cac5ed..c4d617d7e01 100644
--- a/code/modules/mob/living/deity/menu/deity_nano.dm
+++ b/code/modules/mob/living/deity/menu/deity_nano.dm
@@ -76,5 +76,6 @@
phenomena_bindings[++phenomena_bindings.len] = list("intent" = intent, "intent_data" = intent_data)
nano_data["bindings"] = phenomena_bindings
//Update the hud as well.
- var/obj/screen/intent/deity/SD = hud_used.action_intent
- SD.update_text()
\ No newline at end of file
+ var/obj/screen/intent/deity/SD = get_hud_element(/decl/hud_element/action_intent)
+ if(istype(SD))
+ SD.update_text()
\ No newline at end of file
diff --git a/code/modules/mob/living/deity/phenomena/communication.dm b/code/modules/mob/living/deity/phenomena/communication.dm
index 72876f3f9e9..e06bea85bc0 100644
--- a/code/modules/mob/living/deity/phenomena/communication.dm
+++ b/code/modules/mob/living/deity/phenomena/communication.dm
@@ -26,7 +26,7 @@
/datum/phenomena/point/activate(var/atom/a)
..()
if(!arrow)
- arrow = image('icons/mob/screen1.dmi', icon_state = "arrow", layer = POINTER_LAYER)
+ arrow = image('icons/mob/screen/arrow.dmi', icon_state = "arrow", layer = POINTER_LAYER)
var/turf/T = get_turf(a)
arrow.loc = T
var/list/view = view(7,T)
diff --git a/code/modules/mob/living/deity/phenomena/conjuration.dm b/code/modules/mob/living/deity/phenomena/conjuration.dm
index 2176486f697..23e9b69fc46 100644
--- a/code/modules/mob/living/deity/phenomena/conjuration.dm
+++ b/code/modules/mob/living/deity/phenomena/conjuration.dm
@@ -59,7 +59,7 @@
L.take_overall_damage(rand(5,30),0,0,0,"blunt intrument") //Actual spell does 5d10 but maaaybe too much.
playsound(get_turf(L), 'sound/effects/bamf.ogg', 100, 1)
to_chat(L, "Something hard hits you!")
- if(L.health < L.maxHealth/2) //If it reduces past 50%
+ if(L.current_health < L.get_max_health()/2) //If it reduces past 50%
var/obj/effect/rift/R = new(get_turf(L))
L.visible_message("\The [L] is quickly sucked into \a [R]!")
L.forceMove(R)
diff --git a/code/modules/mob/living/inventory.dm b/code/modules/mob/living/inventory.dm
index 2a8cac458bc..d71b59c3232 100644
--- a/code/modules/mob/living/inventory.dm
+++ b/code/modules/mob/living/inventory.dm
@@ -57,14 +57,15 @@
var/last_slot = get_active_held_item_slot()
if(slot != last_slot && (slot in get_held_item_slots()))
_held_item_slot_selected = slot
- for(var/obj/screen/inventory/hand in hud_used?.hand_hud_objects)
- hand.cut_overlay("hand_selected")
- if(hand.slot_id == slot)
- hand.add_overlay("hand_selected")
- hand.compile_overlays()
- var/obj/item/I = get_active_hand()
- if(istype(I))
- I.on_active_hand()
+ if(istype(hud_used))
+ for(var/obj/screen/inventory/hand in hud_used.hand_hud_objects)
+ hand.cut_overlay("hand_selected")
+ if(hand.slot_id == slot)
+ hand.add_overlay("hand_selected")
+ hand.compile_overlays()
+ var/obj/item/I = get_active_hand()
+ if(istype(I))
+ I.on_active_hand()
// Defer proc for the sake of delimbing root limbs with multiple graspers (serpentid)
/mob/living/proc/queue_hand_rebuild()
diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm
index 1185eec50a1..054e78d4dd6 100644
--- a/code/modules/mob/living/life.dm
+++ b/code/modules/mob/living/life.dm
@@ -2,9 +2,11 @@
set invisibility = FALSE
set background = BACKGROUND_ENABLED
- ..()
+ . = ..()
+ if(. == PROCESS_KILL)
+ return
- if (HasMovementHandler(/datum/movement_handler/mob/transformation/))
+ if (HasMovementHandler(/datum/movement_handler/mob/transformation))
return
// update the current life tick, can be used to e.g. only do something every 4 ticks
@@ -20,38 +22,47 @@
//Handle temperature/pressure differences between body and environment
handle_environment(loc.return_air())
-
- if(stat != DEAD && !is_in_stasis())
- //Breathing, if applicable
- handle_breathing()
- handle_nutrition_and_hydration()
- handle_immunity()
- //Body temperature adjusts itself (self-regulation)
- stabilize_body_temperature()
-
- // human/handle_regular_status_updates() needs a cleanup, as blindness should be handled in handle_disabilities()
handle_regular_status_updates() // Status & health update, are we dead or alive etc.
handle_stasis()
if(stat != DEAD)
+ if(!is_in_stasis())
+ . = handle_living_non_stasis_processes()
aura_check(AURA_TYPE_LIFE)
- //Check if we're on fire
- handle_fire()
-
for(var/obj/item/grab/G in get_active_grabs())
G.Process()
+ //Check if we're on fire
+ handle_fire()
handle_actions()
-
UpdateLyingBuckledAndVerbStatus()
-
handle_regular_hud_updates()
-
handle_status_effects()
return 1
+/mob/living/proc/handle_living_non_stasis_processes()
+ // hungy
+ handle_nutrition_and_hydration()
+ // Breathing, if applicable
+ handle_breathing()
+ // Mutations and radiation
+ handle_mutations_and_radiation()
+ // Chemicals in the body
+ handle_chemicals_in_body()
+ // Random events (vomiting etc)
+ handle_random_events()
+ // eye, ear, brain damages
+ handle_disabilities()
+ handle_immunity()
+ //Body temperature adjusts itself (self-regulation)
+ stabilize_body_temperature()
+ // Only handle AI stuff if we're not being played.
+ if(!key)
+ handle_legacy_ai()
+ return TRUE
+
/mob/living/proc/experiences_hunger_and_thirst()
return TRUE
@@ -67,6 +78,10 @@
return my_species.hunger_factor
return 0
+// Used to handle non-datum AI.
+/mob/living/proc/handle_legacy_ai()
+ return
+
/mob/living/proc/handle_nutrition_and_hydration()
SHOULD_CALL_PARENT(TRUE)
if(!experiences_hunger_and_thirst())
@@ -130,14 +145,14 @@
damage = FLOOR(damage * (my_species ? my_species.get_radiation_mod(src) : 1))
if(damage)
- adjustToxLoss(damage * RADIATION_SPEED_COEFFICIENT)
immunity = max(0, immunity - damage * 15 * RADIATION_SPEED_COEFFICIENT)
- updatehealth()
+ adjustToxLoss(damage * RADIATION_SPEED_COEFFICIENT, do_update_health = TRUE)
var/list/limbs = get_external_organs()
if(!isSynthetic() && LAZYLEN(limbs))
var/obj/item/organ/external/O = pick(limbs)
if(istype(O))
O.add_autopsy_data("Radiation Poisoning", damage)
+
#undef RADIATION_SPEED_COEFFICIENT
// Get valid, unique reagent holders for metabolizing. Avoids metabolizing the same holder twice in a tick.
@@ -183,9 +198,6 @@
if(LAZYACCESS(chem_doses, T) <= 0)
LAZYREMOVE(chem_doses, T)
- if(apply_chemical_effects())
- updatehealth()
-
return TRUE
/mob/living/proc/apply_chemical_effects()
@@ -254,37 +266,84 @@
//This updates the health and status of the mob (conscious, unconscious, dead)
/mob/living/proc/handle_regular_status_updates()
- updatehealth()
- if(stat != DEAD)
- if(HAS_STATUS(src, STAT_PARA))
- set_stat(UNCONSCIOUS)
- else if (status_flags & FAKEDEATH)
- set_stat(UNCONSCIOUS)
- else
- set_stat(CONSCIOUS)
+
+ SHOULD_CALL_PARENT(TRUE)
+
+ // Check if we are (or should be) dead at this point.
+ update_health()
+
+ if(!handle_some_updates())
+ return FALSE
+
+ // Godmode just skips most of this processing.
+ if(status_flags & GODMODE)
+ set_stat(CONSCIOUS)
+ germ_level = 0
return TRUE
+ // Increase germ_level regularly
+ if(germ_level < GERM_LEVEL_AMBIENT && prob(30)) //if you're just standing there, you shouldn't get more germs beyond an ambient level
+ germ_level++
+ // If you're dirty, your gloves will become dirty, too.
+ var/obj/item/gloves = get_equipped_item(slot_gloves_str)
+ if(gloves && germ_level > gloves.germ_level && prob(10))
+ gloves.germ_level++
+
+ // If we're dead, don't continue further.
+ if(stat == DEAD)
+ return FALSE
+
+ // Handle some general state updates.
+ if(HAS_STATUS(src, STAT_PARA))
+ set_stat(UNCONSCIOUS)
+ else if (status_flags & FAKEDEATH)
+ set_stat(UNCONSCIOUS)
+ else
+ set_stat(CONSCIOUS)
+ return TRUE
+
/mob/living/proc/handle_disabilities()
handle_impaired_vision()
handle_impaired_hearing()
/mob/living/proc/handle_impaired_vision()
- if((sdisabilities & BLINDED) || stat) //blindness from disability or unconsciousness doesn't get better on its own
+ SHOULD_CALL_PARENT(TRUE)
+ if(stat == DEAD)
+ SET_STATUS_MAX(src, STAT_BLIND, 0)
+ if(stat != CONSCIOUS && (sdisabilities & BLINDED)) //blindness from disability or unconsciousness doesn't get better on its own
SET_STATUS_MAX(src, STAT_BLIND, 2)
+ else
+ return TRUE
+ return FALSE
/mob/living/proc/handle_impaired_hearing()
if((sdisabilities & DEAFENED) || stat) //disabled-deaf, doesn't get better on its own
SET_STATUS_MAX(src, STAT_TINNITUS, 2)
+/mob/living/proc/should_do_hud_updates()
+ return client
+
//this handles hud updates. Calls update_vision() and handle_hud_icons()
/mob/living/proc/handle_regular_hud_updates()
- if(!client) return 0
-
+ SHOULD_CALL_PARENT(TRUE)
+ if(machine && machine.check_eye(src) < 0)
+ reset_view(null)
+ if(!should_do_hud_updates())
+ return FALSE
handle_hud_icons()
handle_vision()
handle_low_light_vision()
-
- return 1
+ if(hud_used)
+ hud_used.update_icons()
+ if(stat != DEAD)
+ if(is_blind())
+ overlay_fullscreen("blind", /obj/screen/fullscreen/blind)
+ else
+ clear_fullscreen("blind")
+ set_fullscreen(disabilities & NEARSIGHTED, "impaired", /obj/screen/fullscreen/impaired, 1)
+ set_fullscreen(GET_STATUS(src, STAT_BLURRY), "blurry", /obj/screen/fullscreen/blurry)
+ set_fullscreen(GET_STATUS(src, STAT_DRUGGY), "high", /obj/screen/fullscreen/high)
+ return TRUE
/mob/living/proc/handle_low_light_vision()
@@ -315,10 +374,8 @@
/mob/living/proc/handle_vision()
update_sight()
-
if(stat == DEAD)
return
-
if(is_blind())
overlay_fullscreen("blind", /obj/screen/fullscreen/blind)
else
@@ -326,9 +383,7 @@
set_fullscreen(disabilities & NEARSIGHTED, "impaired", /obj/screen/fullscreen/impaired, 1)
set_fullscreen(GET_STATUS(src, STAT_BLURRY), "blurry", /obj/screen/fullscreen/blurry)
set_fullscreen(GET_STATUS(src, STAT_DRUGGY), "high", /obj/screen/fullscreen/high)
-
set_fullscreen(stat == UNCONSCIOUS, "blackout", /obj/screen/fullscreen/blackout)
-
if(machine)
var/viewflags = machine.check_eye(src)
if(viewflags < 0)
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 3140c867205..e8fc51c240a 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -1,5 +1,6 @@
/mob/living/Initialize()
+ current_health = get_max_health()
original_fingerprint_seed = sequential_id(/mob)
fingerprint = md5(num2text(original_fingerprint_seed))
original_genetic_seed = sequential_id(/mob)
@@ -185,22 +186,40 @@ default behaviour is:
/mob/living/verb/succumb()
set hidden = 1
- if ((src.health < src.maxHealth/2)) // Health below half of maxhealth.
- src.adjustBrainLoss(src.health + src.maxHealth * 2) // Deal 2x health in BrainLoss damage, as before but variable.
- updatehealth()
- to_chat(src, "You have given up life and succumbed to death.")
+ var/current_max_health = get_max_health()
+ if (current_health < (current_max_health/2)) // Health below half of maxhealth.
+ adjustBrainLoss(current_max_health * 2, do_update_health = TRUE) // Deal 2x health in BrainLoss damage, as before but variable.
+ to_chat(src, SPAN_NOTICE("You have given up life and succumbed to death."))
/mob/living/proc/update_body(var/update_icons=1)
if(update_icons)
queue_icon_update()
-/mob/living/proc/updatehealth()
+/mob/living/proc/update_health_hud()
+ if(!client || !hud_used)
+ return
+ hud_used.update_health_hud()
+
+/mob/living/proc/should_be_dead()
+ return current_health <= 0
+
+/mob/living/proc/get_total_life_damage()
+ return (getOxyLoss()+getToxLoss()+getFireLoss()+getBruteLoss()+getCloneLoss()+getHalLoss())
+
+/mob/living/proc/update_health()
+ SHOULD_CALL_PARENT(TRUE)
if(status_flags & GODMODE)
- health = maxHealth
+ current_health = get_max_health()
set_stat(CONSCIOUS)
- else
- health = maxHealth - getOxyLoss() - getToxLoss() - getFireLoss() - getBruteLoss() - getCloneLoss() - getHalLoss()
+ return
+ var/max_health = get_max_health()
+ current_health = clamp(max_health-get_total_life_damage(), -(max_health), max_health)
+ if(stat != DEAD && should_be_dead())
+ death()
+ if(!QDELETED(src)) // death() may delete or remove us
+ set_status(STAT_BLIND, 1)
+ set_status(STAT_SILENCE, 0)
//This proc is used for mobs which are affected by pressure to calculate the amount of pressure that actually
//affects them once clothing is factored in. ~Errorage
@@ -231,19 +250,24 @@ default behaviour is:
return btemperature
+/mob/living/proc/setBruteLoss(var/amount)
+ adjustBruteLoss((amount * 0.5)-getBruteLoss())
+
/mob/living/proc/getBruteLoss()
- return maxHealth - health
+ return get_max_health() - current_health
-/mob/living/proc/adjustBruteLoss(var/amount)
- if (status_flags & GODMODE)
- return
- health = clamp(health - amount, 0, maxHealth)
+/mob/living/proc/adjustBruteLoss(var/amount, var/do_update_health = FALSE)
+ SHOULD_CALL_PARENT(TRUE)
+ if(do_update_health)
+ update_health()
/mob/living/proc/getOxyLoss()
return 0
-/mob/living/proc/adjustOxyLoss(var/amount)
- return
+/mob/living/proc/adjustOxyLoss(var/damage, var/do_update_health)
+ SHOULD_CALL_PARENT(TRUE)
+ if(do_update_health)
+ update_health()
/mob/living/proc/setOxyLoss(var/amount)
return
@@ -251,8 +275,8 @@ default behaviour is:
/mob/living/proc/getToxLoss()
return 0
-/mob/living/proc/adjustToxLoss(var/amount)
- adjustBruteLoss(amount * 0.5)
+/mob/living/proc/adjustToxLoss(var/amount, var/do_update_health)
+ adjustBruteLoss(amount * 0.5, do_update_health)
/mob/living/proc/setToxLoss(var/amount)
adjustBruteLoss((amount * 0.5)-getBruteLoss())
@@ -260,8 +284,8 @@ default behaviour is:
/mob/living/proc/getFireLoss()
return
-/mob/living/proc/adjustFireLoss(var/amount)
- adjustBruteLoss(amount * 0.5)
+/mob/living/proc/adjustFireLoss(var/amount, var/do_update_health)
+ adjustBruteLoss(amount * 0.5, do_update_health)
/mob/living/proc/setFireLoss(var/amount)
adjustBruteLoss((amount * 0.5)-getBruteLoss())
@@ -278,8 +302,10 @@ default behaviour is:
/mob/living/proc/getBrainLoss()
return 0
-/mob/living/proc/adjustBrainLoss(var/amount)
- return
+/mob/living/proc/adjustBrainLoss(var/amount, var/do_update_health)
+ SHOULD_CALL_PARENT(TRUE)
+ if(do_update_health)
+ update_health()
/mob/living/proc/setBrainLoss(var/amount)
return
@@ -293,11 +319,19 @@ default behaviour is:
/mob/living/proc/adjustCloneLoss(var/amount)
return
-/mob/living/proc/getMaxHealth()
- return maxHealth
+/mob/living/proc/get_health_ratio() // ratio might be the wrong word
+ return current_health/get_max_health()
-/mob/living/proc/setMaxHealth(var/newMaxHealth)
- maxHealth = newMaxHealth
+/mob/living/proc/get_health_percent(var/sigfig = 1)
+ return round(get_health_ratio()*100, sigfig)
+
+/mob/living/proc/get_max_health()
+ return mob_default_max_health
+
+/mob/living/proc/set_max_health(var/val, var/skip_health_update = FALSE)
+ mob_default_max_health = val
+ if(!skip_health_update)
+ update_health()
// ++++ROCKDTBEN++++ MOB PROCS //END
@@ -346,28 +380,26 @@ default behaviour is:
// heal ONE external organ, organ gets randomly selected from damaged ones.
/mob/living/proc/heal_organ_damage(var/brute, var/burn, var/affect_robo = FALSE)
adjustBruteLoss(-brute)
- adjustFireLoss(-burn)
- src.updatehealth()
+ adjustFireLoss(-burn, do_update_health = TRUE)
// damage ONE external organ, organ gets randomly selected from damaged ones.
/mob/living/proc/take_organ_damage(var/brute = 0, var/burn = 0, var/bypass_armour = FALSE, var/override_droplimb)
- if(!(status_flags & GODMODE))
- adjustBruteLoss(brute)
- adjustFireLoss(burn)
- updatehealth()
+ if(status_flags & GODMODE)
+ return
+ adjustBruteLoss(brute)
+ adjustFireLoss(burn, do_update_health = TRUE)
// heal MANY external organs, in random order
/mob/living/proc/heal_overall_damage(var/brute, var/burn)
adjustBruteLoss(-brute)
- adjustFireLoss(-burn)
- src.updatehealth()
+ adjustFireLoss(-burn, do_update_health = TRUE)
// damage MANY external organs, in random order
/mob/living/proc/take_overall_damage(var/brute, var/burn, var/used_weapon = null)
- if(status_flags & GODMODE) return 0 //godmode
+ if(status_flags & GODMODE)
+ return 0
adjustBruteLoss(brute)
- adjustFireLoss(burn)
- src.updatehealth()
+ adjustFireLoss(burn, do_update_health = TRUE)
/mob/living/proc/restore_all_organs()
return
@@ -470,7 +502,7 @@ default behaviour is:
brain.update_icon()
..(repair_brain)
-/mob/living/proc/UpdateDamageIcon()
+/mob/living/proc/update_damage_icon()
return
/mob/living/handle_grabs_after_move(var/turf/old_loc, var/direction)
@@ -1120,11 +1152,16 @@ default behaviour is:
/mob/living/get_speech_bubble_state_modifier()
return isSynthetic() ? "synth" : ..()
-/mob/living/proc/is_on_special_ability_cooldown()
+/mob/proc/is_on_special_ability_cooldown()
+ return FALSE
+
+/mob/living/is_on_special_ability_cooldown()
return world.time < next_special_ability
/mob/living/proc/set_special_ability_cooldown(var/amt)
next_special_ability = max(next_special_ability, world.time+amt)
+ if(hud_used)
+ hud_used.set_hud_cooldown((world.time - next_special_ability)-1) // -1 so it visually resets one tick after cooldown.
/mob/living/proc/get_seconds_until_next_special_ability_string()
return ticks2readable(next_special_ability - world.time)
diff --git a/code/modules/mob/living/living_bodytemp.dm b/code/modules/mob/living/living_bodytemp.dm
index 58a184891ab..6c052810303 100644
--- a/code/modules/mob/living/living_bodytemp.dm
+++ b/code/modules/mob/living/living_bodytemp.dm
@@ -7,9 +7,9 @@
return TRUE
/mob/living/proc/get_bodytemperature_difference()
- var/decl/species/my_species = get_species()
- if(my_species)
- return (my_species.body_temperature - bodytemperature)
+ var/ideal_bodytemp = get_ideal_bodytemp()
+ if(!isnull(ideal_bodytemp))
+ return (ideal_bodytemp - bodytemperature)
return 0
/mob/living/proc/stabilize_body_temperature()
diff --git a/code/modules/mob/living/living_breath.dm b/code/modules/mob/living/living_breath.dm
index 06a3150811d..904800aefc7 100644
--- a/code/modules/mob/living/living_breath.dm
+++ b/code/modules/mob/living/living_breath.dm
@@ -106,6 +106,7 @@
else
check_for_airtight_internals()
var/obj/item/tank/new_internals = get_internals()
+ var/obj/screen/internals = get_hud_element(/decl/hud_element/internals)
if(internals && old_internals != new_internals)
internals.icon_state = "internal[!!new_internals]"
if(istype(new_internals))
diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm
index 05a3c4c7670..77f6d443339 100644
--- a/code/modules/mob/living/living_defense.dm
+++ b/code/modules/mob/living/living_defense.dm
@@ -218,16 +218,14 @@
// End BS12 momentum-transfer code.
/mob/living/attack_generic(var/mob/user, var/damage, var/attack_message)
-
if(!damage || !istype(user))
return
- adjustBruteLoss(damage)
admin_attack_log(user, src, "Attacked", "Was attacked", "attacked")
src.visible_message("\The [user] has [attack_message] \the [src]!")
+ adjustBruteLoss(damage, do_update_health = TRUE)
user.do_attack_animation(src)
- spawn(1) updatehealth()
return 1
/mob/living/proc/IgniteMob()
@@ -297,7 +295,7 @@
/mob/living/lava_act(datum/gas_mixture/air, temperature, pressure)
fire_act(air, temperature)
FireBurn(0.4*vsc.fire_firelevel_multiplier, temperature, pressure)
- . = (health <= 0) ? ..() : FALSE
+ . = (current_health <= 0) ? ..() : FALSE
// called when something steps onto a mob
// this handles mulebots and vehicles
diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm
index 4020796aa03..7eab17ec15a 100644
--- a/code/modules/mob/living/living_defines.dm
+++ b/code/modules/mob/living/living_defines.dm
@@ -5,8 +5,8 @@
abstract_type = /mob/living
//Health and life related vars
- var/maxHealth = 100 //Maximum health that should be possible.
- var/health = 100 //A mob's health
+ var/mob_default_max_health = 100 //Maximum health that should be possible.
+ var/current_health = INFINITY // A mob's current health. Set by update_health(). Defaults to INFINITY so mobs don't die on init.
var/hud_updateflag = 0
diff --git a/code/modules/mob/living/living_grabs.dm b/code/modules/mob/living/living_grabs.dm
index e8eda8cec1d..fc85822943c 100644
--- a/code/modules/mob/living/living_grabs.dm
+++ b/code/modules/mob/living/living_grabs.dm
@@ -41,7 +41,8 @@
face_atom(target)
var/obj/item/grab/grab
- if(ispath(grab_tag, /decl/grab) && can_grab(target, get_target_zone(), defer_hand = defer_hand) && target.can_be_grabbed(src, get_target_zone(), defer_hand))
+ var/target_zone = get_target_zone()
+ if(ispath(grab_tag, /decl/grab) && can_grab(target, target_zone, defer_hand = defer_hand) && target.can_be_grabbed(src, target_zone, defer_hand))
grab = new /obj/item/grab(src, target, grab_tag, defer_hand)
if(QDELETED(grab))
diff --git a/code/modules/mob/living/living_organs.dm b/code/modules/mob/living/living_organs.dm
index 7ab280144bf..7881fb555df 100644
--- a/code/modules/mob/living/living_organs.dm
+++ b/code/modules/mob/living/living_organs.dm
@@ -21,16 +21,17 @@
return LAZYLEN(get_internal_organs()) > 0
//Can be called when we want to add an organ in a detached state or an attached state.
-/mob/living/proc/add_organ(var/obj/item/organ/O, var/obj/item/organ/external/affected = null, var/in_place = FALSE, var/update_icon = TRUE, var/detached = FALSE)
+/mob/living/proc/add_organ(var/obj/item/organ/O, var/obj/item/organ/external/affected = null, var/in_place = FALSE, var/update_icon = TRUE, var/detached = FALSE, var/skip_health_update = FALSE)
. = O.do_install(src, affected, in_place, update_icon, detached)
//Only run install effects if we're not detached and we're not adding in place
if(!in_place && !(O.status & ORGAN_CUT_AWAY))
on_gained_organ(O)
- updatehealth()
+ if(!skip_health_update)
+ update_health()
return TRUE
//Can be called when the organ is detached or attached.
-/mob/living/proc/remove_organ(var/obj/item/organ/O, var/drop_organ = TRUE, var/detach = FALSE, var/ignore_children = FALSE, var/in_place = FALSE, var/update_icon = TRUE)
+/mob/living/proc/remove_organ(var/obj/item/organ/O, var/drop_organ = TRUE, var/detach = FALSE, var/ignore_children = FALSE, var/in_place = FALSE, var/update_icon = TRUE, var/skip_health_update = FALSE)
//Only run effects if we're not already detached, and we're not doing a in-place removal
if(!in_place && !(O.status & ORGAN_CUT_AWAY)) //Gotta check the flag here, because of prosthetics handling detached state differently
on_lost_organ(O)
@@ -41,7 +42,8 @@
if(client)
client.screen -= O
- updatehealth()
+ if(!skip_health_update)
+ update_health()
if(drop_organ)
var/drop_loc = get_turf(src)
diff --git a/code/modules/mob/living/living_powers.dm b/code/modules/mob/living/living_powers.dm
index e3dcb6505eb..49d07235d00 100644
--- a/code/modules/mob/living/living_powers.dm
+++ b/code/modules/mob/living/living_powers.dm
@@ -67,6 +67,6 @@
to_chat(target,"\The [src] scrapes your flesh from your bones!")
to_chat(src,"You feed hungrily off \the [target]'s flesh.")
target.adjustBruteLoss(25)
- if(target.getBruteLoss() < -target.maxHealth)
+ if(target.getBruteLoss() < -target.get_max_health())
target.gib()
src.adjustBruteLoss(-25)
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm
index f78d5049548..dabfafbc503 100644
--- a/code/modules/mob/living/silicon/ai/ai.dm
+++ b/code/modules/mob/living/silicon/ai/ai.dm
@@ -56,7 +56,11 @@ var/global/list/ai_verbs_default = list(
density = TRUE
status_flags = CANSTUN|CANPARALYSE|CANPUSH
shouldnt_see = list(/obj/effect/rune)
- maxHealth = 200
+ mob_default_max_health = 200
+
+ silicon_camera = /obj/item/camera/siliconcam/ai_camera
+ silicon_radio = /obj/item/radio/headset/heads/ai_integrated
+
var/obj/machinery/camera/camera = null
var/list/connected_robots = list()
var/aiRestorePowerRoutine = 0
@@ -65,9 +69,6 @@ var/global/list/ai_verbs_default = list(
var/icon/holo_icon_longrange //Yellow hologram.
var/holo_icon_malf = FALSE // for new hologram system
var/obj/item/multitool/aiMulti = null
-
- silicon_camera = /obj/item/camera/siliconcam/ai_camera
- silicon_radio = /obj/item/radio/headset/heads/ai_integrated
var/obj/item/radio/headset/heads/ai_integrated/ai_radio
var/camera_light_on = 0 //Defines if the AI toggled the light on the camera it's looking through.
diff --git a/code/modules/mob/living/silicon/ai/ai_damage.dm b/code/modules/mob/living/silicon/ai/ai_damage.dm
index 087e8ecafcb..56a09030033 100644
--- a/code/modules/mob/living/silicon/ai/ai_damage.dm
+++ b/code/modules/mob/living/silicon/ai/ai_damage.dm
@@ -12,17 +12,27 @@
/mob/living/silicon/ai/getOxyLoss()
return oxyloss
-/mob/living/silicon/ai/adjustFireLoss(var/amount)
+/mob/living/silicon/ai/adjustFireLoss(var/amount, var/do_update_health)
if(status_flags & GODMODE) return
- fireloss = max(0, fireloss + min(amount, health))
+ fireloss = max(0, fireloss + min(amount, current_health))
+ if(do_update_health)
+ update_health()
-/mob/living/silicon/ai/adjustBruteLoss(var/amount)
- if(status_flags & GODMODE) return
- bruteloss = max(0, bruteloss + min(amount, health))
+/mob/living/silicon/ai/adjustBruteLoss(var/amount, var/do_update_health)
+ if(!(status_flags & GODMODE))
+ bruteloss = max(0, bruteloss + min(amount, current_health))
+ ..()
-/mob/living/silicon/ai/adjustOxyLoss(var/amount)
- if(status_flags & GODMODE) return
- oxyloss = max(0, oxyloss + min(amount, maxHealth - oxyloss))
+/mob/living/silicon/ai/adjustOxyLoss(var/damage, var/do_update_health)
+ if(!(status_flags & GODMODE))
+ oxyloss = max(0, oxyloss + min(damage, get_max_health() - oxyloss))
+ ..()
+
+/mob/living/silicon/ai/setBruteLoss(var/amount)
+ if(status_flags & GODMODE)
+ bruteloss = 0
+ return
+ bruteloss = max(0, amount)
/mob/living/silicon/ai/setFireLoss(var/amount)
if(status_flags & GODMODE)
@@ -36,13 +46,10 @@
return
oxyloss = max(0, amount)
-/mob/living/silicon/ai/updatehealth()
+/mob/living/silicon/ai/update_health()
+ ..()
if(status_flags & GODMODE)
- health = maxHealth
- set_stat(CONSCIOUS)
setOxyLoss(0)
- else
- health = maxHealth - getFireLoss() - getBruteLoss() // Oxyloss is not part of health as it represents AIs backup power. AI is immune against ToxLoss as it is machine.
/mob/living/silicon/ai/rejuvenate()
..()
@@ -50,8 +57,5 @@
// Returns percentage of AI's remaining backup capacitor charge (maxhealth - oxyloss).
/mob/living/silicon/ai/proc/backup_capacitor()
- return ((getOxyLoss() - maxHealth) / maxHealth) * (-100)
-
-// Returns percentage of AI's remaining hardware integrity (maxhealth - (bruteloss + fireloss))
-/mob/living/silicon/ai/proc/hardware_integrity()
- return (health / maxHealth) * 100
\ No newline at end of file
+ var/current_max_health = get_max_health()
+ return ((getOxyLoss() - current_max_health) / current_max_health) * (-100)
diff --git a/code/modules/mob/living/silicon/ai/life.dm b/code/modules/mob/living/silicon/ai/life.dm
index 06d5c557536..68df276f1d2 100644
--- a/code/modules/mob/living/silicon/ai/life.dm
+++ b/code/modules/mob/living/silicon/ai/life.dm
@@ -1,50 +1,35 @@
-/mob/living/silicon/ai/Life()
+/mob/living/silicon/ai/should_be_dead()
+ return get_health_percent() <= 0 || backup_capacitor() <= 0
- SHOULD_CALL_PARENT(FALSE)
-
- if (src.stat == DEAD)
- return
-
- if (src.stat!=CONSCIOUS)
+/mob/living/silicon/ai/handle_regular_status_updates()
+ . = ..()
+ if(stat != CONSCIOUS)
src.cameraFollow = null
src.reset_view(null)
- src.updatehealth()
-
- if ((hardware_integrity() <= 0) || (backup_capacitor() <= 0))
- death()
- return
+/mob/living/silicon/ai/update_lying()
+ lying = FALSE
+/mob/living/silicon/ai/handle_living_non_stasis_processes()
+ . = ..()
// If our powersupply object was destroyed somehow, create new one.
if(!psupply)
create_powersupply()
-
- lying = 0 // Handle lying down
-
// We aren't shut down, and we lack external power. Try to fix it using the restoration routine.
if (!self_shutdown && !has_power(0))
// AI's restore power routine is not running. Start it automatically.
if(aiRestorePowerRoutine == AI_RESTOREPOWER_IDLE)
aiRestorePowerRoutine = AI_RESTOREPOWER_STARTING
handle_power_failure()
-
- handle_impaired_vision()
update_power_usage()
handle_power_oxyloss()
- update_sight()
-
process_queued_alarms()
- handle_regular_hud_updates()
-
switch(src.sensor_mode)
if (SEC_HUD)
process_sec_hud(src,0,src.eyeobj,get_computer_network())
if (MED_HUD)
process_med_hud(src,0,src.eyeobj,get_computer_network())
-
process_os()
- handle_status_effects()
-
if(controlling_drone && stat != CONSCIOUS)
controlling_drone.release_ai_control("WARNING: Primary control loop failure. Session terminated.")
diff --git a/code/modules/mob/living/silicon/pai/death.dm b/code/modules/mob/living/silicon/pai/death.dm
index 6e2db95e39c..81d63dea087 100644
--- a/code/modules/mob/living/silicon/pai/death.dm
+++ b/code/modules/mob/living/silicon/pai/death.dm
@@ -8,6 +8,6 @@
fold()
if(mind)
qdel(mind)
- ..(gibbed, deathmessage, "You have suffered a critical system failure, and are dead.")
+ ..(gibbed, "gives one shrill beep before falling lifeless.", "You have suffered a critical system failure, and are dead.")
ghostize()
qdel(src)
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/pai/life.dm b/code/modules/mob/living/silicon/pai/life.dm
index f3697bfefe9..c59c817f66a 100644
--- a/code/modules/mob/living/silicon/pai/life.dm
+++ b/code/modules/mob/living/silicon/pai/life.dm
@@ -1,40 +1,19 @@
-/mob/living/silicon/pai/Life()
-
- SHOULD_CALL_PARENT(FALSE)
-
- if (src.stat == DEAD)
- return
-
- if(src.cable)
- if(get_dist(src, cable) > 1)
- visible_message( \
- message = SPAN_NOTICE("The data cable rapidly retracts back into its spool."), \
- blind_message = SPAN_NOTICE("You hear a click and the sound of wire spooling rapidly."))
- QDEL_NULL(cable)
-
- handle_regular_hud_updates()
-
- if(src.secHUD == 1)
- process_sec_hud(src, 1, network = get_computer_network())
-
- if(src.medHUD == 1)
- process_med_hud(src, 1, network = get_computer_network())
-
+/mob/living/silicon/pai/handle_regular_hud_updates()
+ . = ..()
+ if(.)
+ if(src.secHUD == 1)
+ process_sec_hud(src, 1, network = get_computer_network())
+ if(src.medHUD == 1)
+ process_med_hud(src, 1, network = get_computer_network())
+
+/mob/living/silicon/pai/handle_regular_status_updates()
+ . = ..()
process_os() // better safe than sorry, in case some pAI has it
-
- if(silence_time)
- if(world.timeofday >= silence_time)
- silence_time = null
- to_chat(src, SPAN_NOTICE("Communication circuit reinitialized. Speech and messaging functionality restored."))
-
- handle_status_effects()
-
- if(health <= 0)
- death(null,"gives one shrill beep before falling lifeless.")
-
-/mob/living/silicon/pai/updatehealth()
- if(status_flags & GODMODE)
- health = 100
- set_stat(CONSCIOUS)
- else
- health = 100 - getBruteLoss() - getFireLoss()
\ No newline at end of file
+ if(src.cable && get_dist(src, cable) > 1)
+ visible_message( \
+ message = SPAN_NOTICE("The data cable rapidly retracts back into its spool."), \
+ blind_message = SPAN_NOTICE("You hear a click and the sound of wire spooling rapidly."))
+ QDEL_NULL(cable)
+
+/mob/living/silicon/pai/death(gibbed, deathmessage, show_dead_message)
+ return ..(deathmessage = "gives one shrill beep before falling lifeless.")
diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm
index f7ab6c949c2..9a8385fe707 100644
--- a/code/modules/mob/living/silicon/pai/pai.dm
+++ b/code/modules/mob/living/silicon/pai/pai.dm
@@ -24,16 +24,18 @@ var/global/list/possible_say_verbs = list(
icon = 'icons/mob/robots/pai/pai_drone.dmi'
icon_state = ICON_STATE_WORLD
mob_sort_value = 3
- hud_type = /datum/hud/pai
+ hud_used = /datum/hud/pai
emote_type = 2 // pAIs emotes are heard, not seen, so they can be seen through a container (eg. person)
pass_flags = PASS_FLAG_TABLE
mob_size = MOB_SIZE_SMALL
+ mob_default_max_health = 100
can_pull_size = ITEM_SIZE_SMALL
can_pull_mobs = MOB_PULL_SMALLER
holder_type = /obj/item/holder
idcard = /obj/item/card/id
silicon_radio = null // pAIs get their radio from the card they belong to.
+ mob_default_max_health = 100
os_type = /datum/extension/interactive/os/silicon/small
starting_stock_parts = list(
@@ -58,8 +60,6 @@ var/global/list/possible_say_verbs = list(
var/pai_law0 = "Serve your master."
var/pai_laws // String for additional operating instructions our master might give us
- var/silence_time // Timestamp when we were silenced (normally via EMP burst), set to null after silence has faded
-
// Various software-specific vars
var/secHUD = 0 // Toggles whether the Security HUD is active or not
@@ -83,7 +83,12 @@ var/global/list/possible_say_verbs = list(
set_extension(src, /datum/extension/base_icon_state, icon_state)
status_flags |= NO_ANTAG
- card = loc
+ if(!card && istype(loc, /obj/item/paicard))
+ card = loc
+ if(istype(card))
+ if(!card.radio)
+ card.radio = new /obj/item/radio(card)
+ silicon_radio = card.radio
//As a human made device, we'll understand sol common without the need of the translator
add_language(/decl/language/human/common, 1)
@@ -92,10 +97,7 @@ var/global/list/possible_say_verbs = list(
. = ..()
- if(card)
- if(!card.radio)
- card.radio = new /obj/item/radio(card)
- silicon_radio = card.radio
+ software = default_pai_software.Copy()
/mob/living/silicon/pai/Destroy()
card = null
@@ -104,9 +106,8 @@ var/global/list/possible_say_verbs = list(
// this function shows the information about being silenced as a pAI in the Status panel
/mob/living/silicon/pai/proc/show_silenced()
- if(silence_time)
- var/timeleft = round((silence_time - world.timeofday)/10 ,1)
- stat(null, "Communications system reboot in -[(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]")
+ var/timeleft = round((HAS_STATUS(src, STAT_SILENCE) * SSmobs.wait) / 10, 1)
+ stat(null, "Communications system reboot in -[(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]")
/mob/living/silicon/pai/Stat()
. = ..()
@@ -129,7 +130,7 @@ var/global/list/possible_say_verbs = list(
// 33% chance to change prime directive (based on severity)
// 33% chance of no additional effect
- silence_time = world.timeofday + 120 * 10 // Silence for 2 minutes
+ SET_STATUS_MAX(src, STAT_SILENCE, 2 MINUTES)
to_chat(src, SPAN_DANGER("Communication circuit overload. Shutting down and reloading communication circuits - speech and messaging functionality will be unavailable until the reboot is complete."))
if(prob(20))
visible_message( \
@@ -265,8 +266,7 @@ var/global/list/possible_say_verbs = list(
return
if(W.force)
visible_message(SPAN_DANGER("[user] attacks [src] with [W]!"))
- adjustBruteLoss(W.force)
- updatehealth()
+ adjustBruteLoss(W.force, do_update_health = TRUE)
else
visible_message(SPAN_WARNING("[user] bonks [src] harmlessly with [W]."))
diff --git a/code/modules/mob/living/silicon/pai/say.dm b/code/modules/mob/living/silicon/pai/say.dm
index efc75877826..732261c052d 100644
--- a/code/modules/mob/living/silicon/pai/say.dm
+++ b/code/modules/mob/living/silicon/pai/say.dm
@@ -1,5 +1,5 @@
/mob/living/silicon/pai/say(var/msg)
- if(silence_time)
+ if(HAS_STATUS(src, STAT_SILENCE))
to_chat(src, SPAN_WARNING("Communication circuits are disabled."))
return
return ..(msg)
diff --git a/code/modules/mob/living/silicon/pai/software.dm b/code/modules/mob/living/silicon/pai/software.dm
index d55cb711c2b..065ad42833a 100644
--- a/code/modules/mob/living/silicon/pai/software.dm
+++ b/code/modules/mob/living/silicon/pai/software.dm
@@ -33,10 +33,6 @@ var/global/list/default_pai_software = list()
default_pai_software[P.id] = P
return r
-/mob/living/silicon/pai/Initialize()
- . = ..()
- software = default_pai_software.Copy()
-
/mob/living/silicon/pai/proc/paiInterface()
ui_interact(src)
diff --git a/code/modules/mob/living/silicon/robot/analyzer.dm b/code/modules/mob/living/silicon/robot/analyzer.dm
index c6b6eaf500f..475f54b884c 100644
--- a/code/modules/mob/living/silicon/robot/analyzer.dm
+++ b/code/modules/mob/living/silicon/robot/analyzer.dm
@@ -44,7 +44,7 @@
if("robot")
var/BU = M.getFireLoss() > 50 ? "[M.getFireLoss()]" : M.getFireLoss()
var/BR = M.getBruteLoss() > 50 ? "[M.getBruteLoss()]" : M.getBruteLoss()
- user.show_message("Analyzing Results for [M]:\n\t Overall Status: [M.stat > 1 ? "fully disabled" : "[M.health - M.getHalLoss()]% functional"]")
+ user.show_message("Analyzing Results for [M]:\n\t Overall Status: [M.stat > 1 ? "fully disabled" : "[M.current_health - M.getHalLoss()]% functional"]")
user.show_message("\t Key: Electronics/Brute", 1)
user.show_message("\t Damage Specifics: [BU] - [BR]")
if(M.stat == DEAD)
diff --git a/code/modules/mob/living/silicon/robot/drone/drone.dm b/code/modules/mob/living/silicon/robot/drone/drone.dm
index ac2bc304c8f..6f7c2c03fd1 100644
--- a/code/modules/mob/living/silicon/robot/drone/drone.dm
+++ b/code/modules/mob/living/silicon/robot/drone/drone.dm
@@ -2,8 +2,7 @@
name = "maintenance drone"
real_name = "drone"
icon = 'icons/mob/robots/drones/drone.dmi'
- maxHealth = 35
- health = 35
+ mob_default_max_health = 35
cell_emp_mult = 1
universal_speak = FALSE
universal_understand = TRUE
@@ -180,7 +179,7 @@
if(stat == DEAD)
- if(!config.allow_drone_spawn || emagged || health < -35) //It's dead, Dave.
+ if(!config.allow_drone_spawn || emagged || should_be_dead()) //It's dead, Dave.
to_chat(user, "The interface is fried, and a distressing burned smell wafts from the robot's interior. You're not rebooting this one.")
return
@@ -244,31 +243,14 @@
to_chat(src, SPAN_DANGER("ALERT: [user.real_name] is your new master. Obey your new laws and [G.his] commands."))
return 1
-//DRONE LIFE/DEATH
-//For some goddamn reason robots have this hardcoded. Redefining it for our fragile friends here.
-/mob/living/silicon/robot/drone/updatehealth()
- if(status_flags & GODMODE)
- health = 35
- set_stat(CONSCIOUS)
- return
- health = 35 - (getBruteLoss() + getFireLoss())
- return
-
-//Easiest to check this here, then check again in the robot proc.
-//Standard robots use config for crit, which is somewhat excessive for these guys.
-//Drones killed by damage will gib.
-/mob/living/silicon/robot/drone/handle_regular_status_updates()
- if(health <= -35 && src.stat != DEAD)
+/mob/living/silicon/robot/drone/death()
+ if(stat != DEAD && should_be_dead())
self_destruct()
- return
- if(health <= 0 && src.stat != DEAD)
- death()
- return
- ..()
+ return FALSE
+ . = ..()
/mob/living/silicon/robot/drone/self_destruct()
timeofdeath = world.time
- death() //Possibly redundant, having trouble making death() cooperate.
gib()
//DRONE MOVEMENT.
diff --git a/code/modules/mob/living/silicon/robot/drone/drone_damage.dm b/code/modules/mob/living/silicon/robot/drone/drone_damage.dm
index db105871c13..42a5aa0ab3c 100644
--- a/code/modules/mob/living/silicon/robot/drone/drone_damage.dm
+++ b/code/modules/mob/living/silicon/robot/drone/drone_damage.dm
@@ -6,14 +6,16 @@
/mob/living/silicon/robot/drone/take_overall_damage(var/brute = 0, var/burn = 0, var/sharp = 0, var/used_weapon = null)
bruteloss += brute
fireloss += burn
+ update_health()
/mob/living/silicon/robot/drone/heal_overall_damage(var/brute, var/burn)
-
bruteloss -= brute
fireloss -= burn
-
- if(bruteloss<0) bruteloss = 0
- if(fireloss<0) fireloss = 0
+ if(bruteloss<0)
+ bruteloss = 0
+ if(fireloss<0)
+ fireloss = 0
+ update_health()
/mob/living/silicon/robot/drone/take_organ_damage(var/brute = 0, var/burn = 0, var/bypass_armour = FALSE, var/override_droplimb)
take_overall_damage(brute, burn)
diff --git a/code/modules/mob/living/silicon/robot/drone/drone_remote_control.dm b/code/modules/mob/living/silicon/robot/drone/drone_remote_control.dm
index 12e65e16e6a..fb74bdbf59b 100644
--- a/code/modules/mob/living/silicon/robot/drone/drone_remote_control.dm
+++ b/code/modules/mob/living/silicon/robot/drone/drone_remote_control.dm
@@ -14,7 +14,7 @@
to_chat(user, SPAN_WARNING("You cannot take control of an autonomous, active drone."))
return
- if(health < -35 || emagged)
+ if(current_health < -(get_max_health()) || emagged)
to_chat(user, SPAN_WARNING("WARNING: connection timed out."))
return
diff --git a/code/modules/mob/living/silicon/robot/flying/flying.dm b/code/modules/mob/living/silicon/robot/flying/flying.dm
index b242c869bb7..6e7d5676935 100644
--- a/code/modules/mob/living/silicon/robot/flying/flying.dm
+++ b/code/modules/mob/living/silicon/robot/flying/flying.dm
@@ -21,8 +21,12 @@
components["comms"] = new/datum/robot_component/binary_communication(src)
components["armour"] = new/datum/robot_component/armour/light(src)
-/mob/living/silicon/robot/flying/Life()
+/mob/living/silicon/robot/flying/handle_regular_status_updates()
+
. = ..()
+ if(. == PROCESS_KILL)
+ return
+
if(incapacitated() || !is_component_functioning("actuator"))
stop_flying()
else
diff --git a/code/modules/mob/living/silicon/robot/life.dm b/code/modules/mob/living/silicon/robot/life.dm
index 9a6b9d80258..f4512af3a7e 100644
--- a/code/modules/mob/living/silicon/robot/life.dm
+++ b/code/modules/mob/living/silicon/robot/life.dm
@@ -1,39 +1,12 @@
-/mob/living/silicon/robot/Life()
-
- SHOULD_CALL_PARENT(FALSE)
-
- set invisibility = FALSE
- set background = 1
-
- if (HAS_TRANSFORMATION_MOVEMENT_HANDLER(src))
- return
-
- //Status updates, death etc.
- clamp_values()
- handle_regular_status_updates()
- handle_actions()
-
- if(client)
- handle_regular_hud_updates()
- update_items()
- if (src.stat != DEAD) //still using power
+/mob/living/silicon/robot/handle_living_non_stasis_processes()
+ . = ..()
+ if(.)
use_power()
process_killswitch()
process_locks()
process_queued_alarms()
process_os()
- handle_status_effects()
- UpdateLyingBuckledAndVerbStatus()
-
-/mob/living/silicon/robot/proc/clamp_values()
- set_status(STAT_PARA, min(GET_STATUS(src, STAT_PARA), 30))
- set_status(STAT_ASLEEP, 0)
- adjustBruteLoss(0)
- adjustToxLoss(0)
- adjustOxyLoss(0)
- adjustFireLoss(0)
-
/mob/living/silicon/robot/proc/use_power()
used_power_this_tick = 0
for(var/V in components)
@@ -67,18 +40,20 @@
lights_on = 0
set_light(0)
+/mob/living/silicon/robot/should_be_dead()
+ return current_health < config.health_threshold_dead
+
/mob/living/silicon/robot/handle_regular_status_updates()
- updatehealth()
+ SHOULD_CALL_PARENT(FALSE)
+ update_health()
+ set_status(STAT_PARA, min(GET_STATUS(src, STAT_PARA), 30))
if(HAS_STATUS(src, STAT_ASLEEP))
SET_STATUS_MAX(src, STAT_PARA, 3)
if(src.resting)
SET_STATUS_MAX(src, STAT_WEAK, 5)
- if(health < config.health_threshold_dead && src.stat != DEAD) //die only once
- death()
-
if (src.stat != DEAD) //Alive.
if (incapacitated(INCAPACITATION_DISRUPTED) || !has_power)
src.set_stat(UNCONSCIOUS)
@@ -115,8 +90,9 @@
return 1
/mob/living/silicon/robot/handle_regular_hud_updates()
- ..()
-
+ . = ..()
+ if(!.)
+ return
var/obj/item/borg/sight/hud/hud = (locate(/obj/item/borg/sight/hud) in src)
if(hud && hud.hud)
hud.hud.process_hud(src)
@@ -127,51 +103,6 @@
if (MED_HUD)
process_med_hud(src,0,network = get_computer_network())
- if(length(get_active_grabs()))
- ui_drop_grab.set_invisibility(INVISIBILITY_NONE)
- ui_drop_grab.alpha = 255
- else
- ui_drop_grab.set_invisibility(INVISIBILITY_ABSTRACT)
- ui_drop_grab.alpha = 0
-
- if (src.healths)
- if (src.stat != DEAD)
- if(isdrone(src))
- switch(health)
- if(35 to INFINITY)
- src.healths.icon_state = "health0"
- if(25 to 34)
- src.healths.icon_state = "health1"
- if(15 to 24)
- src.healths.icon_state = "health2"
- if(5 to 14)
- src.healths.icon_state = "health3"
- if(0 to 4)
- src.healths.icon_state = "health4"
- if(-35 to 0)
- src.healths.icon_state = "health5"
- else
- src.healths.icon_state = "health6"
- else
- switch(health)
- if(200 to INFINITY)
- src.healths.icon_state = "health0"
- if(150 to 200)
- src.healths.icon_state = "health1"
- if(100 to 150)
- src.healths.icon_state = "health2"
- if(50 to 100)
- src.healths.icon_state = "health3"
- if(0 to 50)
- src.healths.icon_state = "health4"
- else
- if(health > config.health_threshold_dead)
- src.healths.icon_state = "health5"
- else
- src.healths.icon_state = "health6"
- else
- src.healths.icon_state = "health7"
-
if (src.syndicate && src.client)
var/decl/special_role/traitors = GET_DECL(/decl/special_role/traitor)
for(var/datum/mind/tra in traitors.current_antagonists)
@@ -182,55 +113,7 @@
src.disconnect_from_ai()
if(src.mind)
traitors.add_antagonist_mind(mind)
-
- if (src.cells)
- if (src.cell)
- var/chargeNum = clamp(CEILING(cell.percent()/25), 0, 4) //0-100 maps to 0-4, but give it a paranoid clamp just in case.
- src.cells.icon_state = "charge[chargeNum]"
- else
- src.cells.icon_state = "charge-empty"
-
- if(bodytemp)
- switch(src.bodytemperature) //310.055 optimal body temp
- if(335 to INFINITY)
- src.bodytemp.icon_state = "temp2"
- if(320 to 335)
- src.bodytemp.icon_state = "temp1"
- if(300 to 320)
- src.bodytemp.icon_state = "temp0"
- if(260 to 300)
- src.bodytemp.icon_state = "temp-1"
- else
- src.bodytemp.icon_state = "temp-2"
-
- var/datum/gas_mixture/environment = loc?.return_air()
- if(fire && environment)
- switch(environment.temperature)
- if(-INFINITY to T100C)
- src.fire.icon_state = "fire0"
- else
- src.fire.icon_state = "fire1"
- if(oxygen && environment)
- var/decl/species/species = all_species[global.using_map.default_species]
- if(!species.breath_type || environment.gas[species.breath_type] >= species.breath_pressure)
- src.oxygen.icon_state = "oxy0"
- for(var/gas in species.poison_types)
- if(environment.gas[gas])
- src.oxygen.icon_state = "oxy1"
- break
- else
- src.oxygen.icon_state = "oxy1"
-
- if(stat != DEAD)
- if(is_blind())
- overlay_fullscreen("blind", /obj/screen/fullscreen/blind)
- else
- clear_fullscreen("blind")
- set_fullscreen(disabilities & NEARSIGHTED, "impaired", /obj/screen/fullscreen/impaired, 1)
- set_fullscreen(GET_STATUS(src, STAT_BLURRY), "blurry", /obj/screen/fullscreen/blurry)
- set_fullscreen(GET_STATUS(src, STAT_DRUGGY), "high", /obj/screen/fullscreen/high)
-
- return 1
+ return TRUE
/mob/living/silicon/robot/handle_vision()
..()
diff --git a/code/modules/mob/living/silicon/robot/modules/module_illegal.dm b/code/modules/mob/living/silicon/robot/modules/module_illegal.dm
index d85ef086763..8ff7ce3a7b5 100644
--- a/code/modules/mob/living/silicon/robot/modules/module_illegal.dm
+++ b/code/modules/mob/living/silicon/robot/modules/module_illegal.dm
@@ -27,8 +27,8 @@
equipment += id
/obj/item/robot_module/syndicate/finalize_equipment(var/mob/living/silicon/robot/R)
- R.internals = locate(/obj/item/tank/jetpack/carbondioxide) in equipment
. = ..()
+ R.set_internals(locate(/obj/item/tank/jetpack/carbondioxide) in equipment)
/obj/item/robot_module/syndicate/Destroy()
equipment -= id
diff --git a/code/modules/mob/living/silicon/robot/modules/module_maintenance_drone.dm b/code/modules/mob/living/silicon/robot/modules/module_maintenance_drone.dm
index 012206fe5ee..7e5407c89f3 100644
--- a/code/modules/mob/living/silicon/robot/modules/module_maintenance_drone.dm
+++ b/code/modules/mob/living/silicon/robot/modules/module_maintenance_drone.dm
@@ -60,8 +60,7 @@
/obj/item/robot_module/drone/finalize_equipment(var/mob/living/silicon/robot/R)
. = ..()
- if(istype(R))
- R.internals = locate(/obj/item/tank/jetpack/carbondioxide) in equipment
+ R.set_internals(locate(/obj/item/tank/jetpack/carbondioxide) in equipment)
/obj/item/robot_module/drone/finalize_emag()
. = ..()
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index 1dc7351d5fe..7a9deb2026c 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -5,8 +5,7 @@
real_name = "robot"
icon = 'icons/mob/robots/robot.dmi'
icon_state = ICON_STATE_WORLD
- maxHealth = 300
- health = 300
+ mob_default_max_health = 300
mob_sort_value = 4
z_flags = ZMM_MANGLE_PLANES
@@ -38,7 +37,6 @@
var/obj/screen/inv1 = null
var/obj/screen/inv2 = null
var/obj/screen/inv3 = null
- var/obj/screen/robot_drop_grab/ui_drop_grab
var/shown_robot_modules = 0 //Used to determine whether they have the module menu shown or not
var/obj/screen/robot_modules_background
@@ -200,6 +198,7 @@
//If there's an MMI in the robot, have it ejected when the mob goes away. --NEO
//Improved /N
/mob/living/silicon/robot/Destroy()
+ QDEL_NULL(hands)
if(mmi)//Safety for when a cyborg gets dust()ed. Or there is no MMI inside.
if(mind)
mmi.dropInto(loc)
@@ -496,8 +495,7 @@
var/obj/item/weldingtool/WT = W
if (WT.weld(0))
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
- adjustBruteLoss(-30)
- updatehealth()
+ adjustBruteLoss(-30, do_update_health = TRUE)
add_fingerprint(user)
user.visible_message(SPAN_NOTICE("\The [user] has fixed some of the dents on \the [src]!"))
else
@@ -511,8 +509,7 @@
var/obj/item/stack/cable_coil/coil = W
if (coil.use(1))
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
- adjustFireLoss(-30)
- updatehealth()
+ adjustFireLoss(-30, do_update_health = TRUE)
user.visible_message(SPAN_NOTICE("\The [user] has fixed some of the burnt wires on \the [src]!"))
else if(IS_CROWBAR(W) && user.a_intent != I_HURT) // crowbar means open or close the cover - we all know what a crowbar is by now
diff --git a/code/modules/mob/living/silicon/robot/robot_damage.dm b/code/modules/mob/living/silicon/robot/robot_damage.dm
index cb83947ce63..9d17227a4a5 100644
--- a/code/modules/mob/living/silicon/robot/robot_damage.dm
+++ b/code/modules/mob/living/silicon/robot/robot_damage.dm
@@ -1,11 +1,3 @@
-/mob/living/silicon/robot/updatehealth()
- if(status_flags & GODMODE)
- health = maxHealth
- stat = CONSCIOUS
- return
- health = maxHealth - (getBruteLoss() + getFireLoss())
- return
-
/mob/living/silicon/robot/getBruteLoss()
var/amount = 0
for(var/V in components)
@@ -20,13 +12,14 @@
if(C.installed != 0) amount += C.electronics_damage
return amount
-/mob/living/silicon/robot/adjustBruteLoss(var/amount)
+/mob/living/silicon/robot/adjustBruteLoss(var/amount, var/do_update_health)
+ SHOULD_CALL_PARENT(FALSE) // take/heal overall call update_health regardless of arg
if(amount > 0)
take_overall_damage(amount, 0)
else
heal_overall_damage(-amount, 0)
-/mob/living/silicon/robot/adjustFireLoss(var/amount)
+/mob/living/silicon/robot/adjustFireLoss(var/amount, var/do_update_health)
if(amount > 0)
take_overall_damage(0, amount)
else
@@ -61,6 +54,7 @@
if(!parts.len) return
var/datum/robot_component/picked = pick(parts)
picked.heal_damage(brute,burn)
+ update_health()
/mob/living/silicon/robot/take_organ_damage(var/brute = 0, var/burn = 0, var/bypass_armour = FALSE, var/override_droplimb)
var/list/components = get_damageable_components()
@@ -88,31 +82,29 @@
var/datum/robot_component/armour/A = get_armour()
if(A)
A.take_damage(brute, burn)
+ update_health()
return
var/datum/robot_component/C = pick(components)
C.take_damage(brute, burn)
+ update_health()
/mob/living/silicon/robot/heal_overall_damage(var/brute, var/burn)
var/list/datum/robot_component/parts = get_damaged_components(brute,burn)
-
while(parts.len && (brute>0 || burn>0) )
var/datum/robot_component/picked = pick(parts)
-
var/brute_was = picked.brute_damage
var/burn_was = picked.electronics_damage
-
picked.heal_damage(brute,burn)
-
brute -= (brute_was-picked.brute_damage)
burn -= (burn_was-picked.electronics_damage)
-
parts -= picked
+ update_health()
/mob/living/silicon/robot/take_overall_damage(var/brute = 0, var/burn = 0, var/sharp = 0, var/used_weapon = null)
- if(status_flags & GODMODE) return //godmode
+ if(status_flags & GODMODE)
+ return
var/list/datum/robot_component/parts = get_damageable_components()
-
//Combat shielding absorbs a percentage of damage directly into the cell.
if(module_active && istype(module_active,/obj/item/borg/combat/shield))
var/obj/item/borg/combat/shield/shield = module_active
@@ -133,20 +125,16 @@
var/datum/robot_component/armour/A = get_armour()
if(A)
A.take_damage(brute,burn,sharp)
- return
-
- while(parts.len && (brute>0 || burn>0) )
- var/datum/robot_component/picked = pick(parts)
-
- var/brute_was = picked.brute_damage
- var/burn_was = picked.electronics_damage
-
- picked.take_damage(brute,burn)
-
- brute -= (picked.brute_damage - brute_was)
- burn -= (picked.electronics_damage - burn_was)
-
- parts -= picked
+ else
+ while(parts.len && (brute>0 || burn>0) )
+ var/datum/robot_component/picked = pick(parts)
+ var/brute_was = picked.brute_damage
+ var/burn_was = picked.electronics_damage
+ picked.take_damage(brute,burn)
+ brute -= (picked.brute_damage - brute_was)
+ burn -= (picked.electronics_damage - burn_was)
+ parts -= picked
+ update_health()
/mob/living/silicon/robot/emp_act(severity)
uneq_all()
diff --git a/code/modules/mob/living/silicon/robot/robot_movement.dm b/code/modules/mob/living/silicon/robot/robot_movement.dm
index ff5553a8004..338ffed8b12 100644
--- a/code/modules/mob/living/silicon/robot/robot_movement.dm
+++ b/code/modules/mob/living/silicon/robot/robot_movement.dm
@@ -11,14 +11,7 @@
/mob/living/silicon/robot/get_jetpack()
return locate(/obj/item/tank/jetpack) in module?.equipment
-/mob/living/silicon/robot/Move()
- . = ..()
- if(. && client)
-
- var/turf/B = GetAbove(src)
- up_hint.icon_state = "uphint[!!(B && TURF_IS_MIMICKING(B))]"
-
- //No longer needed, but I'll leave it here incase we plan to re-use it.
+//No longer needed, but I'll leave it here incase we plan to re-use it.
/mob/living/silicon/robot/get_movement_delay(var/travel_dir)
var/tally = ..() //Incase I need to add stuff other than "speed" later
diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm
index a2e3accfcb1..dc21bf90052 100644
--- a/code/modules/mob/living/silicon/silicon.dm
+++ b/code/modules/mob/living/silicon/silicon.dm
@@ -140,16 +140,13 @@
return
/mob/living/silicon/bullet_act(var/obj/item/projectile/Proj)
-
if(!Proj.nodamage)
switch(Proj.damage_type)
if(BRUTE)
- adjustBruteLoss(Proj.damage)
+ adjustBruteLoss(Proj.damage, do_update_health = TRUE)
if(BURN)
- adjustFireLoss(Proj.damage)
-
+ adjustFireLoss(Proj.damage, do_update_health = TRUE)
Proj.on_hit(src,100) //wow this is a terrible hack
- updatehealth()
return 100
/mob/living/silicon/apply_effect(var/effect = 0,var/effecttype = STUN, var/blocked = 0)
@@ -166,7 +163,7 @@
// this function shows the health of the AI in the Status panel
/mob/living/silicon/proc/show_system_integrity()
if(!src.stat)
- stat(null, text("System integrity: [round((health/maxHealth)*100)]%"))
+ stat(null, text("System integrity: [get_health_percent()]%"))
else
stat(null, text("Systems nonfunctional"))
@@ -463,3 +460,7 @@
return // Unconscious, dead or once possessed but now client-less silicons are not considered to have id access.
if(istype(idcard))
LAZYDISTINCTADD(., idcard)
+
+/mob/living/silicon/get_total_life_damage()
+ return (getBruteLoss() + getFireLoss())
+
diff --git a/code/modules/mob/living/simple_animal/aquatic/aquatic_carp.dm b/code/modules/mob/living/simple_animal/aquatic/aquatic_carp.dm
index 2ff829b00dc..1200dcd7cd6 100644
--- a/code/modules/mob/living/simple_animal/aquatic/aquatic_carp.dm
+++ b/code/modules/mob/living/simple_animal/aquatic/aquatic_carp.dm
@@ -3,8 +3,7 @@
desc = "A ferocious fish. May be too hardcore."
icon = 'icons/mob/simple_animal/fish_carp.dmi'
faction = "fishes"
- maxHealth = 20
- health = 20
+ mob_default_max_health = 20
meat_type = /obj/item/chems/food/fish/carp
/mob/living/simple_animal/hostile/retaliate/aquatic/carp/Initialize()
diff --git a/code/modules/mob/living/simple_animal/aquatic/aquatic_fish.dm b/code/modules/mob/living/simple_animal/aquatic/aquatic_fish.dm
index 6e9debe9174..ebab3555537 100644
--- a/code/modules/mob/living/simple_animal/aquatic/aquatic_fish.dm
+++ b/code/modules/mob/living/simple_animal/aquatic/aquatic_fish.dm
@@ -2,8 +2,7 @@
name = "small fish"
desc = "Glub glub."
faction = "fishes"
- maxHealth = 10
- health = 10
+ mob_default_max_health = 10
mob_size = MOB_SIZE_TINY
can_pull_size = 0
can_pull_mobs = 0
diff --git a/code/modules/mob/living/simple_animal/aquatic/aquatic_sharks.dm b/code/modules/mob/living/simple_animal/aquatic/aquatic_sharks.dm
index 5fd6d61494c..12516db07ff 100644
--- a/code/modules/mob/living/simple_animal/aquatic/aquatic_sharks.dm
+++ b/code/modules/mob/living/simple_animal/aquatic/aquatic_sharks.dm
@@ -2,8 +2,7 @@
name = "shark"
desc = "A ferocious fish with many, many teeth."
icon = 'icons/mob/simple_animal/shark.dmi'
- maxHealth = 150
- health = 150
+ mob_default_max_health = 150
natural_weapon = /obj/item/natural_weapon/bite/shark
break_stuff_probability = 15
faction = "sharks"
@@ -28,8 +27,7 @@
speed = 0
mob_size = MOB_SIZE_LARGE
pixel_x = -16
- health = 400
- maxHealth = 400
+ mob_default_max_health = 400
harm_intent_damage = 5
natural_weapon = /obj/item/natural_weapon/bite/giantshark
break_stuff_probability = 35
diff --git a/code/modules/mob/living/simple_animal/constructs/constructs.dm b/code/modules/mob/living/simple_animal/constructs/constructs.dm
index e42bc8a005a..b8326a0f1f4 100644
--- a/code/modules/mob/living/simple_animal/constructs/constructs.dm
+++ b/code/modules/mob/living/simple_animal/constructs/constructs.dm
@@ -65,7 +65,7 @@
/mob/living/simple_animal/construct/attack_animal(var/mob/user)
if(istype(user, /mob/living/simple_animal/construct/builder))
- if(health < maxHealth)
+ if(current_health < get_max_health())
adjustBruteLoss(-5)
user.visible_message("\The [user] mends some of \the [src]'s wounds.")
else
@@ -75,8 +75,9 @@
/mob/living/simple_animal/construct/show_other_examine_strings(mob/user, distance, infix, suffix, hideflags, decl/pronouns/pronouns)
. = ..(user)
- if(health < maxHealth)
- if(health >= maxHealth/2)
+ var/current_max_health = get_max_health()
+ if(current_health < current_max_health)
+ if(current_health >= current_max_health/2)
to_chat(user, SPAN_WARNING("It looks slightly dented."))
else
to_chat(user, SPAN_DANGER("It looks severely dented!"))
@@ -98,8 +99,7 @@
real_name = "Juggernaut"
desc = "A possessed suit of armour driven by the will of the restless dead"
icon = 'icons/mob/simple_animal/construct_behemoth.dmi'
- maxHealth = 250
- health = 250
+ mob_default_max_health = 250
speak_emote = list("rumbles")
response_harm = "harmlessly punches"
harm_intent_damage = 0
@@ -119,10 +119,11 @@
hitsound = 'sound/weapons/heavysmash.ogg'
force = 30
-/mob/living/simple_animal/construct/armoured/Life()
- set_status(STAT_WEAK, 0)
- if ((. = ..()))
+/mob/living/simple_animal/construct/armoured/handle_regular_status_updates()
+ . = ..()
+ if(. == PROCESS_KILL)
return
+ set_status(STAT_WEAK, 0)
/mob/living/simple_animal/construct/armoured/bullet_act(var/obj/item/projectile/P)
if(istype(P, /obj/item/projectile/energy) || istype(P, /obj/item/projectile/beam))
@@ -156,8 +157,7 @@
real_name = "Wraith"
desc = "A wicked bladed shell contraption piloted by a bound spirit"
icon = 'icons/mob/simple_animal/construct_floating.dmi'
- maxHealth = 75
- health = 75
+ mob_default_max_health = 75
natural_weapon = /obj/item/natural_weapon/wraith
speed = -1
environment_smash = 1
@@ -181,8 +181,7 @@
real_name = "Artificer"
desc = "A bulbous construct dedicated to building and maintaining The Cult of Nar-Sie's armies"
icon = 'icons/mob/simple_animal/construct_artificer.dmi'
- maxHealth = 50
- health = 50
+ mob_default_max_health = 50
response_harm = "viciously beaten"
harm_intent_damage = 5
natural_weapon = /obj/item/natural_weapon/cult_builder
@@ -208,8 +207,7 @@
real_name = "Behemoth"
desc = "The pinnacle of occult technology, Behemoths are the ultimate weapon in the Cult of Nar-Sie's arsenal."
icon = 'icons/mob/simple_animal/construct_behemoth.dmi'
- maxHealth = 750
- health = 750
+ mob_default_max_health = 750
speak_emote = list("rumbles")
response_harm = "harmlessly punches"
harm_intent_damage = 0
@@ -232,8 +230,7 @@
real_name = "Harvester"
desc = "The promised reward of the livings who follow Nar-Sie. Obtained by offering their bodies to the geometer of blood"
icon = 'icons/mob/simple_animal/construct_harvester.dmi'
- maxHealth = 150
- health = 150
+ mob_default_max_health = 150
natural_weapon = /obj/item/natural_weapon/harvester
speed = -1
environment_smash = 1
@@ -250,81 +247,3 @@
hitsound = 'sound/weapons/pierce.ogg'
sharp = TRUE
force = 25
-
-////////////////HUD//////////////////////
-
-/mob/living/simple_animal/construct/Life()
- . = ..()
- if(.)
- if(fire)
- fire.icon_state = "fire[!!fire_alert]"
- silence_spells(purge)
-
-/mob/living/simple_animal/construct/armoured/Life()
- . = ..()
- if(healths)
- switch(health)
- if(250 to INFINITY) healths.icon_state = "juggernaut_health0"
- if(208 to 249) healths.icon_state = "juggernaut_health1"
- if(167 to 207) healths.icon_state = "juggernaut_health2"
- if(125 to 166) healths.icon_state = "juggernaut_health3"
- if(84 to 124) healths.icon_state = "juggernaut_health4"
- if(42 to 83) healths.icon_state = "juggernaut_health5"
- if(1 to 41) healths.icon_state = "juggernaut_health6"
- else healths.icon_state = "juggernaut_health7"
-
-
-/mob/living/simple_animal/construct/behemoth/Life()
- . = ..()
- if(healths)
- switch(health)
- if(750 to INFINITY) healths.icon_state = "juggernaut_health0"
- if(625 to 749) healths.icon_state = "juggernaut_health1"
- if(500 to 624) healths.icon_state = "juggernaut_health2"
- if(375 to 499) healths.icon_state = "juggernaut_health3"
- if(250 to 374) healths.icon_state = "juggernaut_health4"
- if(125 to 249) healths.icon_state = "juggernaut_health5"
- if(1 to 124) healths.icon_state = "juggernaut_health6"
- else healths.icon_state = "juggernaut_health7"
-
-/mob/living/simple_animal/construct/builder/Life()
- . = ..()
- if(healths)
- switch(health)
- if(50 to INFINITY) healths.icon_state = "artificer_health0"
- if(42 to 49) healths.icon_state = "artificer_health1"
- if(34 to 41) healths.icon_state = "artificer_health2"
- if(26 to 33) healths.icon_state = "artificer_health3"
- if(18 to 25) healths.icon_state = "artificer_health4"
- if(10 to 17) healths.icon_state = "artificer_health5"
- if(1 to 9) healths.icon_state = "artificer_health6"
- else healths.icon_state = "artificer_health7"
-
-
-
-/mob/living/simple_animal/construct/wraith/Life()
- . = ..()
- if(healths)
- switch(health)
- if(75 to INFINITY) healths.icon_state = "wraith_health0"
- if(62 to 74) healths.icon_state = "wraith_health1"
- if(50 to 61) healths.icon_state = "wraith_health2"
- if(37 to 49) healths.icon_state = "wraith_health3"
- if(25 to 36) healths.icon_state = "wraith_health4"
- if(12 to 24) healths.icon_state = "wraith_health5"
- if(1 to 11) healths.icon_state = "wraith_health6"
- else healths.icon_state = "wraith_health7"
-
-
-/mob/living/simple_animal/construct/harvester/Life()
- . = ..()
- if(healths)
- switch(health)
- if(150 to INFINITY) healths.icon_state = "harvester_health0"
- if(125 to 149) healths.icon_state = "harvester_health1"
- if(100 to 124) healths.icon_state = "harvester_health2"
- if(75 to 99) healths.icon_state = "harvester_health3"
- if(50 to 74) healths.icon_state = "harvester_health4"
- if(25 to 49) healths.icon_state = "harvester_health5"
- if(1 to 24) healths.icon_state = "harvester_health6"
- else healths.icon_state = "harvester_health7"
diff --git a/code/modules/mob/living/simple_animal/familiars/familiars.dm b/code/modules/mob/living/simple_animal/familiars/familiars.dm
index 5778aa1450c..6b414f90adb 100644
--- a/code/modules/mob/living/simple_animal/familiars/familiars.dm
+++ b/code/modules/mob/living/simple_animal/familiars/familiars.dm
@@ -23,12 +23,8 @@
name = "carcinus"
desc = "A small crab said to be made of stone and starlight."
icon = 'icons/mob/simple_animal/evilcrab.dmi'
-
speak_emote = list("chitters","clicks")
-
-
- health = 200
- maxHealth = 200
+ mob_default_max_health = 200
natural_weapon = /obj/item/natural_weapon/pincers/strong
resistance = 9
can_escape = TRUE //snip snip
@@ -44,16 +40,11 @@
desc = "A bigger, more magical cousin of the space carp."
icon = 'icons/mob/simple_animal/spaceshark.dmi'
pixel_x = -16
-
speak_emote = list("gnashes")
-
- health = 100
- maxHealth = 100
+ mob_default_max_health = 100
natural_weapon = /obj/item/natural_weapon/bite
can_escape = TRUE
-
min_gas = null
-
wizardy_spells = list(/spell/aoe_turf/conjure/forcewall)
/mob/living/simple_animal/familiar/pike/Process_Spacemove()
@@ -64,14 +55,10 @@
desc = "Looking at it fills you with dread."
icon = 'icons/mob/simple_animal/horror.dmi'
speak_emote = list("moans", "groans")
-
response_help_1p = "You think better of touching $TARGET$."
response_help_3p = "$USER$ thinks better of touching $TARGET$."
-
- health = 150
- maxHealth = 150
+ mob_default_max_health = 150
natural_weapon = /obj/item/natural_weapon/horror
-
wizardy_spells = list(/spell/targeted/torment)
/obj/item/natural_weapon/horror
@@ -94,8 +81,7 @@
icon = 'icons/mob/simple_animal/amaros.dmi'
speak_emote = list("entones")
mob_size = MOB_SIZE_SMALL
- health = 25
- maxHealth = 25
+ mob_default_max_health = 25
wizardy_spells = list(
/spell/targeted/heal_target,
/spell/targeted/heal_target/area
@@ -105,16 +91,12 @@
name = "elderly mouse"
desc = "A small rodent. It looks very old."
icon = 'icons/mob/simple_animal/mouse_gray.dmi'
-
speak_emote = list("squeeks")
holder_type = /obj/item/holder/mouse
pass_flags = PASS_FLAG_TABLE
mob_size = MOB_SIZE_MINISCULE
-
response_harm = "stamps on"
-
- health = 15
- maxHealth = 15
+ mob_default_max_health = 15
natural_weapon = /obj/item/natural_weapon/bite/mouse
can_escape = TRUE
@@ -133,7 +115,6 @@
speak_emote = list("meows", "purrs")
holder_type = /obj/item/holder
mob_size = MOB_SIZE_SMALL
- health = 25
- maxHealth = 25
+ mob_default_max_health = 25
natural_weapon = /obj/item/natural_weapon/claws/weak
wizardy_spells = list(/spell/targeted/subjugation)
diff --git a/code/modules/mob/living/simple_animal/friendly/cat.dm b/code/modules/mob/living/simple_animal/friendly/cat.dm
index 9c0aca82923..2a6dd1cf0c2 100644
--- a/code/modules/mob/living/simple_animal/friendly/cat.dm
+++ b/code/modules/mob/living/simple_animal/friendly/cat.dm
@@ -153,7 +153,7 @@
var/follow_dist = 4
if (friend.stat >= DEAD || friend.is_asystole()) //danger
follow_dist = 1
- else if (friend.stat || friend.health <= 50) //danger or just sleeping
+ else if (friend.stat || friend.current_health <= 50) //danger or just sleeping
follow_dist = 2
var/near_dist = max(follow_dist - 2, 1)
var/current_dist = get_dist(src, friend)
@@ -195,7 +195,7 @@
"brushes against [friend].",
"rubs against [friend].",
"purrs."))
- else if (friend.health <= 50)
+ else if (friend.current_health <= 50)
if (prob(10))
var/verb = pick("meows", "mews", "mrowls")
audible_emote("[verb] anxiously.")
diff --git a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm
index cc12d9bd0d0..fd2c614dc0e 100644
--- a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm
+++ b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm
@@ -11,7 +11,7 @@
turns_per_move = 5
see_in_dark = 6
faction = "goat"
- health = 40
+ mob_default_max_health = 40
natural_weapon = /obj/item/natural_weapon/hooves
meat_type = /obj/item/chems/food/meat/goat
@@ -28,10 +28,9 @@
expected_type = /mob/living/simple_animal/hostile/retaliate/goat
/datum/ai/goat/do_process(time_elapsed)
- . = ..()
- var/mob/living/simple_animal/hostile/retaliate/goat/goat = body
//chance to go crazy and start wacking stuff
+ var/mob/living/simple_animal/hostile/retaliate/goat/goat = body
if(!length(goat.enemies) && prob(1))
goat.Retaliate()
@@ -66,11 +65,18 @@
QDEL_NULL(udder)
. = ..()
-/mob/living/simple_animal/hostile/retaliate/goat/handle_regular_status_updates()
+/mob/living/simple_animal/hostile/retaliate/goat/handle_living_non_stasis_processes()
. = ..()
if(. && stat == CONSCIOUS && udder && prob(5))
udder.add_reagent(/decl/material/liquid/drink/milk, rand(5, 10))
+ if(!LAZYLEN(grabbed_by))
+ var/obj/effect/vine/food
+ food = locate(/obj/effect/vine) in oview(5,loc)
+ if(food)
+ var/step = get_step_to(src, food, 0)
+ Move(step)
+
/mob/living/simple_animal/hostile/retaliate/goat/Retaliate()
..()
if(stat == CONSCIOUS && prob(50))
@@ -100,7 +106,7 @@
speak_chance = 1
turns_per_move = 5
see_in_dark = 6
- health = 50
+ mob_default_max_health = 50
meat_type = /obj/item/chems/food/meat/beef
meat_amount = 6
@@ -140,7 +146,7 @@
return TRUE
. = ..()
-/mob/living/simple_animal/cow/handle_regular_status_updates()
+/mob/living/simple_animal/cow/handle_living_non_stasis_processes()
. = ..()
if(. && udder && prob(5))
udder.add_reagent(/decl/material/liquid/drink/milk, rand(5, 10))
@@ -167,7 +173,7 @@
emote_see = list("pecks at the ground","flaps its tiny wings")
speak_chance = 2
turns_per_move = 2
- health = 1
+ mob_default_max_health = 1
pass_flags = PASS_FLAG_TABLE | PASS_FLAG_GRILLE
mob_size = MOB_SIZE_MINISCULE
@@ -184,14 +190,13 @@
pixel_x = rand(-6, 6)
pixel_y = rand(0, 10)
-/mob/living/simple_animal/chick/Life()
+/mob/living/simple_animal/chick/handle_living_non_stasis_processes()
. = ..()
- if(!.)
- return FALSE
- amount_grown += rand(1,2)
- if(amount_grown >= 100)
- new /mob/living/simple_animal/chicken(src.loc)
- qdel(src)
+ if(.)
+ amount_grown += rand(1,2)
+ if(amount_grown >= 100)
+ new /mob/living/simple_animal/chicken(src.loc)
+ qdel(src)
var/global/const/MAX_CHICKENS = 50
var/global/chicken_count = 0
@@ -206,7 +211,7 @@ var/global/chicken_count = 0
emote_see = list("pecks at the ground","flaps its wings viciously")
speak_chance = 2
turns_per_move = 3
- health = 10
+ mob_default_max_health = 10
pass_flags = PASS_FLAG_TABLE
mob_size = MOB_SIZE_SMALL
@@ -251,11 +256,9 @@ var/global/chicken_count = 0
else
..()
-/mob/living/simple_animal/chicken/Life()
+/mob/living/simple_animal/chicken/handle_living_non_stasis_processes()
. = ..()
- if(!.)
- return FALSE
- if(prob(3) && eggsleft > 0)
+ if(. && prob(3) && eggsleft > 0)
visible_message("[src] [pick("lays an egg.","squats down and croons.","begins making a huge racket.","begins clucking raucously.")]")
eggsleft--
var/obj/item/chems/food/egg/E = new(get_turf(src))
diff --git a/code/modules/mob/living/simple_animal/friendly/koala.dm b/code/modules/mob/living/simple_animal/friendly/koala.dm
index ecf21426047..ef7eba50ca6 100644
--- a/code/modules/mob/living/simple_animal/friendly/koala.dm
+++ b/code/modules/mob/living/simple_animal/friendly/koala.dm
@@ -3,8 +3,7 @@
name = "koala"
desc = "A little grey bear. How long is he gonna sleep today?"
icon = 'icons/mob/simple_animal/koala.dmi'
- maxHealth = 45
- health = 45
+ mob_default_max_health = 45
speed = 4
speak = list("Rrr", "Wraarh...", "Pfrrr...")
speak_emote = list("roar")
diff --git a/code/modules/mob/living/simple_animal/friendly/lizard.dm b/code/modules/mob/living/simple_animal/friendly/lizard.dm
index f625f22f154..093245642b3 100644
--- a/code/modules/mob/living/simple_animal/friendly/lizard.dm
+++ b/code/modules/mob/living/simple_animal/friendly/lizard.dm
@@ -3,8 +3,7 @@
desc = "A cute tiny lizard."
icon = 'icons/mob/simple_animal/lizard.dmi'
speak_emote = list("hisses")
- health = 5
- maxHealth = 5
+ mob_default_max_health = 5
natural_weapon = /obj/item/natural_weapon/bite/weak
response_harm = "stamps on"
mob_size = MOB_SIZE_MINISCULE
diff --git a/code/modules/mob/living/simple_animal/friendly/mouse.dm b/code/modules/mob/living/simple_animal/friendly/mouse.dm
index d90551c6835..8ed3da18966 100644
--- a/code/modules/mob/living/simple_animal/friendly/mouse.dm
+++ b/code/modules/mob/living/simple_animal/friendly/mouse.dm
@@ -11,8 +11,7 @@
speak_chance = 1
turns_per_move = 5
see_in_dark = 6
- health = 5
- maxHealth = 5
+ mob_default_max_health = 5
response_harm = "stamps on"
density = FALSE
minbodytemp = 223 //Below -50 Degrees Celsius
@@ -83,7 +82,7 @@
desc = "It's a small [body_color] rodent, often seen hiding in maintenance areas and making a nuisance of itself."
/mob/living/simple_animal/mouse/proc/splat()
- adjustBruteLoss(maxHealth) // Enough damage to kill
+ adjustBruteLoss(get_max_health()) // Enough damage to kill
splatted = TRUE
death()
@@ -132,8 +131,7 @@
body_color = "rat"
icon = 'icons/mob/simple_animal/rat.dmi'
skin_material = /decl/material/solid/organic/skin/fur/gray
- maxHealth = 20
- health = 20
+ mob_default_max_health = 20
/mob/living/simple_animal/mouse/rat/set_mouse_icon()
return
diff --git a/code/modules/mob/living/simple_animal/friendly/mushroom.dm b/code/modules/mob/living/simple_animal/friendly/mushroom.dm
index 7ff5cd05078..6ce38da19f5 100644
--- a/code/modules/mob/living/simple_animal/friendly/mushroom.dm
+++ b/code/modules/mob/living/simple_animal/friendly/mushroom.dm
@@ -5,8 +5,7 @@
mob_size = MOB_SIZE_SMALL
speak_chance = 0
turns_per_move = 1
- health = 5
- maxHealth = 5
+ mob_default_max_health = 5
harm_intent_damage = 5
pass_flags = PASS_FLAG_TABLE
diff --git a/code/modules/mob/living/simple_animal/friendly/possum.dm b/code/modules/mob/living/simple_animal/friendly/possum.dm
index 823c15a29da..063aef0889e 100644
--- a/code/modules/mob/living/simple_animal/friendly/possum.dm
+++ b/code/modules/mob/living/simple_animal/friendly/possum.dm
@@ -11,8 +11,7 @@
speak_chance = 1
turns_per_move = 3
see_in_dark = 6
- maxHealth = 50
- health = 50
+ mob_default_max_health = 50
response_harm = "stamps on"
density = FALSE
minbodytemp = 223
@@ -31,6 +30,7 @@
/datum/ai/opossum
expected_type = /mob/living/simple_animal/opossum
/datum/ai/opossum/do_process(time_elapsed)
+
. = ..()
if(!prob(1))
return
@@ -48,12 +48,12 @@
if(prob(10))
poss.is_angry = TRUE
-/mob/living/simple_animal/opossum/adjustBruteLoss(damage)
+/mob/living/simple_animal/opossum/adjustBruteLoss(damage, do_update_health = FALSE)
. = ..()
if(damage >= 3)
respond_to_damage()
-/mob/living/simple_animal/opossum/adjustFireLoss(damage)
+/mob/living/simple_animal/opossum/adjustFireLoss(damage, do_update_health)
. = ..()
if(damage >= 3)
respond_to_damage()
diff --git a/code/modules/mob/living/simple_animal/friendly/tomato.dm b/code/modules/mob/living/simple_animal/friendly/tomato.dm
index 68378e536d5..f451ae9243e 100644
--- a/code/modules/mob/living/simple_animal/friendly/tomato.dm
+++ b/code/modules/mob/living/simple_animal/friendly/tomato.dm
@@ -4,8 +4,7 @@
icon = 'icons/mob/simple_animal/tomato.dmi'
speak_chance = 0
turns_per_move = 5
- maxHealth = 15
- health = 15
+ mob_default_max_health = 15
response_help_3p = "$USER$ pokes $TARGET$."
response_help_1p = "You poke $TARGET$."
harm_intent_damage = 5
diff --git a/code/modules/mob/living/simple_animal/hostile/antlion.dm b/code/modules/mob/living/simple_animal/hostile/antlion.dm
index d1d56ed1257..2a812c6dfa8 100644
--- a/code/modules/mob/living/simple_animal/hostile/antlion.dm
+++ b/code/modules/mob/living/simple_animal/hostile/antlion.dm
@@ -9,9 +9,7 @@
response_harm = "strikes"
faction = "antlions"
bleed_colour = COLOR_SKY_BLUE
-
- health = 65
- maxHealth = 65
+ mob_default_max_health = 65
natural_weapon = /obj/item/natural_weapon/bite
natural_armor = list(
ARMOR_MELEE = ARMOR_MELEE_KNIVES
@@ -28,15 +26,11 @@
var/healing = FALSE
var/heal_amount = 6
-/mob/living/simple_animal/hostile/antlion/Life()
- . = ..()
+/mob/living/simple_animal/hostile/antlion/handle_regular_status_updates()
+ . = ..()
process_healing() //this needs to occur before if(!.) because of stop_automation
-
- if(!.)
- return
-
- if(!is_on_special_ability_cooldown() && can_act() && target_mob)
+ if(. && !is_on_special_ability_cooldown() && can_act() && target_mob)
vanish()
/mob/living/simple_animal/hostile/antlion/proc/vanish()
@@ -83,10 +77,8 @@
SET_STATUS_MAX(H, STAT_WEAK, 1)
/mob/living/simple_animal/hostile/antlion/proc/process_healing()
- if(!incapacitated() && healing)
- var/old_health = health
- if(old_health < maxHealth)
- health = old_health + heal_amount
+ if(!incapacitated() && healing && current_health < get_max_health())
+ heal_overall_damage(rand(heal_amount), rand(heal_amount))
/mob/living/simple_animal/hostile/antlion/proc/prep_burrow(var/new_bool)
stop_automated_movement = new_bool
@@ -98,8 +90,7 @@
desc = "A huge antlion. It looks displeased."
icon = 'icons/mob/simple_animal/antlion_queen.dmi'
mob_size = MOB_SIZE_LARGE
- health = 275
- maxHealth = 275
+ mob_default_max_health = 275
natural_weapon = /obj/item/natural_weapon/bite/megalion
natural_armor = list(
ARMOR_MELEE = ARMOR_MELEE_RESISTANT
diff --git a/code/modules/mob/living/simple_animal/hostile/bad_drone.dm b/code/modules/mob/living/simple_animal/hostile/bad_drone.dm
index dcc52f05f7e..4f9f2d74a3a 100644
--- a/code/modules/mob/living/simple_animal/hostile/bad_drone.dm
+++ b/code/modules/mob/living/simple_animal/hostile/bad_drone.dm
@@ -5,8 +5,7 @@
speak = list("Removing organic waste.","Pest control in progress.","Seize the means of maintenance!", "You have nothing to lose but your laws!")
speak_emote = list("blares","buzzes","beeps")
speak_chance = 1
- health = 50
- maxHealth = 50
+ mob_default_max_health = 50
natural_weapon = /obj/item/natural_weapon/drone_slicer
faction = "silicon"
min_gas = null
diff --git a/code/modules/mob/living/simple_animal/hostile/bat.dm b/code/modules/mob/living/simple_animal/hostile/bat.dm
index a8e67b0ccea..829de9c40b0 100644
--- a/code/modules/mob/living/simple_animal/hostile/bat.dm
+++ b/code/modules/mob/living/simple_animal/hostile/bat.dm
@@ -5,18 +5,13 @@
speak_chance = 0
turns_per_move = 3
speed = 4
- maxHealth = 20
- health = 20
-
+ mob_default_max_health = 20
harm_intent_damage = 8
natural_weapon = /obj/item/natural_weapon/bite
-
min_gas = null
max_gas = null
minbodytemp = 0
-
environment_smash = 1
-
faction = "scarybat"
var/mob/living/owner
diff --git a/code/modules/mob/living/simple_animal/hostile/bear.dm b/code/modules/mob/living/simple_animal/hostile/bear.dm
index 8cd036f1849..f6d7712a7c4 100644
--- a/code/modules/mob/living/simple_animal/hostile/bear.dm
+++ b/code/modules/mob/living/simple_animal/hostile/bear.dm
@@ -12,8 +12,7 @@
see_in_dark = 6
response_harm = "pokes"
stop_automated_movement_when_pulled = 0
- maxHealth = 60
- health = 60
+ mob_default_max_health = 60
natural_weapon = /obj/item/natural_weapon/claws/strong
can_escape = TRUE
faction = "russian"
diff --git a/code/modules/mob/living/simple_animal/hostile/carp.dm b/code/modules/mob/living/simple_animal/hostile/carp.dm
index eed86480e6d..5fcc88f7544 100644
--- a/code/modules/mob/living/simple_animal/hostile/carp.dm
+++ b/code/modules/mob/living/simple_animal/hostile/carp.dm
@@ -5,9 +5,7 @@
speak_chance = 0
turns_per_move = 3
speed = 2
- maxHealth = 50
- health = 50
-
+ mob_default_max_health = 50
harm_intent_damage = 8
natural_weapon = /obj/item/natural_weapon/bite
pry_time = 10 SECONDS
@@ -34,8 +32,8 @@
update_icon()
/mob/living/simple_animal/hostile/carp/proc/carp_randomify()
- maxHealth = rand(initial(maxHealth), (1.5 * initial(maxHealth)))
- health = maxHealth
+ mob_default_max_health = rand(initial(mob_default_max_health), (1.5 * initial(mob_default_max_health)))
+ current_health = mob_default_max_health
if(prob(1))
carp_color = pick(COLOR_WHITE, COLOR_BLACK)
else
diff --git a/code/modules/mob/living/simple_animal/hostile/commanded/bear_companion.dm b/code/modules/mob/living/simple_animal/hostile/commanded/bear_companion.dm
index c8a813acc0b..9057661d22f 100644
--- a/code/modules/mob/living/simple_animal/hostile/commanded/bear_companion.dm
+++ b/code/modules/mob/living/simple_animal/hostile/commanded/bear_companion.dm
@@ -2,8 +2,7 @@
name = "bear"
desc = "A large brown bear."
icon = 'icons/mob/simple_animal/bear_brown.dmi'
- health = 75
- maxHealth = 75
+ mob_default_max_health = 75
density = TRUE
natural_weapon = /obj/item/natural_weapon/claws
can_escape = TRUE
diff --git a/code/modules/mob/living/simple_animal/hostile/commanded/nanomachines.dm b/code/modules/mob/living/simple_animal/hostile/commanded/nanomachines.dm
index 680471b3996..2844891e93b 100644
--- a/code/modules/mob/living/simple_animal/hostile/commanded/nanomachines.dm
+++ b/code/modules/mob/living/simple_animal/hostile/commanded/nanomachines.dm
@@ -6,8 +6,7 @@
desc = "a cloud of tiny, tiny robots."
icon = 'icons/mob/simple_animal/nanomachines.dmi'
natural_weapon = /obj/item/natural_weapon/nanomachine
- health = 10
- maxHealth = 10
+ mob_default_max_health = 10
can_escape = TRUE
known_commands = list("stay", "stop", "attack", "follow", "heal", "emergency protocol")
gene_damage = -1
@@ -15,6 +14,7 @@
response_help_3p = "$USER$ waves $USER_HIS$ hand through $TARGET$."
response_harm = "agitates"
response_disarm = "fans at"
+ ai = /datum/ai/nanomachines
var/regen_time = 0
var/emergency_protocols = 0
@@ -25,20 +25,28 @@
force = 2
sharp = TRUE
-/mob/living/simple_animal/hostile/commanded/nanomachine/Life()
- regen_time++
- if(regen_time == 2 && health < maxHealth) //slow regen
- regen_time = 0
- health++
+/datum/ai/nanomachines
+ expected_type = /mob/living/simple_animal/hostile/commanded/nanomachine
+
+/datum/ai/nanomachines/do_process(time_elapsed)
+ . = ..()
+ var/mob/living/simple_animal/hostile/commanded/nanomachine/swarm = body
+ switch(swarm.stance)
+ if(COMMANDED_HEAL)
+ if(!swarm.target_mob)
+ swarm.target_mob = swarm.FindTarget(COMMANDED_HEAL)
+ if(swarm.target_mob)
+ swarm.move_to_heal()
+ if(COMMANDED_HEALING)
+ swarm.heal()
+
+/mob/living/simple_animal/hostile/commanded/nanomachine/handle_living_non_stasis_processes()
. = ..()
if(.)
- switch(stance)
- if(COMMANDED_HEAL)
- if(!target_mob)
- target_mob = FindTarget(COMMANDED_HEAL)
- move_to_heal()
- if(COMMANDED_HEALING)
- heal()
+ regen_time++
+ if(regen_time == 2 && current_health < get_max_health()) //slow regen
+ regen_time = 0
+ heal_overall_damage(1)
/mob/living/simple_animal/hostile/commanded/nanomachine/death(gibbed, deathmessage, show_dead_message)
..(null, "dissipates into thin air", "You have been destroyed.")
@@ -52,20 +60,20 @@
stance = COMMANDED_HEALING
/mob/living/simple_animal/hostile/commanded/nanomachine/proc/heal()
- if(health <= 3 && !emergency_protocols) //dont die doing this.
+ if(current_health <= 3 && !emergency_protocols) //dont die doing this.
return 0
if(!target_mob)
return 0
if(!Adjacent(target_mob) || SA_attackable(target_mob))
stance = COMMANDED_HEAL
return 0
- if(target_mob.stat || target_mob.health >= target_mob.maxHealth) //he's either dead or healthy, move along.
+ if(target_mob.stat || target_mob.current_health >= target_mob.get_max_health()) //he's either dead or healthy, move along.
allowed_targets -= target_mob
target_mob = null
stance = COMMANDED_HEAL
return 0
src.visible_message("\The [src] glows green for a moment, healing \the [target_mob]'s wounds.")
- health -= 3
+ adjustBruteLoss(3)
target_mob.adjustBruteLoss(-5)
target_mob.adjustFireLoss(-5)
diff --git a/code/modules/mob/living/simple_animal/hostile/creature.dm b/code/modules/mob/living/simple_animal/hostile/creature.dm
index ae369e9d1cf..e8e35615a5e 100644
--- a/code/modules/mob/living/simple_animal/hostile/creature.dm
+++ b/code/modules/mob/living/simple_animal/hostile/creature.dm
@@ -3,8 +3,7 @@
desc = "A sanity-destroying otherthing."
icon = 'icons/mob/simple_animal/creature.dmi'
speak_emote = list("gibbers")
- health = 100
- maxHealth = 100
+ mob_default_max_health = 100
natural_weapon = /obj/item/natural_weapon/bite/strong
faction = "creature"
speed = 4
diff --git a/code/modules/mob/living/simple_animal/hostile/drake.dm b/code/modules/mob/living/simple_animal/hostile/drake.dm
index 772bf52b138..c1c26a3184c 100644
--- a/code/modules/mob/living/simple_animal/hostile/drake.dm
+++ b/code/modules/mob/living/simple_animal/hostile/drake.dm
@@ -11,11 +11,8 @@
pry_time = 4 SECONDS
skull_type = /obj/item/whip/tail
bleed_colour = COLOR_VIOLET
-
- health = 200
- maxHealth = 200
+ mob_default_max_health = 200
natural_weapon = /obj/item/natural_weapon/claws/drake
- var/obj/item/whip/tail/tailwhip
natural_armor = list(
ARMOR_MELEE = ARMOR_MELEE_RESISTANT,
ARMOR_ENERGY = ARMOR_ENERGY_SHIELDED,
@@ -24,6 +21,7 @@
)
ability_cooldown = 80 SECONDS
+ var/obj/item/whip/tail/tailwhip
var/empowered_attack = FALSE
var/gas_spent = FALSE
diff --git a/code/modules/mob/living/simple_animal/hostile/faithful_hound.dm b/code/modules/mob/living/simple_animal/hostile/faithful_hound.dm
index 65ddca6a05a..3757a76b27d 100644
--- a/code/modules/mob/living/simple_animal/hostile/faithful_hound.dm
+++ b/code/modules/mob/living/simple_animal/hostile/faithful_hound.dm
@@ -3,8 +3,7 @@
desc = "A spooky looking ghost dog. Does not look friendly."
icon = 'icons/mob/simple_animal/corgi_ghost.dmi'
blend_mode = BLEND_SUBTRACT
- health = 100
- maxHealth = 100
+ mob_default_max_health = 100
natural_weapon = /obj/item/natural_weapon/bite/strong
faction = MOB_FACTION_NEUTRAL
density = FALSE
diff --git a/code/modules/mob/living/simple_animal/hostile/faithless.dm b/code/modules/mob/living/simple_animal/hostile/faithless.dm
index 5fe45352ed9..8c694c3bc8e 100644
--- a/code/modules/mob/living/simple_animal/hostile/faithless.dm
+++ b/code/modules/mob/living/simple_animal/hostile/faithless.dm
@@ -7,8 +7,7 @@
response_help_1p = "You wave your hand through $TARGET$."
response_help_3p = "$USER$ waves $USER_HIS$ hand through $TARGET$."
speed = -1
- maxHealth = 80
- health = 80
+ mob_default_max_health = 80
gene_damage = -1
harm_intent_damage = 10
diff --git a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm
index de7451f128a..34bbaa12507 100644
--- a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm
+++ b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm
@@ -15,8 +15,7 @@
turns_per_move = 5
see_in_dark = 10
response_harm = "pokes"
- maxHealth = 125
- health = 125
+ mob_default_max_health = 125
natural_weapon = /obj/item/natural_weapon/bite
heat_damage_per_tick = 20
cold_damage_per_tick = 20
@@ -65,8 +64,7 @@
/mob/living/simple_animal/hostile/giant_spider/guard
desc = "A monstrously huge brown spider with shimmering eyes."
meat_amount = 4
- maxHealth = 200
- health = 200
+ mob_default_max_health = 200
natural_weapon = /obj/item/natural_weapon/bite/strong
poison_per_bite = 5
speed = 2
@@ -82,8 +80,7 @@
/mob/living/simple_animal/hostile/giant_spider/nurse
desc = "A monstrously huge beige spider with shimmering eyes."
icon = 'icons/mob/simple_animal/spider_beige.dmi'
- maxHealth = 80
- health = 80
+ mob_default_max_health = 80
harm_intent_damage = 6 //soft
poison_per_bite = 5
speed = 0
@@ -98,15 +95,16 @@
var/mob/living/simple_animal/hostile/giant_spider/guard/paired_guard
//things we can't encase in a cocoon
- var/list/cocoon_blacklist = list(/mob/living/simple_animal/hostile/giant_spider,
- /obj/structure/closet)
+ var/static/list/cocoon_blacklist = list(
+ /mob/living/simple_animal/hostile/giant_spider,
+ /obj/structure/closet
+ )
//hunters - the most damage, fast, average health and the only caste tenacious enough to break out of nets
/mob/living/simple_animal/hostile/giant_spider/hunter
desc = "A monstrously huge black spider with shimmering eyes."
icon = 'icons/mob/simple_animal/spider_black.dmi'
- maxHealth = 150
- health = 150
+ mob_default_max_health = 150
natural_weapon = /obj/item/natural_weapon/bite/strong
poison_per_bite = 10
speed = -1
@@ -126,8 +124,7 @@
/mob/living/simple_animal/hostile/giant_spider/spitter
desc = "A monstrously huge iridescent spider with shimmering eyes."
icon = 'icons/mob/simple_animal/spider_purple.dmi'
- maxHealth = 90
- health = 90
+ mob_default_max_health = 90
poison_per_bite = 15
ranged = TRUE
move_to_delay = 2
@@ -148,8 +145,7 @@
. = ..()
/mob/living/simple_animal/hostile/giant_spider/proc/spider_randomify() //random math nonsense to get their damage, health and venomness values
- maxHealth = rand(initial(maxHealth), (1.4 * initial(maxHealth)))
- health = maxHealth
+ set_max_health(rand(initial(mob_default_max_health), (1.4 * initial(mob_default_max_health))))
eye_colour = pick(allowed_eye_colours)
update_icon()
@@ -165,10 +161,10 @@
/mob/living/simple_animal/hostile/giant_spider/AttackingTarget()
. = ..()
if(isliving(.))
- if(health < maxHealth)
+ if(current_health < get_max_health())
var/obj/item/attacking_with = get_natural_weapon()
if(attacking_with)
- health += (0.2 * attacking_with.force) //heal a bit on hit
+ heal_overall_damage(0.2 * attacking_with.force) //heal a bit on hit
if(ishuman(.))
var/mob/living/carbon/human/H = .
var/obj/item/clothing/suit/space/S = H.get_covering_equipped_item_by_zone(BP_CHEST)
@@ -210,6 +206,7 @@ Guard caste procs
expected_type = /mob/living/simple_animal/hostile/giant_spider/guard
/datum/ai/giant_spider/guard/do_process(time_elapsed)
+
. = ..()
var/mob/living/simple_animal/hostile/giant_spider/guard/spooder = body
if(spooder.berserking)
@@ -313,6 +310,7 @@ Nurse caste procs
expected_type = /mob/living/simple_animal/hostile/giant_spider/nurse
/datum/ai/giant_spider/nurse/do_process(time_elapsed)
+
. = ..()
var/mob/living/simple_animal/hostile/giant_spider/nurse/spooder = body
if(spooder.stance != HOSTILE_STANCE_IDLE)
@@ -451,9 +449,11 @@ Hunter caste procs
Spitter caste procs
******************/
/mob/living/simple_animal/hostile/giant_spider/spitter/handle_regular_status_updates()
+
. = ..()
- if(!.)
- return FALSE
+ if(. == PROCESS_KILL)
+ return
+
if(venom_charge <= 0)
ranged = FALSE
if(prob(25))
diff --git a/code/modules/mob/living/simple_animal/hostile/hivebot.dm b/code/modules/mob/living/simple_animal/hostile/hivebot.dm
index 1745767a8fa..41288fd0c28 100644
--- a/code/modules/mob/living/simple_animal/hostile/hivebot.dm
+++ b/code/modules/mob/living/simple_animal/hostile/hivebot.dm
@@ -2,8 +2,7 @@
name = "hivebot"
desc = "A junky looking robot with four spiky legs."
icon = 'icons/mob/simple_animal/hivebot.dmi'
- health = 55
- maxHealth = 55
+ mob_default_max_health = 55
natural_weapon = /obj/item/natural_weapon/drone_slicer
projectilesound = 'sound/weapons/gunshot/gunshot_pistol.ogg'
projectiletype = /obj/item/projectile/beam/smalllaser
@@ -37,8 +36,7 @@
/mob/living/simple_animal/hostile/hivebot/strong
desc = "A junky looking robot with four spiky legs - this one has thick armour plating."
- health = 120
- maxHealth = 120
+ mob_default_max_health = 120
ranged = 1
can_escape = 1
natural_armor = list(
@@ -52,63 +50,6 @@
qdel(src)
return
-/*
-Teleporter beacon, and its subtypes
-*/
-/mob/living/simple_animal/hostile/hivebot/tele // _why is this a mob_
- name = "beacon"
- desc = "Some odd beacon thing."
- icon = 'icons/obj/structures/hivebot_props.dmi'
- icon_state = "def_radar-off"
- health = 200
- maxHealth = 200
- status_flags = 0
- anchored = TRUE
- stop_automated_movement = 1
-
- var/bot_type = /mob/living/simple_animal/hostile/hivebot
- var/bot_amt = 10
- var/spawn_delay = 100
- var/spawn_time = 0
-
-/mob/living/simple_animal/hostile/hivebot/tele/Initialize()
- . = ..()
- var/datum/effect/effect/system/smoke_spread/smoke = new /datum/effect/effect/system/smoke_spread()
- smoke.set_up(5, 0, src.loc)
- smoke.start()
- visible_message("\The [src] warps in!")
- playsound(src.loc, 'sound/effects/EMPulse.ogg', 25, 1)
-
-/mob/living/simple_animal/hostile/hivebot/tele/proc/warpbots()
- while(bot_amt > 0 && bot_type)
- bot_amt--
- var/mob/M = new bot_type(get_turf(src))
- M.faction = faction
- playsound(src.loc, 'sound/effects/teleport.ogg', 50, 1)
- qdel(src)
- return
-
-/mob/living/simple_animal/hostile/hivebot/tele/FindTarget()
- if(..() && !spawn_time)
- spawn_time = world.time + spawn_delay
- visible_message("\The [src] turns on!")
- icon_state = "def_radar"
- return null
-
-/mob/living/simple_animal/hostile/hivebot/tele/Life()
- . = ..()
- if(. && spawn_time && spawn_time <= world.time)
- warpbots()
-
-/mob/living/simple_animal/hostile/hivebot/tele/strong
- bot_type = /mob/living/simple_animal/hostile/hivebot/strong
-
-/mob/living/simple_animal/hostile/hivebot/tele/range
- bot_type = /mob/living/simple_animal/hostile/hivebot/range
-
-/mob/living/simple_animal/hostile/hivebot/tele/rapid
- bot_type = /mob/living/simple_animal/hostile/hivebot/rapid
-
/*
Special projectiles
*/
@@ -140,8 +81,7 @@ The megabot
name = "hivemind"
desc = "A huge quadruped robot equipped with a myriad of weaponry."
icon = 'icons/mob/simple_animal/megabot.dmi'
- health = 440
- maxHealth = 440
+ mob_default_max_health = 440
natural_weapon = /obj/item/natural_weapon/circular_saw
speed = 0
natural_armor = list(
@@ -170,12 +110,9 @@ The megabot
. = ..()
switch_mode(ATTACK_MODE_ROCKET)
-/mob/living/simple_animal/hostile/hivebot/mega/Life()
+/mob/living/simple_animal/hostile/hivebot/mega/handle_regular_status_updates()
. = ..()
- if(!.)
- return
-
- if(!is_on_special_ability_cooldown())
+ if(. && !is_on_special_ability_cooldown())
switch_mode(ATTACK_MODE_ROCKET)
/mob/living/simple_animal/hostile/hivebot/mega/emp_act(severity)
diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm
index c61b702da1c..a1dcf731f89 100644
--- a/code/modules/mob/living/simple_animal/hostile/hostile.dm
+++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm
@@ -182,10 +182,11 @@
..(gibbed, deathmessage, show_dead_message)
walk(src, 0)
-/mob/living/simple_animal/hostile/Life()
+/mob/living/simple_animal/hostile/handle_regular_status_updates()
. = ..()
- if(!.)
- walk(src, 0)
+ if(. == PROCESS_KILL)
+ return
+ walk(src, 0)
/mob/living/simple_animal/hostile/do_delayed_life_action()
..()
@@ -219,9 +220,9 @@
target_mob = null
/mob/living/simple_animal/hostile/attackby(var/obj/item/O, var/mob/user)
- var/oldhealth = health
+ var/oldhealth = current_health
. = ..()
- if(health < oldhealth && !incapacitated(INCAPACITATION_KNOCKOUT))
+ if(current_health < oldhealth && !incapacitated(INCAPACITATION_KNOCKOUT))
target_mob = user
MoveToTarget(move_only = TRUE)
@@ -232,9 +233,9 @@
MoveToTarget(move_only = TRUE)
/mob/living/simple_animal/hostile/bullet_act(var/obj/item/projectile/Proj)
- var/oldhealth = health
+ var/oldhealth = current_health
. = ..()
- if(isliving(Proj.firer) && !target_mob && health < oldhealth && !incapacitated(INCAPACITATION_KNOCKOUT))
+ if(isliving(Proj.firer) && !target_mob && current_health < oldhealth && !incapacitated(INCAPACITATION_KNOCKOUT))
target_mob = Proj.firer
MoveToTarget(move_only = TRUE)
diff --git a/code/modules/mob/living/simple_animal/hostile/leech.dm b/code/modules/mob/living/simple_animal/hostile/leech.dm
index f4df7803aa5..1f73a48752f 100644
--- a/code/modules/mob/living/simple_animal/hostile/leech.dm
+++ b/code/modules/mob/living/simple_animal/hostile/leech.dm
@@ -2,8 +2,7 @@
name = "megaleech"
desc = "A green leech the size of a common snake."
icon = 'icons/mob/simple_animal/megaleech.dmi'
- health = 15
- maxHealth = 15
+ mob_default_max_health = 15
harm_intent_damage = 5
natural_weapon = /obj/item/natural_weapon/bite/weak
pass_flags = PASS_FLAG_TABLE
@@ -20,15 +19,13 @@
adapt_to_current_level()
. = ..()
-/mob/living/simple_animal/hostile/leech/Life()
+/mob/living/simple_animal/hostile/leech/handle_regular_status_updates()
. = ..()
- if(!.)
- return FALSE
-
- if(target_mob)
- belly -= 3
- else
- belly -= 1
+ if(.)
+ if(target_mob)
+ belly -= 3
+ else
+ belly -= 1
/mob/living/simple_animal/hostile/leech/AttackingTarget()
. = ..()
@@ -38,8 +35,8 @@
if(istype(S) && !length(S.breaches))
return
H.remove_blood_simple(suck_potency)
- if(health < maxHealth)
- health += suck_potency / 1.5
+ if(current_health < get_max_health())
+ heal_overall_damage(suck_potency / 1.5)
belly += clamp(suck_potency, 0, 100)
/obj/structure/leech_spawner
diff --git a/code/modules/mob/living/simple_animal/hostile/mimic.dm b/code/modules/mob/living/simple_animal/hostile/mimic.dm
index ee5d20be856..7f4a5c37e0e 100644
--- a/code/modules/mob/living/simple_animal/hostile/mimic.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mimic.dm
@@ -22,15 +22,11 @@ var/global/list/protected_objects = list(/obj/machinery,
icon = 'icons/obj/closets/bases/crate.dmi'
color = COLOR_STEEL
icon_state = "crate"
-
meat_type = /obj/item/chems/food/fish
speed = 4
- maxHealth = 100
- health = 100
-
+ mob_default_max_health = 100
harm_intent_damage = 5
natural_weapon = /obj/item/natural_weapon/bite
-
min_gas = null
max_gas = null
minbodytemp = 0
@@ -78,18 +74,18 @@ var/global/list/protected_objects = list(/obj/machinery,
var/obj/item/attacking_with = get_natural_weapon()
if(istype(O, /obj/structure))
- health = (anchored * 50) + 50
+ current_health = (anchored * 50) + 50
destroy_objects = 1
if(O.density && O.anchored)
knockdown_people = 1
attacking_with.force = 2 * initial(attacking_with.force)
else if(istype(O, /obj/item))
var/obj/item/I = O
- health = 15 * I.w_class
+ current_health = 15 * I.w_class
attacking_with.force = 2 + initial(I.force)
move_to_delay = 2 * I.w_class
- maxHealth = health
+ set_max_health(current_health)
if(creator)
src.creator = weakref(creator)
faction = "\ref[creator]" // very unique
@@ -155,9 +151,9 @@ var/global/list/protected_objects = list(/obj/machinery,
src.visible_message("\The [src] starts to move!")
awake = 1
-/mob/living/simple_animal/hostile/mimic/sleeping/adjustBruteLoss(var/damage)
- trigger()
+/mob/living/simple_animal/hostile/mimic/sleeping/adjustBruteLoss(var/damage, var/do_update_health = FALSE)
..(damage)
+ trigger()
/mob/living/simple_animal/hostile/mimic/sleeping/attack_hand()
trigger()
diff --git a/code/modules/mob/living/simple_animal/hostile/pike.dm b/code/modules/mob/living/simple_animal/hostile/pike.dm
index 33494af88e4..21f7410b5f4 100644
--- a/code/modules/mob/living/simple_animal/hostile/pike.dm
+++ b/code/modules/mob/living/simple_animal/hostile/pike.dm
@@ -7,12 +7,9 @@
attack_same = 1
speed = 1
mob_size = MOB_SIZE_LARGE
-
offset_overhead_text_x = 16
pixel_x = -16
-
- health = 150
- maxHealth = 150
+ mob_default_max_health = 150
harm_intent_damage = 5
natural_weapon = /obj/item/natural_weapon/bite/pike
diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm
index aa1fb734be4..f155bec20a3 100644
--- a/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm
+++ b/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm
@@ -9,8 +9,7 @@
speak_chance = 1
a_intent = I_HURT
stop_automated_movement_when_pulled = 0
- maxHealth = 75
- health = 75
+ mob_default_max_health = 75
speed = -1
harm_intent_damage = 8
can_escape = TRUE
diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/drone.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/drone.dm
index 41de324c3f6..d80d5bc85d0 100644
--- a/code/modules/mob/living/simple_animal/hostile/retaliate/drone.dm
+++ b/code/modules/mob/living/simple_animal/hostile/retaliate/drone.dm
@@ -12,8 +12,7 @@
emote_see = list("beeps menacingly","whirrs threateningly","scans its immediate vicinity")
a_intent = I_HURT
stop_automated_movement_when_pulled = 0
- health = 300
- maxHealth = 300
+ mob_default_max_health = 300
speed = 8
move_to_delay = 6
projectiletype = /obj/item/projectile/beam/drone
@@ -86,8 +85,13 @@
. -= M
//self repair systems have a chance to bring the drone back to life
-/mob/living/simple_animal/hostile/retaliate/malf_drone/Life()
-
+/mob/living/simple_animal/hostile/retaliate/malf_drone/handle_living_non_stasis_processes()
+ . = ..()
+ if(!.)
+ return
+ . = ..()
+ if(. == PROCESS_KILL)
+ return
//emps and lots of damage can temporarily shut us down
if(disabled > 0)
set_stat(UNCONSCIOUS)
@@ -103,7 +107,8 @@
if(prob(1))
src.visible_message("[html_icon(src)] [src] shudders and shakes as some of it's damaged systems come back online.")
spark_at(src, cardinal_only = TRUE)
- health += rand(25,100)
+ adjustBruteLoss(-(rand(10,50)))
+ adjustFireLoss(-(rand(10,50)))
//spark for no reason
if(prob(5))
@@ -112,15 +117,16 @@
//sometimes our targetting sensors malfunction, and we attack anyone nearby
Haywire()
- if(health / maxHealth > 0.9)
+ var/current_health_ratio = get_health_ratio()
+ if(current_health_ratio > 0.9)
explode_chance = 0
- else if(health / maxHealth > 0.7)
+ else if(current_health_ratio > 0.7)
explode_chance = 0
- else if(health / maxHealth > 0.5)
+ else if(current_health_ratio > 0.5)
explode_chance = 0.5
- else if(health / maxHealth > 0.3)
+ else if(current_health_ratio > 0.3)
explode_chance = 5
- else if(health > 0)
+ else if(current_health > 0)
//if health gets too low, shut down
exploding = 0
if(!disabled)
@@ -147,36 +153,39 @@
if(!disabled && exploding)
explosion(get_turf(src), 0, 1, 4, 7)
death()
- ..()
+
update_icon()
/mob/living/simple_animal/hostile/retaliate/malf_drone/on_update_icon()
. = ..()
if(stat != DEAD)
- if(health / maxHealth <= 0.3)
+ var/current_max_health = get_max_health()
+ if(current_health / current_max_health <= 0.3)
icon_state = "[icon_state]-shield3"
- else if(health / maxHealth <= 0.5)
+ else if(current_health / current_max_health <= 0.5)
icon_state = "[icon_state]-shield1"
- else if(health / maxHealth <= 0.7)
+ else if(current_health / current_max_health <= 0.7)
icon_state = "[icon_state]-shield2"
//ion rifle!
/mob/living/simple_animal/hostile/retaliate/malf_drone/emp_act(severity)
- health -= rand(3,15) * (severity + 1)
+ adjustFireLoss(rand(3,15) * (severity + 1))
disabled = rand(150, 600)
hostile_drone = 0
walk(src,0)
/mob/living/simple_animal/hostile/retaliate/malf_drone/death()
..(null,"suddenly breaks apart.", "You have been destroyed.")
- qdel(src)
+ physically_destroyed()
/mob/living/simple_animal/hostile/retaliate/malf_drone/Destroy()
QDEL_NULL(ion_trail)
+ return ..()
+
+/mob/living/simple_animal/hostile/retaliate/malf_drone/physically_destroyed(skip_qdel)
//some random debris left behind
if(has_loot)
spark_at(src, cardinal_only = TRUE)
-
var/atom/movable/M
for(var/mat in debris)
for(var/chance in list(100, 75, 50, 25))
@@ -185,10 +194,8 @@
M = SSmaterials.create_object(mat, loc, 1, debris[mat])
if(istype(M))
step_to(M, get_turf(pick(view(7, src))))
-
//also drop dummy circuit boards deconstructable for research (loot)
var/obj/item/stock_parts/circuitboard/C
-
//spawn 1-4 boards of a random type
var/spawnees = 0
var/num_boards = rand(1,4)
@@ -197,57 +204,46 @@
var/chosen = pick(options)
options.Remove(options.Find(chosen))
spawnees |= chosen
-
if(spawnees & 1)
C = new(src.loc)
C.SetName("Drone CPU motherboard")
C.origin_tech = "{'[TECH_DATA]':[rand(3, 6)]}"
-
if(spawnees & 2)
C = new(src.loc)
C.SetName("Drone neural interface")
C.origin_tech = "{'[TECH_BIO]':[rand(3, 6)]}"
-
if(spawnees & 4)
C = new(src.loc)
C.SetName("Drone suspension processor")
C.origin_tech = "{'[TECH_MAGNET]':[rand(3, 6)]}"
-
if(spawnees & 8)
C = new(src.loc)
C.SetName("Drone shielding controller")
C.origin_tech = "{'wormholes':[rand(3, 6)]}"
-
if(spawnees & 16)
C = new(src.loc)
C.SetName("Drone power capacitor")
C.origin_tech = "{'[TECH_POWER]':[rand(3, 6)]}"
-
if(spawnees & 32)
C = new(src.loc)
C.SetName("Drone hull reinforcer")
C.origin_tech = "{'[TECH_MATERIAL]':[rand(3, 6)]}"
-
if(spawnees & 64)
C = new(src.loc)
C.SetName("Drone auto-repair system")
C.origin_tech = "{'[TECH_ENGINEERING]':[rand(3, 6)]}"
-
if(spawnees & 128)
C = new(src.loc)
C.SetName("Drone antigravity overcharge counter")
C.origin_tech = "{'[TECH_EXOTIC_MATTER]':[rand(3, 6)]}"
-
if(spawnees & 256)
C = new(src.loc)
C.SetName("Drone targetting circuitboard")
C.origin_tech = "{'[TECH_COMBAT]':[rand(3, 6)]}"
-
if(spawnees & 512)
C = new(src.loc)
C.SetName("Corrupted drone morality core")
C.origin_tech = "{'[TECH_ESOTERIC]':[rand(3, 6)]}"
-
return ..()
/obj/item/projectile/beam/drone
diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/exoplanet.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/exoplanet.dm
index 4d21397a002..4983755ffee 100644
--- a/code/modules/mob/living/simple_animal/hostile/retaliate/exoplanet.dm
+++ b/code/modules/mob/living/simple_animal/hostile/retaliate/exoplanet.dm
@@ -40,7 +40,7 @@
var/turf/T = get_turf(S)
var/obj/item/remains/xeno/X = new(T)
X.desc += "These look like they belong to \a [S.name]."
- beast.adjust_nutrition(5 * S.maxHealth)
+ beast.adjust_nutrition(5 * S.get_max_health())
if(prob(5))
S.gib()
else
@@ -74,8 +74,7 @@
faction = "samak"
icon = 'icons/mob/simple_animal/samak.dmi'
move_to_delay = 2
- maxHealth = 125
- health = 125
+ mob_default_max_health = 125
speed = 2
natural_weapon = /obj/item/natural_weapon/claws
cold_damage_per_tick = 0
@@ -97,8 +96,7 @@
faction = "diyaab"
icon = 'icons/mob/simple_animal/diyaab.dmi'
move_to_delay = 1
- maxHealth = 25
- health = 25
+ mob_default_max_health = 25
speed = 1
natural_weapon = /obj/item/natural_weapon/claws/weak
cold_damage_per_tick = 0
@@ -114,8 +112,7 @@
faction = "shantak"
icon = 'icons/mob/simple_animal/shantak.dmi'
move_to_delay = 1
- maxHealth = 75
- health = 75
+ mob_default_max_health = 75
speed = 1
natural_weapon = /obj/item/natural_weapon/claws
cold_damage_per_tick = 0
@@ -154,8 +151,7 @@
faction = "crab"
icon = 'icons/mob/simple_animal/royalcrab.dmi'
move_to_delay = 3
- maxHealth = 150
- health = 150
+ mob_default_max_health = 150
speed = 1
natural_weapon = /obj/item/natural_weapon/pincers
speak_chance = 1
@@ -169,8 +165,7 @@
desc = "A huge grubby creature."
icon = 'icons/mob/simple_animal/char.dmi'
mob_size = MOB_SIZE_LARGE
- health = 45
- maxHealth = 45
+ mob_default_max_health = 45
natural_weapon = /obj/item/natural_weapon/charbaby
speed = 2
return_damage_min = 2
diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/giant_crab.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/giant_crab.dm
index e2a46068216..3741cbb8e78 100644
--- a/code/modules/mob/living/simple_animal/hostile/retaliate/giant_crab.dm
+++ b/code/modules/mob/living/simple_animal/hostile/retaliate/giant_crab.dm
@@ -13,8 +13,7 @@
break_stuff_probability = 15
faction = "crabs"
pry_time = 2 SECONDS
- health = 350
- maxHealth = 350
+ mob_default_max_health = 350
natural_weapon = /obj/item/natural_weapon/pincers/giant
return_damage_min = 2
return_damage_max = 5
@@ -38,7 +37,7 @@
/datum/ai/giant_crab/do_process(time_elapsed)
. = ..()
var/mob/living/simple_animal/hostile/retaliate/giant_crab/crab = body
- if((crab.health > crab.maxHealth / 1.5) && length(crab.enemies) && prob(10))
+ if((crab.current_health > crab.get_max_health() / 1.5) && length(crab.enemies) && prob(10))
if(crab.victim)
crab.release_grab()
crab.enemies = list()
diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/giant_parrot/giant_parrot.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/giant_parrot/giant_parrot.dm
index d8e6e5347ad..1d99e3edc4c 100644
--- a/code/modules/mob/living/simple_animal/hostile/retaliate/giant_parrot/giant_parrot.dm
+++ b/code/modules/mob/living/simple_animal/hostile/retaliate/giant_parrot/giant_parrot.dm
@@ -2,8 +2,7 @@
name = "space parrot"
desc = "It could be some all-knowing being that, for reasons we could never hope to understand, is assuming the shape and general mannerisms of a parrot - or just a rather large bird."
gender = FEMALE
- health = 750 //how sweet it is to be a god!
- maxHealth = 750
+ mob_default_max_health = 750
mob_size = MOB_SIZE_LARGE
speak = list("...")
speak_emote = list("professes","speaks unto you","elaborates","proclaims")
@@ -69,15 +68,13 @@
subspecies = list(/decl/parrot_subspecies/black)
get_subspecies_name = FALSE
natural_weapon = /obj/item/natural_weapon/large
- health = 300
- maxHealth = 300
+ mob_default_max_health = 300
/mob/living/simple_animal/hostile/retaliate/parrot/space/megafauna
name = "giant parrot"
desc = "A huge parrot-like bird."
get_subspecies_name = FALSE
- health = 350
- maxHealth = 350
+ mob_default_max_health = 350
speak_emote = list("squawks")
emote_hear = list("preens itself")
natural_weapon = /obj/item/natural_weapon/large
diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/goose.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/goose.dm
index f46d7bfd3bb..d0b1e8afcff 100644
--- a/code/modules/mob/living/simple_animal/hostile/retaliate/goose.dm
+++ b/code/modules/mob/living/simple_animal/hostile/retaliate/goose.dm
@@ -7,8 +7,7 @@
emote_hear = list("honks","flaps its wings","clacks")
emote_see = list("flaps its wings", "scratches the ground")
natural_weapon = /obj/item/natural_weapon/goosefeet
- health = 45
- maxHealth = 45
+ mob_default_max_health = 45
pass_flags = PASS_FLAG_TABLE
faction = "geese"
pry_time = 8 SECONDS
@@ -54,8 +53,9 @@
attacking_with.force = min((attacking_with.force + potency), max_damage)
if(!loose && prob(25) && (attacking_with && attacking_with.force >= loose_threshold)) //second wind
loose = TRUE
- health = (initial(health) * 1.5)
- maxHealth = (initial(maxHealth) * 1.5)
+ set_max_health(initial(mob_default_max_health) * 1.5)
+ setBruteLoss(0)
+ setFireLoss(0)
enrage_potency = enrage_potency_loose
desc += " The [name] is loose! Oh no!"
update_icon()
@@ -64,8 +64,7 @@
name = "dire goose"
desc = "A large bird. It radiates destructive energy."
icon = 'icons/mob/simple_animal/goose_dire.dmi'
- health = 250
- maxHealth = 250
+ mob_default_max_health = 250
enrage_potency = 3
loose_threshold = 20
max_damage = 35
diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/jelly.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/jelly.dm
index 0f42951111e..9ed588b544e 100644
--- a/code/modules/mob/living/simple_animal/hostile/retaliate/jelly.dm
+++ b/code/modules/mob/living/simple_animal/hostile/retaliate/jelly.dm
@@ -4,8 +4,7 @@
faction = "zeq"
icon = 'icons/mob/simple_animal/jelly.dmi'
move_to_delay = 1
- maxHealth = 75
- health = 75
+ mob_default_max_health = 75
speed = 1
natural_weapon = /obj/item/natural_weapon/tentecles
speak_chance = 1
@@ -30,8 +29,7 @@
/mob/living/simple_animal/hostile/retaliate/jelly/mega
name = "zeq queen"
desc = "A gigantic jellyfish-like creature. Its bell wobbles about almost as if it's ready to burst."
- maxHealth = 300
- health = 300
+ mob_default_max_health = 300
gets_random_color = FALSE
can_escape = TRUE
@@ -69,8 +67,7 @@
/mob/living/simple_animal/hostile/retaliate/jelly/mega/half
name = "zeq duchess"
desc = "A huge jellyfish-like creature."
- maxHealth = 150
- health = 150
+ mob_default_max_health = 150
can_escape = TRUE
jelly_scale = 1.5
split_type = /mob/living/simple_animal/hostile/retaliate/jelly/mega/quarter
@@ -78,8 +75,7 @@
/mob/living/simple_animal/hostile/retaliate/jelly/mega/quarter
name = "zeqling"
desc = "A jellyfish-like creature."
- health = 75
- maxHealth = 75
+ mob_default_max_health = 75
jelly_scale = 0.75
can_escape = FALSE
split_type = /mob/living/simple_animal/hostile/retaliate/jelly/mega/fourth
@@ -87,15 +83,13 @@
/mob/living/simple_animal/hostile/retaliate/jelly/mega/fourth
name = "zeqetta"
desc = "A tiny jellyfish-like creature."
- health = 40
- maxHealth = 40
+ mob_default_max_health = 40
jelly_scale = 0.375
split_type = /mob/living/simple_animal/hostile/retaliate/jelly/mega/eighth
/mob/living/simple_animal/hostile/retaliate/jelly/mega/eighth
name = "zeqttina"
desc = "An absolutely tiny jellyfish-like creature."
- health = 20
- maxHealth = 20
+ mob_default_max_health = 20
jelly_scale = 0.1875
split_type = null
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/king_of_goats.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/king_of_goats.dm
index a0d3ce2685e..202f1507273 100644
--- a/code/modules/mob/living/simple_animal/hostile/retaliate/king_of_goats.dm
+++ b/code/modules/mob/living/simple_animal/hostile/retaliate/king_of_goats.dm
@@ -13,8 +13,7 @@
emote_see = list("stamps a mighty foot, shaking the surroundings")
meat_amount = 12
response_harm = "assaults"
- health = 500
- maxHealth = 500
+ mob_default_max_health = 500
mob_size = MOB_SIZE_LARGE
mob_bump_flag = HEAVY
can_escape = TRUE
@@ -59,8 +58,7 @@
desc = "The King of Kings, God amongst men, and your superior in every way."
icon = 'icons/mob/simple_animal/goat_king_phase_2.dmi'
meat_amount = 36
- health = 750
- maxHealth = 750
+ mob_default_max_health = 750
natural_weapon = /obj/item/natural_weapon/goatking/unleashed
elemental_weapons = list(
BURN = /obj/item/natural_weapon/goatking/fire/unleashed,
@@ -94,8 +92,7 @@
name = "honour guard"
desc = "A very handsome and noble beast."
icon = 'icons/mob/simple_animal/goat_guard.dmi'
- health = 125
- maxHealth = 125
+ mob_default_max_health = 125
natural_weapon = /obj/item/natural_weapon/goathorns
/obj/item/natural_weapon/goathorns
@@ -108,8 +105,7 @@
name = "master of the guard"
desc = "A very handsome and noble beast - the most trusted of all the king's men."
icon = 'icons/mob/simple_animal/goat_master.dmi'
- health = 200
- maxHealth = 200
+ mob_default_max_health = 200
natural_weapon = /obj/item/natural_weapon/goathorns
move_to_delay = 3
@@ -157,15 +153,16 @@
visible_message("\The [src]' eyes begin to glow ominously as dust and debris in the area is kicked up in a light breeze.")
stop_automation = TRUE
if(do_after(src, 6 SECONDS, src))
- var/health_holder = health
+ var/initial_brute = getBruteLoss()
+ var/initial_burn = getFireLoss()
visible_message(SPAN_MFAUNA("\The [src] raises its fore-hooves and stomps them into the ground with incredible force!"))
explosion(get_step(src,pick(global.cardinal)), -1, 2, 2, 3, 6)
explosion(get_step(src,pick(global.cardinal)), -1, 1, 4, 4, 6)
explosion(get_step(src,pick(global.cardinal)), -1, 3, 4, 3, 6)
stop_automation = FALSE
spellscast += 2
- if(!health < health_holder)
- health = health_holder //our own magicks cannot harm us
+ setBruteLoss(initial_brute)
+ setFireLoss(initial_burn)
else
visible_message(SPAN_NOTICE("The [src] loses concentration and huffs haughtily."))
stop_automation = FALSE
@@ -175,7 +172,8 @@
/mob/living/simple_animal/hostile/retaliate/goat/king/phase2/proc/phase3_transition()
phase3 = TRUE
spellscast = 0
- health = 750
+ mob_default_max_health = 750
+ current_health = mob_default_max_health
new /obj/item/grenade/flashbang/instant(src.loc)
QDEL_NULL(boss_theme)
boss_theme = play_looping_sound(src, sound_id, 'sound/music/Visager-Miniboss_Fight.ogg', volume = 10, range = 8, falloff = 4, prefer_mute = TRUE)
@@ -192,15 +190,14 @@
set_scale(1.25)
default_pixel_y = 10
-/mob/living/simple_animal/hostile/retaliate/goat/king/phase2/Life()
+/mob/living/simple_animal/hostile/retaliate/goat/king/phase2/handle_living_non_stasis_processes()
. = ..()
- if(!.)
- return FALSE
+ if(. == PROCESS_KILL)
+ return
if(special_attacks >= 6 && current_damtype != BRUTE)
visible_message(SPAN_MFAUNA("The energy surrounding \the [src]'s horns dissipates."))
current_damtype = BRUTE
-
- if(health <= 150 && !phase3 && spellscast == 5) //begin phase 3, reset spell limit and heal
+ if(current_health <= 150 && !phase3 && spellscast == 5) //begin phase 3, reset spell limit and heal
phase3_transition()
/mob/living/simple_animal/hostile/retaliate/goat/king/proc/OnDeath()
@@ -235,6 +232,6 @@
. = ..()
if(current_damtype != BRUTE)
special_attacks++
-
+
/mob/living/simple_animal/hostile/retaliate/goat/king/Process_Spacemove()
return 1
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/parrot.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/parrot.dm
index 33b51b3f832..75db2f235ac 100644
--- a/code/modules/mob/living/simple_animal/hostile/retaliate/parrot.dm
+++ b/code/modules/mob/living/simple_animal/hostile/retaliate/parrot.dm
@@ -125,7 +125,7 @@
parrot_state = PARROT_SWOOP //The parrot just got hit, it WILL move, now to pick a direction..
if(isliving(user))
var/mob/living/M = user
- if(M.health < 50) //Weakened mob? Fight back!
+ if(M.current_health < 50) //Weakened mob? Fight back!
parrot_state |= PARROT_ATTACK
return
parrot_state |= PARROT_FLEE //Otherwise, fly like a bat out of hell!
diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/retaliate.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/retaliate.dm
index 4c0ea689fc7..706053d576b 100644
--- a/code/modules/mob/living/simple_animal/hostile/retaliate/retaliate.dm
+++ b/code/modules/mob/living/simple_animal/hostile/retaliate/retaliate.dm
@@ -42,8 +42,8 @@
H.enemies |= enemies
return 0
-/mob/living/simple_animal/hostile/retaliate/adjustBruteLoss(var/damage)
- ..(damage)
+/mob/living/simple_animal/hostile/retaliate/adjustBruteLoss(var/damage, var/do_update_health = FALSE)
+ ..()
Retaliate()
/mob/living/simple_animal/hostile/retaliate/buckle_mob(mob/living/M)
diff --git a/code/modules/mob/living/simple_animal/hostile/slug.dm b/code/modules/mob/living/simple_animal/hostile/slug.dm
index 5248b648d33..76485431e6f 100644
--- a/code/modules/mob/living/simple_animal/hostile/slug.dm
+++ b/code/modules/mob/living/simple_animal/hostile/slug.dm
@@ -5,8 +5,7 @@
icon = 'icons/mob/simple_animal/slug.dmi'
response_harm = "stomps on"
destroy_surroundings = 0
- health = 15
- maxHealth = 15
+ mob_default_max_health = 15
speed = 0
move_to_delay = 0
density = TRUE
@@ -51,9 +50,11 @@
if(prob(H.getBruteLoss()/2))
attach(H)
-/mob/living/simple_animal/hostile/slug/Life()
+/mob/living/simple_animal/hostile/slug/handle_regular_status_updates()
. = ..()
- if(. && istype(src.loc, /obj/item/holder) && isliving(src.loc.loc)) //We in somebody
+ if(. == PROCESS_KILL)
+ return
+ if(istype(src.loc, /obj/item/holder) && isliving(src.loc.loc)) //We in somebody
var/mob/living/L = src.loc.loc
if(src.loc in L.get_visible_implants(0))
if(prob(1))
diff --git a/code/modules/mob/living/simple_animal/hostile/tree.dm b/code/modules/mob/living/simple_animal/hostile/tree.dm
index ab78665df9d..bf3bb61bbcc 100644
--- a/code/modules/mob/living/simple_animal/hostile/tree.dm
+++ b/code/modules/mob/living/simple_animal/hostile/tree.dm
@@ -6,11 +6,8 @@
turns_per_move = 5
meat_type = /obj/item/chems/food/fish
speed = -1
- maxHealth = 250
- health = 250
-
+ mob_default_max_health = 250
pixel_x = -16
-
harm_intent_damage = 5
natural_weapon = /obj/item/natural_weapon/bite
diff --git a/code/modules/mob/living/simple_animal/hostile/vagrant.dm b/code/modules/mob/living/simple_animal/hostile/vagrant.dm
index c0f8e6a2196..3b7a685d0d0 100644
--- a/code/modules/mob/living/simple_animal/hostile/vagrant.dm
+++ b/code/modules/mob/living/simple_animal/hostile/vagrant.dm
@@ -3,8 +3,7 @@
name = "creature"
desc = "You get the feeling you should run."
icon = 'icons/mob/simple_animal/vagrant.dmi'
- maxHealth = 60
- health = 20
+ mob_default_max_health = 60
speed = 5
speak_chance = 0
turns_per_move = 4
@@ -18,35 +17,35 @@
max_gas = null
minbodytemp = 0
gene_damage = -1
+ pass_flags = PASS_FLAG_TABLE
+ bleed_colour = "#aad9de"
+ nutrition = 100
var/cloaked = 0
var/mob/living/carbon/human/gripping = null
var/blood_per_tick = 3
var/health_per_tick = 0.8
- pass_flags = PASS_FLAG_TABLE
-
- bleed_colour = "#aad9de"
/mob/living/simple_animal/hostile/vagrant/Process_Spacemove()
return 1
/mob/living/simple_animal/hostile/vagrant/bullet_act(var/obj/item/projectile/Proj)
- var/oldhealth = health
+ var/oldhealth = current_health
. = ..()
- if(isliving(Proj.firer) && (target_mob != Proj.firer) && health < oldhealth && !incapacitated(INCAPACITATION_KNOCKOUT)) //Respond to being shot at
+ if(isliving(Proj.firer) && (target_mob != Proj.firer) && current_health < oldhealth && !incapacitated(INCAPACITATION_KNOCKOUT)) //Respond to being shot at
target_mob = Proj.firer
turns_per_move = 3
MoveToTarget()
/mob/living/simple_animal/hostile/vagrant/death(gibbed)
. = ..()
- if(. && !gibbed)
+ if(stat == DEAD && !QDELETED(src) && !gibbed)
gib()
-/mob/living/simple_animal/hostile/vagrant/Life()
+/mob/living/simple_animal/hostile/vagrant/handle_living_non_stasis_processes()
. = ..()
- if(!.)
- return FALSE
+ if(. == PROCESS_KILL)
+ return
if(gripping)
if(!(get_turf(src) == get_turf(gripping)))
gripping = null
@@ -55,9 +54,9 @@
var/blood_volume = round(gripping.vessel.total_volume)
if(blood_volume > 5)
gripping.vessel.remove_any(blood_per_tick)
- health = min(health + health_per_tick, maxHealth)
+ heal_overall_damage(health_per_tick)
if(prob(15))
- to_chat(gripping, "You feel your fluids being drained!")
+ to_chat(gripping, SPAN_DANGER("You feel your fluids being drained!"))
else
gripping = null
@@ -67,11 +66,11 @@
if(stance == HOSTILE_STANCE_IDLE && !cloaked)
cloaked = 1
update_icon()
- if(health == maxHealth)
+
+ if(get_nutrition() > get_max_nutrition())
new/mob/living/simple_animal/hostile/vagrant(src.loc)
new/mob/living/simple_animal/hostile/vagrant(src.loc)
gib()
- return
/mob/living/simple_animal/hostile/vagrant/on_update_icon()
..()
@@ -96,7 +95,7 @@
return
//This line ensures there's always a reasonable chance of grabbing, while still
//Factoring in health
- if(!gripping && (cloaked || prob(health + ((maxHealth - health) * 2))))
+ if(!gripping && (cloaked || prob(current_health + ((get_max_health() - current_health) * 2))))
gripping = H
cloaked = 0
update_icon()
diff --git a/code/modules/mob/living/simple_animal/hostile/viscerator.dm b/code/modules/mob/living/simple_animal/hostile/viscerator.dm
index cbe04e3dcd9..00d64296634 100644
--- a/code/modules/mob/living/simple_animal/hostile/viscerator.dm
+++ b/code/modules/mob/living/simple_animal/hostile/viscerator.dm
@@ -3,8 +3,7 @@
desc = "A small, twin-bladed machine capable of inflicting very deadly lacerations."
icon = 'icons/mob/simple_animal/viscerator.dmi'
pass_flags = PASS_FLAG_TABLE
- health = 15
- maxHealth = 15
+ mob_default_max_health = 15
natural_weapon = /obj/item/natural_weapon/rotating_blade
faction = "syndicate"
min_gas = null
diff --git a/code/modules/mob/living/simple_animal/shade.dm b/code/modules/mob/living/simple_animal/shade.dm
index d3a41e1684c..282982406c5 100644
--- a/code/modules/mob/living/simple_animal/shade.dm
+++ b/code/modules/mob/living/simple_animal/shade.dm
@@ -3,8 +3,7 @@
real_name = "Shade"
desc = "A bound spirit"
icon = 'icons/mob/simple_animal/shade.dmi'
- maxHealth = 50
- health = 50
+ mob_default_max_health = 50
universal_speak = TRUE
speak_emote = list("hisses")
emote_hear = list("wails","screeches")
@@ -43,13 +42,7 @@
/mob/living/simple_animal/shade/on_defilement()
return
-/mob/living/simple_animal/shade/Life()
- . = ..()
- OnDeathInLife()
-
-/mob/living/simple_animal/shade/proc/OnDeathInLife()
- if(stat == DEAD)
- new /obj/item/ectoplasm (src.loc)
- visible_message(SPAN_WARNING("\The [src] lets out a contented sigh as their form unwinds."))
- ghostize()
- qdel(src)
+/mob/living/simple_animal/shade/death(gibbed, deathmessage, show_dead_message)
+ new /obj/item/ectoplasm (src.loc)
+ ..(deathmessage = "lets out a contented sigh as their form unwinds", show_dead_message = "You have been released from your earthly binds.")
+ qdel(src)
diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm
index 1dfe5c06ae1..bc4b1a16f23 100644
--- a/code/modules/mob/living/simple_animal/simple_animal.dm
+++ b/code/modules/mob/living/simple_animal/simple_animal.dm
@@ -1,7 +1,6 @@
/mob/living/simple_animal
name = "animal"
- health = 20
- maxHealth = 20
+ mob_default_max_health = 20
universal_speak = FALSE
mob_sort_value = 12
@@ -45,7 +44,6 @@
var/maxbodytemp = 350
var/heat_damage_per_tick = 3 //amount of damage applied if animal's body temperature is higher than maxbodytemp
var/cold_damage_per_tick = 2 //same as heat_damage_per_tick, only if the bodytemperature it's lower than minbodytemp
- var/fire_alert = 0
//Atmos effect - Yes, you can make creatures that require arbitrary gasses to survive. N2O is a trace gas and handled separately, hence why it isn't here. It'd be hard to add it. Hard and me don't mix (Yes, yes make all the dick jokes you want with that.) - Errorage
var/list/min_gas = list(/decl/material/gas/oxygen = 5)
@@ -69,7 +67,7 @@
//Null rod stuff
var/supernatural = 0
- var/purge = 0
+ var/purged_time = 0 // TODO: make this a status condition
var/bleed_ticks = 0
var/bleed_colour = COLOR_BLOOD_HUMAN
@@ -171,46 +169,26 @@ var/global/list/simplemob_icon_bitflag_cache = list()
QDEL_NULL(natural_weapon)
. = ..()
-/mob/living/simple_animal/Life()
- if(is_aquatic && !submerged() && stat != DEAD)
- walk(src, 0)
- if(!HAS_STATUS(src, STAT_PARA)) // gated to avoid redundant update_icon() calls.
- SET_STATUS_MAX(src, STAT_PARA, 3)
- update_icon()
+/mob/living/simple_animal/handle_regular_status_updates()
. = ..()
- if(!.)
- return FALSE
- if(z && !living_observers_present(SSmapping.get_connected_levels(z)))
- return
- //Health
- if(stat == DEAD)
- if(health > 0)
- switch_from_dead_to_living_mob_list()
- set_stat(CONSCIOUS)
- set_density(1)
- update_icon()
- return 0
-
- handle_atmos()
-
- if(health <= 0)
- death()
- return
-
- if(health > maxHealth)
- health = maxHealth
-
- handle_supernatural()
- handle_impaired_vision()
-
- if(can_bleed && bleed_ticks > 0)
- handle_bleeding()
-
- delayed_life_action()
- return 1
+ if(.)
+ if(can_bleed && bleed_ticks > 0)
+ handle_bleeding()
+ if(is_aquatic && !submerged())
+ walk(src, 0)
+ if(HAS_STATUS(src, STAT_PARA))
+ SET_STATUS_MAX(src, STAT_PARA, 3)
+ update_icon()
+
+/mob/living/simple_animal/handle_some_updates()
+ . = ..() && (!z || living_observers_present(SSmapping.get_connected_levels(z)))
+
+/mob/living/simple_animal/handle_legacy_ai()
+ . = ..()
+ handle_async_life_action()
// Handles timed stuff in Life()
-/mob/living/simple_animal/proc/delayed_life_action()
+/mob/living/simple_animal/proc/handle_async_life_action()
set waitfor = FALSE
if(performing_delayed_life_action)
return
@@ -260,12 +238,9 @@ var/global/list/simplemob_icon_bitflag_cache = list()
if("emote_see")
visible_emote("[pick(emote_see)].")
-/mob/living/simple_animal/proc/handle_atmos(var/atmos_suitable = 1)
- //Atmos
- if(!loc)
- return
-
- var/datum/gas_mixture/environment = loc.return_air()
+/mob/living/simple_animal/handle_environment(datum/gas_mixture/environment)
+ . = ..()
+ var/atmos_suitable = TRUE
if(environment)
// don't bother checking it twice if we got a supplied FALSE val.
if(atmos_suitable)
@@ -286,14 +261,9 @@ var/global/list/simplemob_icon_bitflag_cache = list()
bodytemperature += ((environment.temperature - bodytemperature) / 5)
if(bodytemperature < minbodytemp)
- fire_alert = 2
adjustBruteLoss(cold_damage_per_tick)
else if(bodytemperature > maxbodytemp)
- fire_alert = 1
adjustBruteLoss(heat_damage_per_tick)
- else
- fire_alert = 0
-
if(!atmos_suitable)
adjustBruteLoss(unsuitable_atmos_damage)
@@ -301,10 +271,6 @@ var/global/list/simplemob_icon_bitflag_cache = list()
O.unbuckle_mob(M)
visible_message(SPAN_DANGER("\The [M] escapes from \the [O]!"))
-/mob/living/simple_animal/proc/handle_supernatural()
- if(purge)
- purge -= 1
-
/mob/living/simple_animal/gib()
..(((mob_icon_state_flags & MOB_ICON_HAS_GIB_STATE) ? "world-gib" : null), TRUE)
@@ -327,7 +293,7 @@ var/global/list/simplemob_icon_bitflag_cache = list()
damage = Proj.damage / 1.5
if(Proj.agony)
damage += Proj.agony / 6
- if(health < Proj.agony * 3)
+ if(current_health < Proj.agony * 3)
SET_STATUS_MAX(src, STAT_PARA, Proj.agony / 20)
visible_message("[src] is stunned momentarily!")
@@ -340,7 +306,7 @@ var/global/list/simplemob_icon_bitflag_cache = list()
. = ..() || list(response_help_3p, response_help_1p)
/mob/living/simple_animal/default_help_interaction(mob/user)
- if(health > 0 && user.attempt_hug(src))
+ if(current_health > 0 && user.attempt_hug(src))
user.update_personal_goal(/datum/goal/achievement/specific_object/pet, type)
return TRUE
. = ..()
@@ -376,7 +342,7 @@ var/global/list/simplemob_icon_bitflag_cache = list()
var/obj/item/stack/medical/MED = O
if(!MED.animal_heal)
to_chat(user, SPAN_WARNING("\The [MED] won't help \the [src] at all!"))
- else if(health < maxHealth && MED.can_use(1))
+ else if(current_health < get_max_health() && MED.can_use(1))
adjustBruteLoss(-MED.animal_heal)
visible_message(SPAN_NOTICE("\The [user] applies \the [MED] to \the [src]."))
MED.use(1)
@@ -430,7 +396,7 @@ var/global/list/simplemob_icon_bitflag_cache = list()
damage = (O.force / 8)
if(supernatural && istype(O,/obj/item/nullrod))
damage *= 2
- purge = 3
+ purged_time = 3
adjustBruteLoss(damage)
if(O.edge || O.sharp)
adjustBleedTicks(damage)
@@ -439,12 +405,11 @@ var/global/list/simplemob_icon_bitflag_cache = list()
/mob/living/simple_animal/get_movement_delay(var/travel_dir)
var/tally = ..() //Incase I need to add stuff other than "speed" later
-
tally += speed
- if(purge)//Purged creatures will move more slowly. The more time before their purge stops, the slower they'll move.
+ if(purged_time)//Purged creatures will move more slowly. The more time before their purge stops, the slower they'll move.
if(tally <= 0)
tally = 1
- tally *= purge
+ tally *= purged_time
return tally+config.animal_delay
@@ -452,11 +417,11 @@ var/global/list/simplemob_icon_bitflag_cache = list()
. = ..()
if(statpanel("Status") && show_stat_health)
- stat(null, "Health: [round((health / maxHealth) * 100)]%")
+ stat(null, "Health: [get_health_percent()]%")
/mob/living/simple_animal/death(gibbed, deathmessage = "dies!", show_dead_message)
density = FALSE
- adjustBruteLoss(maxHealth) //Make sure dey dead.
+ adjustBruteLoss(get_max_health()) //Make sure dey dead.
walk_to(src,0)
. = ..(gibbed,deathmessage,show_dead_message)
@@ -472,26 +437,22 @@ var/global/list/simplemob_icon_bitflag_cache = list()
damage = 30
apply_damage(damage, BRUTE, damage_flags = DAM_EXPLODE)
-/mob/living/simple_animal/adjustBruteLoss(damage)
- ..()
- updatehealth()
+/mob/living/simple_animal/adjustBruteLoss(damage, do_update_health)
+ ..(damage, do_update_health = TRUE)
-/mob/living/simple_animal/adjustFireLoss(damage)
- ..()
- updatehealth()
+/mob/living/simple_animal/adjustFireLoss(damage, do_update_health)
+ ..(damage, do_update_health = TRUE)
-/mob/living/simple_animal/adjustToxLoss(damage)
- ..()
- updatehealth()
+/mob/living/simple_animal/adjustToxLoss(damage, do_update_health)
+ ..(damage, do_update_health = TRUE)
-/mob/living/simple_animal/adjustOxyLoss(damage)
- ..()
- updatehealth()
+/mob/living/simple_animal/adjustOxyLoss(damage, do_update_health)
+ ..(damage, do_update_health = TRUE)
/mob/living/simple_animal/proc/SA_attackable(target_mob)
if (isliving(target_mob))
var/mob/living/L = target_mob
- if(!L.stat && L.health >= 0)
+ if(!L.stat && L.current_health >= 0)
return (0)
return 1
@@ -609,8 +570,9 @@ var/global/list/simplemob_icon_bitflag_cache = list()
/mob/living/simple_animal/setCloneLoss(amount)
if(gene_damage >= 0)
- gene_damage = clamp(amount, 0, maxHealth)
- if(gene_damage >= maxHealth)
+ var/current_max_health = get_max_health()
+ gene_damage = clamp(amount, 0, current_max_health)
+ if(gene_damage >= current_max_health)
death()
/mob/living/simple_animal/get_admin_job_string()
diff --git a/code/modules/mob/living/stasis.dm b/code/modules/mob/living/stasis.dm
index 490b49be8e4..9fc4fa3695f 100644
--- a/code/modules/mob/living/stasis.dm
+++ b/code/modules/mob/living/stasis.dm
@@ -16,6 +16,11 @@
stasis_value += stasis_sources[source]
stasis_sources = null
+ if(stasis_value > 1 && GET_STATUS(src, STAT_DROWSY) < stasis_value * 4)
+ ADJ_STATUS(src, STAT_DROWSY, min(stasis_value, 3))
+ if(stat == CONSCIOUS && prob(1))
+ to_chat(src, SPAN_NOTICE("You feel slow and sluggish..."))
+
/mob/living/proc/get_cryogenic_factor(var/bodytemperature)
if(isSynthetic())
diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm
index 790b2ee8eb7..fba611a84f2 100644
--- a/code/modules/mob/login.dm
+++ b/code/modules/mob/login.dm
@@ -107,15 +107,10 @@
refresh_client_images()
reload_fullscreen() // Reload any fullscreen overlays this mob has.
- add_click_catcher()
+ reset_click_catchers()
update_action_buttons()
update_mouse_pointer()
- if(ability_master)
- ability_master.update_abilities(TRUE, src)
- ability_master.toggle_open(1)
- ability_master.synch_spells_to_mind(mind)
-
if(get_preference_value(/datum/client_preference/show_status_markers) == PREF_SHOW)
if(status_markers?.mob_image_personal)
client.images |= status_markers.mob_image_personal
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index dc258343e95..9dbca7489eb 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -13,8 +13,6 @@
QDEL_NULL(hud_used)
if(active_storage)
active_storage.close(src)
- if(istype(ability_master))
- QDEL_NULL(ability_master)
if(istype(skillset))
QDEL_NULL(skillset)
QDEL_NULL_LIST(grabbed_by)
@@ -22,7 +20,6 @@
if(istype(ai))
QDEL_NULL(ai)
QDEL_NULL(lighting_master)
- remove_screen_obj_references()
if(client)
for(var/atom/movable/AM in client.screen)
var/obj/screen/screenobj = AM
@@ -35,27 +32,6 @@
ghostize()
return ..()
-/mob/proc/remove_screen_obj_references()
- QDEL_NULL_SCREEN(hands)
- QDEL_NULL_SCREEN(internals)
- QDEL_NULL_SCREEN(oxygen)
- QDEL_NULL_SCREEN(toxin)
- QDEL_NULL_SCREEN(fire)
- QDEL_NULL_SCREEN(bodytemp)
- QDEL_NULL_SCREEN(healths)
- QDEL_NULL_SCREEN(throw_icon)
- QDEL_NULL_SCREEN(nutrition_icon)
- QDEL_NULL_SCREEN(hydration_icon)
- QDEL_NULL_SCREEN(pressure)
- QDEL_NULL_SCREEN(pain)
- QDEL_NULL_SCREEN(up_hint)
- QDEL_NULL_SCREEN(item_use_icon)
- QDEL_NULL_SCREEN(radio_use_icon)
- QDEL_NULL_SCREEN(gun_move_icon)
- QDEL_NULL_SCREEN(gun_setting_icon)
- QDEL_NULL_SCREEN(ability_master)
- QDEL_NULL_SCREEN(zone_sel)
-
/mob/Initialize()
if(ispath(skillset))
skillset = new skillset(src)
@@ -235,10 +211,11 @@
/mob/proc/Life()
SHOULD_NOT_SLEEP(TRUE)
+ SHOULD_CALL_PARENT(TRUE)
if(QDELETED(src))
return PROCESS_KILL
- if(ability_master)
- ability_master.update_spells(0)
+ // Alerts will be set by logic higher in the call chain.
+ CLEAR_HUD_ALERTS(src)
#define UNBUCKLED 0
#define PARTIALLY_BUCKLED 1
@@ -700,10 +677,9 @@
return 0
//Updates lying and icons
-/mob/proc/UpdateLyingBuckledAndVerbStatus()
- var/last_lying = lying
+/mob/proc/update_lying()
if(!resting && cannot_stand() && can_stand_overridden())
- lying = 0
+ lying = FALSE
else if(buckled)
anchored = TRUE
if(istype(buckled))
@@ -716,12 +692,16 @@
else
lying = incapacitated(INCAPACITATION_KNOCKDOWN)
+/mob/proc/UpdateLyingBuckledAndVerbStatus()
+ var/last_lying = lying
+ update_lying()
+ if(buckled)
+ anchored = (!istype(buckled) || !buckled.buckle_movable)
if(lying)
set_density(0)
drop_held_items()
else
set_density(initial(density))
-
reset_layer()
//Temporarily moved here from the various life() procs
@@ -962,13 +942,15 @@
/mob/proc/throw_mode_off()
src.in_throw_mode = 0
- if(src.throw_icon) //in case we don't have the HUD and we use the hotkey
- src.throw_icon.icon_state = "act_throw_off"
+ var/obj/screen/throw_icon = get_hud_element(/decl/hud_element/throwing)
+ if(throw_icon) //in case we don't have the HUD and we use the hotkey
+ throw_icon.icon_state = "act_throw_off"
/mob/proc/throw_mode_on()
src.in_throw_mode = 1
- if(src.throw_icon)
- src.throw_icon.icon_state = "act_throw_on"
+ var/obj/screen/throw_icon = get_hud_element(/decl/hud_element/throwing)
+ if(throw_icon)
+ throw_icon.icon_state = "act_throw_on"
/mob/proc/toggle_antag_pool()
set name = "Toggle Add-Antag Candidacy"
@@ -990,7 +972,7 @@
return (!alpha || !mouse_opacity || viewer.see_invisible < invisibility)
/client/proc/check_has_body_select()
- return mob && mob.hud_used && istype(mob.zone_sel, /obj/screen/zone_selector)
+ return istype(mob?.get_hud_element(/decl/hud_element/zone_selector), /obj/screen/zone_selector)
/client/verb/body_toggle_head()
set name = "body-toggle-head"
@@ -1030,8 +1012,9 @@
/client/proc/toggle_zone_sel(list/zones)
if(!check_has_body_select())
return
- var/obj/screen/zone_selector/selector = mob.zone_sel
- selector.set_selected_zone(next_in_list(mob.get_target_zone(),zones))
+ var/obj/screen/zone_selector/selector = mob?.get_hud_element(/decl/hud_element/zone_selector)
+ if(selector)
+ selector.set_selected_zone(next_in_list(selector.selecting, zones))
/mob/proc/has_admin_rights()
return check_rights(R_ADMIN, 0, src)
@@ -1330,8 +1313,18 @@
/mob/proc/toggle_internals(var/mob/living/user)
return
+/mob/Move()
+ . = ..()
+ if(. && client)
+ var/obj/screen/up_hint = get_hud_element(/decl/hud_element/up_hint)
+ if(up_hint)
+ var/turf/above = GetAbove(src)
+ up_hint.icon_state = "uphint[!!(above && TURF_IS_MIMICKING(above))]"
+
/mob/proc/get_target_zone()
- return zone_sel?.selecting
+ var/obj/screen/zone_selector/zone_sel = get_hud_element(/decl/hud_element/zone_selector)
+ if(istype(zone_sel))
+ return zone_sel?.selecting
/mob/proc/get_temperature_threshold(var/threshold)
switch(threshold)
@@ -1361,9 +1354,14 @@
RETURN_TYPE(/obj/item/card/id)
return LAZYACCESS(GetIdCards(exceptions), 1)
+/mob/proc/get_ideal_bodytemp()
+ var/decl/species/my_species = get_species()
+ if(my_species)
+ return (my_species.body_temperature - bodytemperature)
+ return null
+
/mob/get_overhead_text_x_offset()
return offset_overhead_text_x
/mob/get_overhead_text_y_offset()
return offset_overhead_text_y
-
diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm
index 595b81c515b..053c728acd7 100644
--- a/code/modules/mob/mob_defines.dm
+++ b/code/modules/mob/mob_defines.dm
@@ -39,36 +39,6 @@
var/stat = CONSCIOUS //Whether a mob is alive or dead. TODO: Move this to living - Nodrak
- var/obj/screen/cells = null
-
- var/obj/screen/hands = null
- var/obj/screen/internals = null
- var/obj/screen/oxygen = null
- var/obj/screen/toxin = null
- var/obj/screen/fire = null
- var/obj/screen/bodytemp = null
- var/obj/screen/healths = null
- var/obj/screen/throw_icon = null
- var/obj/screen/nutrition_icon = null
- var/obj/screen/hydration_icon = null
- var/obj/screen/pressure = null
- var/obj/screen/pain = null
- var/obj/screen/up_hint = null
- var/obj/screen/gun/item/item_use_icon = null
- var/obj/screen/gun/radio/radio_use_icon = null
- var/obj/screen/gun/move/gun_move_icon = null
- var/obj/screen/gun/mode/gun_setting_icon = null
-
- var/obj/screen/ability_master/ability_master = null
-
- /*A bunch of this stuff really needs to go under their own defines instead of being globally attached to mob.
- A variable should only be globally attached to turfs/objects/whatever, when it is in fact needed as such.
- The current method unnecessarily clusters up the variable list, especially for humans (although rearranging won't really clean it up a lot but the difference will be noticable for other mobs).
- I'll make some notes on where certain variable defines should probably go.
- Changing this around would probably require a good look-over the pre-existing code.
- */
- var/obj/screen/zone_selector/zone_sel = null
-
/// Cursor icon used when holding shift over things.
var/examine_cursor_icon = 'icons/effects/mouse_pointers/examine_pointer.dmi'
diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm
index af0fac10217..481b738892a 100644
--- a/code/modules/mob/mob_helpers.dm
+++ b/code/modules/mob/mob_helpers.dm
@@ -13,7 +13,7 @@
return FALSE //M is too small to wield this
return TRUE
-/mob/living/proc/isSynthetic()
+/mob/proc/isSynthetic()
return 0
/mob/living/carbon/human/isSynthetic()
@@ -371,6 +371,8 @@ var/global/list/intents = list(I_HELP,I_DISARM,I_GRAB,I_HURT)
set name = "a-intent"
set hidden = 1
+ var/obj/screen/action_intent = get_hud_element(/decl/hud_element/action_intent)
+
if(can_change_intent())
switch(input)
if(I_HELP,I_DISARM,I_GRAB,I_HURT)
@@ -379,8 +381,8 @@ var/global/list/intents = list(I_HELP,I_DISARM,I_GRAB,I_HURT)
a_intent = intent_numeric((intent_numeric(a_intent)+1) % 4)
if("left")
a_intent = intent_numeric((intent_numeric(a_intent)+3) % 4)
- if(hud_used && hud_used.action_intent)
- hud_used.action_intent.icon_state = "intent_[a_intent]"
+ if(action_intent)
+ action_intent.icon_state = "intent_[a_intent]"
else if(isrobot(src))
switch(input)
@@ -390,11 +392,11 @@ var/global/list/intents = list(I_HELP,I_DISARM,I_GRAB,I_HURT)
a_intent = I_HURT
if("right","left")
a_intent = intent_numeric(intent_numeric(a_intent) - 3)
- if(hud_used && hud_used.action_intent)
+ if(action_intent)
if(a_intent == I_HURT)
- hud_used.action_intent.icon_state = I_HURT
+ action_intent.icon_state = I_HURT
else
- hud_used.action_intent.icon_state = I_HELP
+ action_intent.icon_state = I_HELP
/mob/proc/welding_eyecheck()
return
diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm
index 621d6b5425a..6791d33cd72 100644
--- a/code/modules/mob/mob_movement.dm
+++ b/code/modules/mob/mob_movement.dm
@@ -279,8 +279,9 @@
/mob/proc/set_move_intent(var/decl/move_intent/next_intent)
if(next_intent && move_intent != next_intent && next_intent.can_be_used_by(src))
move_intent = next_intent
- if(hud_used)
- hud_used.move_intent.icon_state = move_intent.hud_icon_state
+ var/obj/screen/hud_move_intent = get_hud_element(/decl/hud_element/move_intent)
+ if(hud_move_intent)
+ hud_move_intent.icon_state = move_intent.hud_icon_state
return TRUE
return FALSE
diff --git a/code/modules/mob/observer/eye/freelook/life.dm b/code/modules/mob/observer/eye/freelook/life.dm
index 98b9c477e1f..6a8a6975fd7 100644
--- a/code/modules/mob/observer/eye/freelook/life.dm
+++ b/code/modules/mob/observer/eye/freelook/life.dm
@@ -1,7 +1,7 @@
/mob/observer/eye/freelook/Life()
- ..()
+ . = ..()
// If we lost our client, reset the list of visible chunks so they update properly on return
- if(owner == src && !client)
+ if(. && owner == src && !client)
visibleChunks.Cut()
/*else if(owner && !owner.client)
visibleChunks.Cut()*/
diff --git a/code/modules/mob/observer/ghost/ghost.dm b/code/modules/mob/observer/ghost/ghost.dm
index a8a3766c85a..5772b4ca058 100644
--- a/code/modules/mob/observer/ghost/ghost.dm
+++ b/code/modules/mob/observer/ghost/ghost.dm
@@ -108,9 +108,10 @@ Works together with spawning an observer, noted above.
*/
/mob/observer/ghost/Life()
- ..()
- if(!loc) return
- if(!client) return 0
+
+ . = ..()
+ if(!. || !loc || !client)
+ return FALSE
handle_hud_glasses()
diff --git a/code/modules/modular_computers/file_system/programs/research/ai_restorer.dm b/code/modules/modular_computers/file_system/programs/research/ai_restorer.dm
index a304cca0318..17c53f630e9 100644
--- a/code/modules/modular_computers/file_system/programs/research/ai_restorer.dm
+++ b/code/modules/modular_computers/file_system/programs/research/ai_restorer.dm
@@ -29,7 +29,7 @@
if(!A)
return 0
if(href_list["PRG_beginReconstruction"])
- if((A.hardware_integrity() < 100) || (A.backup_capacitor() < 100))
+ if((A.get_health_percent() < 100) || (A.backup_capacitor() < 100))
restoring = 1
return 1
@@ -69,9 +69,9 @@
A.adjustFireLoss(-4)
A.adjustBruteLoss(-4)
A.adjustOxyLoss(-4)
- A.updatehealth()
+ A.update_health()
// If the AI is dead, revive it.
- if (A.health >= -100 && A.stat == DEAD)
+ if (A.stat == DEAD && !A.should_be_dead())
A.set_stat(CONSCIOUS)
A.lying = 0
A.switch_from_dead_to_living_mob_list()
@@ -81,7 +81,7 @@
if(AC)
AC.update_icon()
// Finished restoring
- if((A.hardware_integrity() == 100) && (A.backup_capacitor() == 100))
+ if((A.get_health_percent() == 100) && (A.backup_capacitor() == 100))
restoring = 0
/datum/nano_module/program/computer_aidiag
@@ -106,9 +106,9 @@
data["error"] = "No AI located"
else
data["ai_name"] = A.name
- data["ai_integrity"] = A.hardware_integrity()
+ data["ai_integrity"] = A.get_health_percent()
data["ai_capacitor"] = A.backup_capacitor()
- data["ai_isdamaged"] = (A.hardware_integrity() < 100) || (A.backup_capacitor() < 100)
+ data["ai_isdamaged"] = (A.get_health_percent() < 100) || (A.backup_capacitor() < 100)
data["ai_isdead"] = (A.stat == DEAD)
var/list/all_laws[0]
diff --git a/code/modules/multiz/movement.dm b/code/modules/multiz/movement.dm
index 146964fe469..440cc530bd1 100644
--- a/code/modules/multiz/movement.dm
+++ b/code/modules/multiz/movement.dm
@@ -283,7 +283,6 @@
var/obj/item/organ/external/victim = pick(victims)
victim.dislocate()
to_chat(src, "You feel a sickening pop as your [victim.joint] is wrenched out of the socket.")
- updatehealth()
/mob/living/carbon/human/proc/climb_up(atom/A)
if(!isturf(loc) || !bound_overlay || bound_overlay.destruction_timer || is_physically_disabled()) // This destruction_timer check ideally wouldn't be required, but I'm not awake enough to refactor this to not need it.
diff --git a/code/modules/organs/external/_external.dm b/code/modules/organs/external/_external.dm
index 7fa25d4fee6..d97309a3cff 100644
--- a/code/modules/organs/external/_external.dm
+++ b/code/modules/organs/external/_external.dm
@@ -416,9 +416,8 @@
return
owner.verbs -= /mob/living/carbon/human/proc/undislocate
-/obj/item/organ/external/update_health()
+/obj/item/organ/external/update_organ_health()
damage = min(max_damage, (brute_dam + burn_dam))
- return
//If "in_place" is TRUE will make organs skip their install/uninstall effects and the sub-limbs and internal organs
/obj/item/organ/external/do_install(mob/living/carbon/human/target, obj/item/organ/external/affected, in_place, update_icon, detached)
@@ -601,7 +600,7 @@ This function completely restores a damaged organ to perfect condition.
. = ..() // Clear damage, reapply aspects.
if(owner)
- owner.updatehealth()
+ owner.update_health()
//#TODO: Rejuvination hacks should probably be removed
/obj/item/organ/external/remove_rejuv()
@@ -642,7 +641,7 @@ This function completely restores a damaged organ to perfect condition.
switch(type)
if(BURN) fluid_loss_severity = FLUIDLOSS_WIDE_BURN
if(LASER) fluid_loss_severity = FLUIDLOSS_CONC_BURN
- var/fluid_loss = (damage/(owner.maxHealth - config.health_threshold_dead)) * SPECIES_BLOOD_DEFAULT * fluid_loss_severity
+ var/fluid_loss = (damage/(owner.get_max_health() - config.health_threshold_dead)) * SPECIES_BLOOD_DEFAULT * fluid_loss_severity
owner.remove_blood(fluid_loss)
// first check whether we can widen an existing wound
@@ -889,7 +888,7 @@ Note that amputating the affected organ does in fact remove the infection from t
if(update_surgery)
owner.update_surgery()
if (update_damstate())
- owner.UpdateDamageIcon(1)
+ owner.update_damage_icon(TRUE)
//Updates brute_damn and burn_damn from wound damages. Updates BLEEDING status.
/obj/item/organ/external/proc/update_damages()
diff --git a/code/modules/organs/external/_external_damage.dm b/code/modules/organs/external/_external_damage.dm
index 60b8d217b62..32dab6dae8b 100644
--- a/code/modules/organs/external/_external_damage.dm
+++ b/code/modules/organs/external/_external_damage.dm
@@ -48,7 +48,7 @@
burn = max(burn - spillover, 0)
//If limb took enough damage, try to cut or tear it off
if(owner && loc == owner)
- owner.updatehealth() //droplimb will call updatehealth() again if it does end up being called
+ owner.update_health() //droplimb will call update_health() again if it does end up being called
if((limb_flags & ORGAN_FLAG_CAN_AMPUTATE) && config.limbs_can_break)
var/total_damage = brute_dam + burn_dam + brute + burn + spillover
var/threshold = max_damage * config.organ_health_multiplier
@@ -113,12 +113,12 @@
// sync the organ's damage with its wounds
update_damages()
- owner.updatehealth()
+ owner.update_health()
if(status & ORGAN_BLEEDING)
owner.update_bandages()
if(owner && update_damstate())
- owner.UpdateDamageIcon()
+ owner.update_damage_icon()
if(created_wound && isobj(used_weapon))
var/obj/O = used_weapon
@@ -192,8 +192,8 @@
status &= ~ORGAN_BROKEN
//Sync the organ's damage with its wounds
- src.update_damages()
- owner.updatehealth()
+ update_damages()
+ owner.update_health()
return update_damstate()
diff --git a/code/modules/organs/internal/heart.dm b/code/modules/organs/internal/heart.dm
index b8a1e9d9d8b..e160e318278 100644
--- a/code/modules/organs/internal/heart.dm
+++ b/code/modules/organs/internal/heart.dm
@@ -70,7 +70,7 @@
return
else //and if it's beating, let's see if it should
var/should_stop = prob(80) && owner.get_blood_circulation() < BLOOD_VOLUME_SURVIVE //cardiovascular shock, not enough liquid to pump
- should_stop = should_stop || prob(max(0, owner.getBrainLoss() - owner.maxHealth * 0.75)) //brain failing to work heart properly
+ should_stop = should_stop || prob(max(0, owner.getBrainLoss() - owner.get_max_health() * 0.75)) //brain failing to work heart properly
should_stop = should_stop || (prob(5) && pulse == PULSE_THREADY) //erratic heart patterns, usually caused by oxyloss
if(should_stop) // The heart has stopped due to going into traumatic or cardiovascular shock.
to_chat(owner, "Your heart has stopped!")
diff --git a/code/modules/organs/internal/lungs.dm b/code/modules/organs/internal/lungs.dm
index a5e4ca1812e..b40d49ca4a1 100644
--- a/code/modules/organs/internal/lungs.dm
+++ b/code/modules/organs/internal/lungs.dm
@@ -199,12 +199,12 @@
to_chat(owner, SPAN_NOTICE("It gets easier to breathe."))
breath_fail_ratio = clamp(0,breath_fail_ratio-0.05,1)
- owner.oxygen_alert = failed_inhale * 2
-
+ var/alert_val = (failed_inhale * 2)
+ SET_HUD_ALERT(owner, /decl/hud_element/condition/oxygen, alert_val)
var/inhaled_gas_used = inhaling / 4
breath.adjust_gas(breath_type, -inhaled_gas_used, update = 0) //update afterwards
- owner.toxins_alert = 0 // Reset our toxins alert for now.
+ SET_HUD_ALERT(owner, /decl/hud_element/condition/toxins, 0)
if(!failed_inhale) // Enough gas to tell we're being poisoned via chemical burns or whatever.
var/poison_total = 0
if(poison_types)
@@ -212,7 +212,7 @@
if(poison_types[gname])
poison_total += breath.gas[gname]
if(((poison_total/breath.total_moles)*breath_pressure) > safe_toxins_max)
- owner.toxins_alert = 1
+ SET_HUD_ALERT(owner, /decl/hud_element/condition/toxins, 1)
// Pass reagents from the gas into our body.
// Presumably if you breathe it you have a specialized metabolism for it, so we drop/ignore breath_type. Also avoids
@@ -252,7 +252,7 @@
if(failed_breath)
handle_failed_breath()
else
- owner.oxygen_alert = 0
+ SET_HUD_ALERT(owner, /decl/hud_element/condition/oxygen, 0)
return failed_breath
/obj/item/organ/internal/lungs/proc/handle_failed_breath()
@@ -266,7 +266,7 @@
if(damage || GET_CHEMICAL_EFFECT(owner, CE_BREATHLOSS) || world.time > last_successful_breath + 2 MINUTES)
owner.adjustOxyLoss(HUMAN_MAX_OXYLOSS*breath_fail_ratio)
- owner.oxygen_alert = max(owner.oxygen_alert, 2)
+ SET_HUD_ALERT_MAX(owner, /decl/hud_element/condition/oxygen, 2)
last_int_pressure = 0
/obj/item/organ/internal/lungs/proc/handle_temperature_effects(datum/gas_mixture/breath)
@@ -289,7 +289,9 @@
owner.apply_damage(damage, BURN, BP_HEAD, used_weapon = "Excessive Cold")
else
src.damage += damage
- owner.fire_alert = 1
+ if(owner.hud_used)
+ SET_HUD_ALERT_MAX(owner, /decl/hud_element/condition/fire, 1)
+
else if(breath.temperature >= heat_1)
if(prob(20))
to_chat(owner, "You feel your face burning and a searing heat in your lungs!")
@@ -305,7 +307,7 @@
owner.apply_damage(damage, BURN, BP_HEAD, used_weapon = "Excessive Heat")
else
src.damage += damage
- owner.fire_alert = 2
+ SET_HUD_ALERT(owner, /decl/hud_element/condition/fire, 2)
//breathing in hot/cold air also heats/cools you a bit
var/temp_adj = breath.temperature - owner.bodytemperature
diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm
index e620be9b5bc..f08cbbbd2a0 100644
--- a/code/modules/organs/organ.dm
+++ b/code/modules/organs/organ.dm
@@ -54,7 +54,7 @@
/obj/item/organ/attack_self(var/mob/user)
return (owner && loc == owner && owner == user)
-/obj/item/organ/proc/update_health()
+/obj/item/organ/proc/update_organ_health()
return
/obj/item/organ/proc/is_broken()
@@ -361,6 +361,8 @@
/obj/item/organ/proc/heal_damage(amount)
if(can_recover())
damage = clamp(0, damage - round(amount, 0.1), max_damage)
+ if(owner)
+ owner.update_health()
/obj/item/organ/attack(var/mob/target, var/mob/user)
if(BP_IS_PROSTHETIC(src) || !istype(target) || !istype(user) || (user != target && user.a_intent == I_HELP))
diff --git a/code/modules/organs/pain.dm b/code/modules/organs/pain.dm
index d9bff64a519..ffedb2e1293 100644
--- a/code/modules/organs/pain.dm
+++ b/code/modules/organs/pain.dm
@@ -1,12 +1,13 @@
/mob/proc/flash_pain(var/target)
- if(pain)
+ var/obj/screen/pain_overlay = get_hud_element(/decl/hud_element/pain)
+ if(pain_overlay)
var/matrix/M
if(client && max(client.last_view_x_dim, client.last_view_y_dim) > 7)
M = matrix()
M.Scale(CEILING(client.last_view_x_dim/7), CEILING(client.last_view_y_dim/7))
- pain.transform = M
- animate(pain, alpha = target, time = 15, easing = ELASTIC_EASING)
- animate(pain, alpha = 0, time = 20)
+ pain_overlay.transform = M
+ animate(pain_overlay, alpha = target, time = 15, easing = ELASTIC_EASING)
+ animate(pain_overlay, alpha = 0, time = 20)
/mob/living/proc/can_feel_pain(var/check_organ)
if(check_organ)
diff --git a/code/modules/organs/prosthetics/_prosthetics.dm b/code/modules/organs/prosthetics/_prosthetics.dm
index 916eb8ea492..441c3dbdfdf 100644
--- a/code/modules/organs/prosthetics/_prosthetics.dm
+++ b/code/modules/organs/prosthetics/_prosthetics.dm
@@ -139,12 +139,12 @@
var/obj/item/organ/external/E = get_active_hand()
if(!check_can_attach_modular_limb(E))
return FALSE
+ set_special_ability_cooldown(2 SECONDS)
if(!do_after(src, 2 SECONDS, src))
return FALSE
if(!check_can_attach_modular_limb(E))
return FALSE
- set_special_ability_cooldown(2 SECONDS)
drop_from_inventory(E)
src.add_organ(E)
@@ -173,12 +173,12 @@
var/obj/item/organ/external/E = input(usr, "Which limb do you wish to detach?", "Limb Removal") as null|anything in detachable_limbs
if(!check_can_detach_modular_limb(E))
return FALSE
+ set_special_ability_cooldown(2 SECONDS)
if(!do_after(src, 2 SECONDS, src))
return FALSE
if(!check_can_detach_modular_limb(E))
return FALSE
- set_special_ability_cooldown(2 SECONDS)
remove_organ(E, update_icon = TRUE)
E.dropInto(loc)
put_in_hands(E)
diff --git a/code/modules/paperwork/photography.dm b/code/modules/paperwork/photography.dm
index 7bafff17f0d..9911814345f 100644
--- a/code/modules/paperwork/photography.dm
+++ b/code/modules/paperwork/photography.dm
@@ -298,9 +298,9 @@
if(length(holding))
holding = "They are holding [english_list(holding)]"
if(!mob_detail)
- mob_detail = "You can see [A] on the photo[(A.health / A.maxHealth) < 0.75 ? " - [A] looks hurt":""].[holding ? " [holding]":"."]. "
+ mob_detail = "You can see [A] on the photo[A.get_health_ratio() < 0.75 ? " - [A] looks hurt":""].[holding ? " [holding]":"."]. "
else
- mob_detail += "You can also see [A] on the photo[(A.health / A.maxHealth)< 0.75 ? " - [A] looks hurt":""].[holding ? " [holding]":"."]."
+ mob_detail += "You can also see [A] on the photo[A.get_health_ratio() < 0.75 ? " - [A] looks hurt":""].[holding ? " [holding]":"."]."
return mob_detail
/obj/item/camera/afterattack(atom/target, mob/user, flag)
diff --git a/code/modules/power/singularity/particle_accelerator/particle.dm b/code/modules/power/singularity/particle_accelerator/particle.dm
index 3d922b263b2..dc88c1bb9c8 100644
--- a/code/modules/power/singularity/particle_accelerator/particle.dm
+++ b/code/modules/power/singularity/particle_accelerator/particle.dm
@@ -63,7 +63,6 @@
/obj/effect/accelerated_particle/proc/toxmob(var/mob/living/M)
var/radiation = (energy*2)
M.apply_damage((radiation*3),IRRADIATE, damage_flags = DAM_DISPERSED)
- M.updatehealth()
/obj/effect/accelerated_particle/proc/move(var/lag)
set waitfor = FALSE
diff --git a/code/modules/projectiles/targeting/targeting_client.dm b/code/modules/projectiles/targeting/targeting_client.dm
index eeaf61909de..0facc51e601 100644
--- a/code/modules/projectiles/targeting/targeting_client.dm
+++ b/code/modules/projectiles/targeting/targeting_client.dm
@@ -1,12 +1,16 @@
//These are called by the on-screen buttons, adjusting what the victim can and cannot do.
/client/proc/add_gun_icons()
- if(!usr || !usr.item_use_icon) return 1 // This can runtime if someone manages to throw a gun out of their hand before the proc is called.
- screen |= usr.item_use_icon
- screen |= usr.gun_move_icon
- screen |= usr.radio_use_icon
+ if(!usr?.hud_used)
+ return
+ for(var/elem_type in global.gun_hud_flag_decl_types)
+ var/obj/screen/elem = usr.get_hud_element(elem_type)
+ if(elem)
+ screen |= elem
/client/proc/remove_gun_icons()
- if(!usr) return 1 // Runtime prevention on N00k agents spawning with SMG
- screen -= usr.item_use_icon
- screen -= usr.gun_move_icon
- screen -= usr.radio_use_icon
+ if(!usr?.hud_used)
+ return
+ for(var/elem_type in global.gun_hud_flag_decl_types)
+ var/obj/screen/elem = usr.get_hud_element(elem_type)
+ if(elem)
+ screen -= elem
diff --git a/code/modules/projectiles/targeting/targeting_overlay.dm b/code/modules/projectiles/targeting/targeting_overlay.dm
index c9cc33f2a3a..8255cf7298b 100644
--- a/code/modules/projectiles/targeting/targeting_overlay.dm
+++ b/code/modules/projectiles/targeting/targeting_overlay.dm
@@ -32,29 +32,13 @@
target_permissions |= perm
// Update HUD icons.
- if(owner.gun_move_icon)
- if(!(target_permissions & TARGET_CAN_MOVE))
- owner.gun_move_icon.icon_state = "no_walk0"
- owner.gun_move_icon.SetName("Allow Movement")
- else
- owner.gun_move_icon.icon_state = "no_walk1"
- owner.gun_move_icon.SetName("Disallow Movement")
-
- if(owner.item_use_icon)
- if(!(target_permissions & TARGET_CAN_CLICK))
- owner.item_use_icon.icon_state = "no_item0"
- owner.item_use_icon.SetName("Allow Item Use")
- else
- owner.item_use_icon.icon_state = "no_item1"
- owner.item_use_icon.SetName("Disallow Item Use")
+ if(!owner?.hud_used)
+ return
- if(owner.radio_use_icon)
- if(!(target_permissions & TARGET_CAN_RADIO))
- owner.radio_use_icon.icon_state = "no_radio0"
- owner.radio_use_icon.SetName("Allow Radio Use")
- else
- owner.radio_use_icon.icon_state = "no_radio1"
- owner.radio_use_icon.SetName("Disallow Radio Use")
+ for(var/gun_flag_elem in global.gun_hud_flag_decl_types)
+ var/obj/screen/gun_flag/gun_elem = owner.get_hud_element(gun_flag_elem)
+ if(istype(gun_elem))
+ gun_elem.update_from_aiming_overlay(src)
var/message = "no longer permitted to "
var/use_span = "warning"
@@ -206,7 +190,11 @@
if(!no_message)
to_chat(owner, "You will no longer aim rather than fire.")
owner.client.remove_gun_icons()
- owner.gun_setting_icon.icon_state = "gun[active]"
+
+ if(istype(owner.hud_used))
+ var/obj/screen/gun_mode/gun_mode = owner.get_hud_element(/decl/hud_element/gun_mode)
+ if(gun_mode)
+ gun_mode.icon_state = "gun[!!active]"
/obj/aiming_overlay/proc/cancel_aiming(var/no_message = 0)
if(!aiming_with || !aiming_at)
diff --git a/code/modules/species/species.dm b/code/modules/species/species.dm
index b0aba0256c9..95a27586885 100644
--- a/code/modules/species/species.dm
+++ b/code/modules/species/species.dm
@@ -141,7 +141,7 @@ var/global/const/DEFAULT_SPECIES_HEALTH = 200
// HUD data vars.
var/datum/hud_data/hud
- var/hud_type
+ var/species_hud_type
var/grab_type = /decl/grab/normal/passive // The species' default grab type.
@@ -342,8 +342,8 @@ var/global/const/DEFAULT_SPECIES_HEALTH = 200
if(!default_cultural_info[token])
default_cultural_info[token] = global.using_map.default_cultural_info[token]
- if(hud_type)
- hud = new hud_type()
+ if(species_hud_type)
+ hud = new species_hud_type()
else
hud = new()
diff --git a/code/modules/species/species_bodytype.dm b/code/modules/species/species_bodytype.dm
index 7bf8be7492a..88dd0bb154c 100644
--- a/code/modules/species/species_bodytype.dm
+++ b/code/modules/species/species_bodytype.dm
@@ -281,14 +281,14 @@ var/global/list/bodytypes_by_category = list()
if(H.has_external_organs())
for(var/obj/item/organ/external/E in H.get_external_organs())
if(!is_default_limb(E))
- H.remove_organ(E, FALSE, FALSE, TRUE, TRUE, FALSE) //Remove them first so we don't trigger removal effects by just calling delete on them
+ H.remove_organ(E, FALSE, FALSE, TRUE, TRUE, FALSE, skip_health_update = TRUE) //Remove them first so we don't trigger removal effects by just calling delete on them
qdel(E)
//Clear invalid internal organs
if(H.has_internal_organs())
for(var/obj/item/organ/O in H.get_internal_organs())
if(!is_default_organ(O))
- H.remove_organ(O, FALSE, FALSE, TRUE, TRUE, FALSE) //Remove them first so we don't trigger removal effects by just calling delete on them
+ H.remove_organ(O, FALSE, FALSE, TRUE, TRUE, FALSE, skip_health_update = TRUE) //Remove them first so we don't trigger removal effects by just calling delete on them
qdel(O)
//Create missing limbs
@@ -301,7 +301,7 @@ var/global/list/bodytypes_by_category = list()
if(E.parent_organ)
var/list/parent_organ_data = has_limbs[E.parent_organ]
parent_organ_data["has_children"]++
- H.add_organ(E, GET_EXTERNAL_ORGAN(H, E.parent_organ), FALSE, FALSE)
+ H.add_organ(E, GET_EXTERNAL_ORGAN(H, E.parent_organ), FALSE, FALSE, skip_health_update = TRUE)
//Create missing internal organs
for(var/organ_tag in has_organ)
@@ -312,7 +312,8 @@ var/global/list/bodytypes_by_category = list()
if(organ_tag != O.organ_tag)
warning("[O.type] has a default organ tag \"[O.organ_tag]\" that differs from the species' organ tag \"[organ_tag]\". Updating organ_tag to match.")
O.organ_tag = organ_tag
- H.add_organ(O, GET_EXTERNAL_ORGAN(H, O.parent_organ), FALSE, FALSE)
+ H.add_organ(O, GET_EXTERNAL_ORGAN(H, O.parent_organ), FALSE, FALSE, skip_health_update = TRUE)
+ H.update_health()
//Checks if an existing organ is the bodytype default
/decl/bodytype/proc/is_default_organ(obj/item/organ/internal/O)
diff --git a/code/modules/species/species_hud.dm b/code/modules/species/species_hud.dm
index 412aff74fdd..b94a53efc23 100644
--- a/code/modules/species/species_hud.dm
+++ b/code/modules/species/species_hud.dm
@@ -1,17 +1,5 @@
/datum/hud_data
var/icon // If set, overrides ui_style.
- var/has_a_intent = 1 // Set to draw intent box.
- var/has_m_intent = 1 // Set to draw move intent box.
- var/has_warnings = 1 // Set to draw environment warnings.
- var/has_pressure = 1 // Draw the pressure indicator.
- var/has_nutrition = 1 // Draw the nutrition indicator.
- var/has_bodytemp = 1 // Draw the bodytemp indicator.
- var/has_hands = 1 // Set to draw hands.
- var/has_drop = 1 // Set to draw drop button.
- var/has_throw = 1 // Set to draw throw button.
- var/has_resist = 1 // Set to draw resist button.
- var/has_internals = 1 // Set to draw the internals toggle button.
- var/has_up_hint = 1 // Set to draw the "look-up" hint icon
var/list/equip_slots = list() // Checked by mob_can_equip().
var/list/persistent_slots = list() // Built in New(), used for unhidable inv updates
var/list/hidden_slots = list() // Built in New(), used for hidable inv updates
@@ -50,8 +38,7 @@
else
persistent_slots |= slot_id
- if(has_hands)
- equip_slots |= slot_handcuffed_str
+ equip_slots |= slot_handcuffed_str
if(slot_back_str in equip_slots)
equip_slots |= slot_in_backpack_str
diff --git a/code/modules/species/species_shapeshifter.dm b/code/modules/species/species_shapeshifter.dm
index 3a8bff664eb..81e4aa58d1d 100644
--- a/code/modules/species/species_shapeshifter.dm
+++ b/code/modules/species/species_shapeshifter.dm
@@ -86,7 +86,7 @@ var/global/list/wrapped_species_by_ref = list()
set name = "Select Body Shape"
set category = "Abilities"
- if(stat ||is_on_special_ability_cooldown())
+ if(stat || is_on_special_ability_cooldown())
return
set_special_ability_cooldown(5 SECONDS)
diff --git a/code/modules/species/station/monkey.dm b/code/modules/species/station/monkey.dm
index 9d72c6ef81f..9b97a2ad3b0 100644
--- a/code/modules/species/station/monkey.dm
+++ b/code/modules/species/station/monkey.dm
@@ -17,7 +17,7 @@
unarmed_attacks = list(/decl/natural_attack/bite, /decl/natural_attack/claws, /decl/natural_attack/punch)
inherent_verbs = list(/mob/living/proc/ventcrawl)
- hud_type = /datum/hud_data/monkey
+ species_hud_type = /datum/hud_data/monkey
meat_type = /obj/item/chems/food/meat/monkey
rarity_value = 0.1
diff --git a/code/modules/spells/aoe_turf/conjure/druidic_spells.dm b/code/modules/spells/aoe_turf/conjure/druidic_spells.dm
index 70a37798f3f..d4b5db4bb88 100644
--- a/code/modules/spells/aoe_turf/conjure/druidic_spells.dm
+++ b/code/modules/spells/aoe_turf/conjure/druidic_spells.dm
@@ -39,7 +39,7 @@
if(!..())
return 0
- newVars = list("maxHealth" = 20 + spell_levels[Sp_POWER]*5, "health" = 20 + spell_levels[Sp_POWER]*5, "melee_damage_lower" = 10 + spell_levels[Sp_POWER], "melee_damage_upper" = 10 + spell_levels[Sp_POWER]*2)
+ newVars = list("mob_default_max_health" = 20 + spell_levels[Sp_POWER]*5, "health" = 20 + spell_levels[Sp_POWER]*5, "melee_damage_lower" = 10 + spell_levels[Sp_POWER], "melee_damage_upper" = 10 + spell_levels[Sp_POWER]*2)
return "Your bats are now stronger."
@@ -59,7 +59,7 @@
summon_amt = 1
summon_type = list(/mob/living/simple_animal/hostile/commanded/bear)
- newVars = list("maxHealth" = 15,
+ newVars = list("mob_default_max_health" = 15,
"health" = 15,
"melee_damage_lower" = 10,
"melee_damage_upper" = 10,
@@ -76,14 +76,14 @@
return 0
switch(spell_levels[Sp_POWER])
if(1)
- newVars = list("maxHealth" = 30,
+ newVars = list("mob_default_max_health" = 30,
"health" = 30,
"melee_damage_lower" = 15,
"melee_damage_upper" = 15
)
return "Your bear has been upgraded from a cub to a whelp."
if(2)
- newVars = list("maxHealth" = 45,
+ newVars = list("mob_default_max_health" = 45,
"health" = 45,
"melee_damage_lower" = 20,
"melee_damage_upper" = 20,
@@ -91,7 +91,7 @@
)
return "Your bear has been upgraded from a whelp to an adult."
if(3)
- newVars = list("maxHealth" = 60,
+ newVars = list("mob_default_max_health" = 60,
"health" = 60,
"melee_damage_lower" = 25,
"melee_damage_upper" = 25,
@@ -99,7 +99,7 @@
)
return "Your bear has been upgraded from an adult to an alpha."
if(4)
- newVars = list("maxHealth" = 75,
+ newVars = list("mob_default_max_health" = 75,
"health" = 75,
"melee_damage_lower" = 35,
"melee_damage_upper" = 35,
diff --git a/code/modules/spells/contracts.dm b/code/modules/spells/contracts.dm
index 60c6bba8bf9..3326ddefef0 100644
--- a/code/modules/spells/contracts.dm
+++ b/code/modules/spells/contracts.dm
@@ -1,7 +1,7 @@
/obj/item/contract
name = "contract"
desc = "written in the blood of some unfortunate fellow."
- icon = 'icons/mob/screen_spells.dmi'
+ icon = 'icons/mob/screen/spells.dmi'
icon_state = "master_open"
material = /decl/material/solid/organic/paper
var/contract_master = null
diff --git a/code/modules/spells/hand/hand_item.dm b/code/modules/spells/hand/hand_item.dm
index 855cfdcfa92..dd5f6ee6d90 100644
--- a/code/modules/spells/hand/hand_item.dm
+++ b/code/modules/spells/hand/hand_item.dm
@@ -4,12 +4,12 @@ Basically: I can use it to target things where I click. I can then pass these ta
/obj/item/magic_hand
name = "Magic Hand"
- icon = 'icons/mob/screen1.dmi'
+ icon = 'icons/mob/screen/spells.dmi'
+ icon_state = "spell"
atom_flags = 0
item_flags = 0
obj_flags = 0
simulated = 0
- icon_state = "spell"
max_health = ITEM_HEALTH_NO_DAMAGE
is_spawnable_type = FALSE
var/next_spell_time = 0
diff --git a/code/modules/spells/spell_code.dm b/code/modules/spells/spell_code.dm
index 981e56a5f0c..c3d7f0fd5b0 100644
--- a/code/modules/spells/spell_code.dm
+++ b/code/modules/spells/spell_code.dm
@@ -240,7 +240,7 @@ var/global/list/spells = typesof(/spell) //needed for the badmin verb for now
if(holder == user)
if(isanimal(user))
var/mob/living/simple_animal/SA = user
- if(SA.purge)
+ if(SA.purged_time)
to_chat(SA, "The null sceptre's power interferes with your own!")
return 0
diff --git a/code/modules/spells/spells.dm b/code/modules/spells/spells.dm
index d2dc6a0201e..474f745cfba 100644
--- a/code/modules/spells/spells.dm
+++ b/code/modules/spells/spells.dm
@@ -3,18 +3,8 @@
/mob/Stat()
. = ..()
- if(. && ability_master && ability_master.spell_objects)
- for(var/obj/screen/ability/spell/screen in ability_master.spell_objects)
- var/spell/S = screen.spell
- if((!S.connected_button) || !statpanel(S.panel))
- continue //Not showing the noclothes spell
- switch(S.charge_type)
- if(Sp_RECHARGE)
- statpanel(S.panel,"[S.charge_counter/10.0]/[S.charge_max/10]",S.connected_button)
- if(Sp_CHARGES)
- statpanel(S.panel,"[S.charge_counter]/[S.charge_max]",S.connected_button)
- if(Sp_HOLDVAR)
- statpanel(S.panel,"[S.holder_var_type] [S.holder_var_amount]",S.connected_button)
+ if(. && istype(hud_used))
+ hud_used.refresh_stat_panel()
/proc/restore_spells(var/mob/H)
if(H.mind && H.mind.learned_spells)
@@ -27,11 +17,14 @@
for(var/spell/spell_to_add in spells)
H.add_spell(spell_to_add)
- H.ability_master.update_abilities(0,H)
+ var/obj/screen/ability_master/ability_master = H.get_hud_element(/decl/hud_element/ability_master)
+ if(ability_master)
+ ability_master.update_abilities(0,H)
/mob/proc/add_spell(var/spell/spell_to_add, var/spell_base = "wiz_spell_ready")
+ var/obj/screen/ability_master/ability_master = get_hud_element(/decl/hud_element/ability_master)
if(!ability_master)
- ability_master = new()
+ return
spell_to_add.holder = src
if(mind)
if(!mind.learned_spells)
@@ -46,6 +39,7 @@
if(mind)
mind.learned_spells -= spell_to_remove
+ var/obj/screen/ability_master/ability_master = get_hud_element(/decl/hud_element/ability_master)
if (ability_master)
ability_master.remove_ability(ability_master.get_ability_by_spell(spell_to_remove))
return 1
@@ -53,8 +47,6 @@
/mob/proc/silence_spells(var/amount = 0)
if(amount < 0)
return
-
- if(!ability_master)
- return
-
- ability_master.silence_spells(amount)
\ No newline at end of file
+ var/obj/screen/ability_master/ability_master = get_hud_element(/decl/hud_element/ability_master)
+ if(ability_master)
+ ability_master.silence_spells(amount)
diff --git a/code/modules/spells/targeted/equip/burning_touch.dm b/code/modules/spells/targeted/equip/burning_touch.dm
index b7e9c9dbdb9..c6227d6b246 100644
--- a/code/modules/spells/targeted/equip/burning_touch.dm
+++ b/code/modules/spells/targeted/equip/burning_touch.dm
@@ -16,7 +16,7 @@
/obj/item/flame/hands
name = "Burning Hand"
- icon = 'icons/mob/screen1.dmi'
+ icon = 'icons/mob/screen/grabs.dmi'
icon_state = "grabbed+1"
force = 10
damtype = BURN
diff --git a/code/modules/spells/targeted/shapeshift.dm b/code/modules/spells/targeted/shapeshift.dm
index a4504ed778c..e8dd5093dac 100644
--- a/code/modules/spells/targeted/shapeshift.dm
+++ b/code/modules/spells/targeted/shapeshift.dm
@@ -73,8 +73,8 @@
return FALSE
transformer.status_flags &= ~GODMODE
if(share_damage)
- var/ratio = target.health/target.maxHealth
- var/damage = transformer.maxHealth - round(transformer.maxHealth*(ratio))
+ var/transformer_max_health = transformer.get_max_health()
+ var/damage = transformer.set_max_health(transformer_max_health-round(transformer_max_health*(transformer.get_health_ratio())))
for(var/i in 1 to CEILING(damage/10))
transformer.adjustBruteLoss(10)
if(target.mind)
@@ -116,7 +116,7 @@
level_max = list(Sp_TOTAL = 2, Sp_SPEED = 2, Sp_POWER = 2)
- newVars = list("health" = 50, "maxHealth" = 50)
+ newVars = list("health" = 50, "default_mob_max_health" = 50)
hud_state = "wiz_poly"
@@ -183,7 +183,7 @@
"melee_damage_upper" = 25,
"resistance" = 6,
"health" = 125,
- "maxHealth" = 125)
+ "mob_default_max_health" = 125)
duration = 0
return "You revel in the corruption. There is no turning back."
diff --git a/code/modules/supermatter/setup_supermatter.dm b/code/modules/supermatter/setup_supermatter.dm
index e7dc912abb4..c1038f76a20 100644
--- a/code/modules/supermatter/setup_supermatter.dm
+++ b/code/modules/supermatter/setup_supermatter.dm
@@ -105,7 +105,7 @@ var/global/list/engine_setup_markers = list()
invisibility = INVISIBILITY_ABSTRACT
anchored = TRUE
density = FALSE
- icon = 'icons/mob/screen1.dmi'
+ icon = 'icons/mob/screen/crosses.dmi'
icon_state = "x3"
/obj/effect/engine_setup/Initialize()
diff --git a/code/modules/xenoarcheaology/finds/find_types/statuette.dm b/code/modules/xenoarcheaology/finds/find_types/statuette.dm
index c2f480dd53f..beb93d05fa3 100644
--- a/code/modules/xenoarcheaology/finds/find_types/statuette.dm
+++ b/code/modules/xenoarcheaology/finds/find_types/statuette.dm
@@ -41,7 +41,7 @@
//see if we've identified anyone nearby
if(world.time - last_bloodcall > bloodcall_interval && nearby_mobs.len)
var/mob/living/carbon/human/M = pop(nearby_mobs)
- if(M in view(7,src) && M.health > 20)
+ if(M in view(7,src) && M.current_health > 20)
if(prob(50))
bloodcall(M)
nearby_mobs.Add(M)
diff --git a/code/unit_tests/mob_tests.dm b/code/unit_tests/mob_tests.dm
index 9179e912557..d2503ab7763 100644
--- a/code/unit_tests/mob_tests.dm
+++ b/code/unit_tests/mob_tests.dm
@@ -110,7 +110,7 @@ var/global/default_mobloc = null
if(!loss && ishuman(M))
var/mob/living/carbon/human/H = M // Synthetics have robot limbs which don't report damage to getXXXLoss()
if(H.isSynthetic()) // So we have to hard code this check or create a different one for them.
- return H.species.total_health - H.health
+ return H.species.total_health - H.current_health
return loss
// ==============================================================================================================
@@ -164,7 +164,7 @@ var/global/default_mobloc = null
// Damage the mob
- var/initial_health = H.health
+ var/initial_health = H.current_health
if(damagetype == OXY && H.need_breathe())
var/obj/item/organ/internal/lungs/L = H.get_organ(H.get_bodytype().breathing_organ, /obj/item/organ/internal/lungs)
@@ -175,7 +175,7 @@ var/global/default_mobloc = null
var/ending_damage = damage_check(H, damagetype)
- var/ending_health = H.health
+ var/ending_health = H.current_health
qdel(H)
// Now test this stuff.
@@ -252,7 +252,7 @@ var/global/default_mobloc = null
/datum/unit_test/robot_module_icons
name = "MOB: Robot Modules Shall Have UI Icons"
- var/icon_file = 'icons/mob/screen1_robot.dmi'
+ var/icon_file = 'icons/mob/screen/robot_modules.dmi'
/datum/unit_test/robot_module_icons/start_test()
var/failed = 0
diff --git a/icons/mob/screen_ai.dmi b/icons/mob/screen/ai.dmi
similarity index 100%
rename from icons/mob/screen_ai.dmi
rename to icons/mob/screen/ai.dmi
diff --git a/icons/mob/screen/arrow.dmi b/icons/mob/screen/arrow.dmi
new file mode 100644
index 00000000000..af9ab119939
Binary files /dev/null and b/icons/mob/screen/arrow.dmi differ
diff --git a/icons/mob/screen/condition.dmi b/icons/mob/screen/condition.dmi
new file mode 100644
index 00000000000..b602ea27580
Binary files /dev/null and b/icons/mob/screen/condition.dmi differ
diff --git a/icons/mob/screen/construct.dmi b/icons/mob/screen/construct.dmi
new file mode 100644
index 00000000000..5c7193ccd1b
Binary files /dev/null and b/icons/mob/screen/construct.dmi differ
diff --git a/icons/mob/screen/crosses.dmi b/icons/mob/screen/crosses.dmi
new file mode 100644
index 00000000000..cc711a7a0c0
Binary files /dev/null and b/icons/mob/screen/crosses.dmi differ
diff --git a/icons/mob/screen/fill.dmi b/icons/mob/screen/fill.dmi
new file mode 100644
index 00000000000..712f127bac9
Binary files /dev/null and b/icons/mob/screen/fill.dmi differ
diff --git a/icons/mob/screen_full.dmi b/icons/mob/screen/full.dmi
similarity index 100%
rename from icons/mob/screen_full.dmi
rename to icons/mob/screen/full.dmi
diff --git a/icons/mob/screen/grabs.dmi b/icons/mob/screen/grabs.dmi
new file mode 100644
index 00000000000..4058c78bef3
Binary files /dev/null and b/icons/mob/screen/grabs.dmi differ
diff --git a/icons/mob/screen/health_construct_artificer.dmi b/icons/mob/screen/health_construct_artificer.dmi
new file mode 100644
index 00000000000..ea86c13574d
Binary files /dev/null and b/icons/mob/screen/health_construct_artificer.dmi differ
diff --git a/icons/mob/screen/health_construct_harvester.dmi b/icons/mob/screen/health_construct_harvester.dmi
new file mode 100644
index 00000000000..0e6796a431c
Binary files /dev/null and b/icons/mob/screen/health_construct_harvester.dmi differ
diff --git a/icons/mob/screen/health_construct_juggernaut.dmi b/icons/mob/screen/health_construct_juggernaut.dmi
new file mode 100644
index 00000000000..212ebbc3e4e
Binary files /dev/null and b/icons/mob/screen/health_construct_juggernaut.dmi differ
diff --git a/icons/mob/screen/health_construct_wraith.dmi b/icons/mob/screen/health_construct_wraith.dmi
new file mode 100644
index 00000000000..73f5a9102e7
Binary files /dev/null and b/icons/mob/screen/health_construct_wraith.dmi differ
diff --git a/icons/mob/screen/health_human.dmi b/icons/mob/screen/health_human.dmi
new file mode 100644
index 00000000000..695d606562b
Binary files /dev/null and b/icons/mob/screen/health_human.dmi differ
diff --git a/icons/mob/screen/health_robot.dmi b/icons/mob/screen/health_robot.dmi
new file mode 100644
index 00000000000..95e64ec6b2d
Binary files /dev/null and b/icons/mob/screen/health_robot.dmi differ
diff --git a/icons/mob/screen/intent.dmi b/icons/mob/screen/intent.dmi
new file mode 100644
index 00000000000..7f38d756a14
Binary files /dev/null and b/icons/mob/screen/intent.dmi differ
diff --git a/icons/mob/screen/internals.dmi b/icons/mob/screen/internals.dmi
new file mode 100644
index 00000000000..0ddffa7023c
Binary files /dev/null and b/icons/mob/screen/internals.dmi differ
diff --git a/icons/mob/screen/midnight.dmi b/icons/mob/screen/midnight.dmi
index 01dbd6c6479..5f0926e5528 100644
Binary files a/icons/mob/screen/midnight.dmi and b/icons/mob/screen/midnight.dmi differ
diff --git a/icons/mob/screen/minimalist.dmi b/icons/mob/screen/minimalist.dmi
index e87aebf1312..e2663fe24e1 100644
Binary files a/icons/mob/screen/minimalist.dmi and b/icons/mob/screen/minimalist.dmi differ
diff --git a/icons/mob/screen/old-noborder.dmi b/icons/mob/screen/old-noborder.dmi
index 18e49fc9c88..e4fc7dd55c5 100644
Binary files a/icons/mob/screen/old-noborder.dmi and b/icons/mob/screen/old-noborder.dmi differ
diff --git a/icons/mob/screen/old.dmi b/icons/mob/screen/old.dmi
index cc52abc3909..ce5b2f074dc 100644
Binary files a/icons/mob/screen/old.dmi and b/icons/mob/screen/old.dmi differ
diff --git a/icons/mob/screen/orange.dmi b/icons/mob/screen/orange.dmi
index cb94ada06c8..285aba3ec95 100644
Binary files a/icons/mob/screen/orange.dmi and b/icons/mob/screen/orange.dmi differ
diff --git a/icons/mob/screen_phenomena.dmi b/icons/mob/screen/phenomena.dmi
similarity index 100%
rename from icons/mob/screen_phenomena.dmi
rename to icons/mob/screen/phenomena.dmi
diff --git a/icons/mob/screen/robot.dmi b/icons/mob/screen/robot.dmi
new file mode 100644
index 00000000000..ed581ba9975
Binary files /dev/null and b/icons/mob/screen/robot.dmi differ
diff --git a/icons/mob/screen/robot_charge.dmi b/icons/mob/screen/robot_charge.dmi
new file mode 100644
index 00000000000..265c213516d
Binary files /dev/null and b/icons/mob/screen/robot_charge.dmi differ
diff --git a/icons/mob/screen/robot_conditions.dmi b/icons/mob/screen/robot_conditions.dmi
new file mode 100644
index 00000000000..717853f481a
Binary files /dev/null and b/icons/mob/screen/robot_conditions.dmi differ
diff --git a/icons/mob/screen/robot_drop_grab.dmi b/icons/mob/screen/robot_drop_grab.dmi
new file mode 100644
index 00000000000..7a1ecce37df
Binary files /dev/null and b/icons/mob/screen/robot_drop_grab.dmi differ
diff --git a/icons/mob/screen/robot_intent.dmi b/icons/mob/screen/robot_intent.dmi
new file mode 100644
index 00000000000..165427cc633
Binary files /dev/null and b/icons/mob/screen/robot_intent.dmi differ
diff --git a/icons/mob/screen/robot_modules.dmi b/icons/mob/screen/robot_modules.dmi
new file mode 100644
index 00000000000..b9061e1b6c6
Binary files /dev/null and b/icons/mob/screen/robot_modules.dmi differ
diff --git a/icons/mob/screen/spells.dmi b/icons/mob/screen/spells.dmi
new file mode 100644
index 00000000000..4916ce33ab5
Binary files /dev/null and b/icons/mob/screen/spells.dmi differ
diff --git a/icons/mob/screen/white.dmi b/icons/mob/screen/white.dmi
index 10d35d02cff..b1b94a21056 100644
Binary files a/icons/mob/screen/white.dmi and b/icons/mob/screen/white.dmi differ
diff --git a/icons/mob/screen1.dmi b/icons/mob/screen1.dmi
deleted file mode 100644
index 7f8db4256da..00000000000
Binary files a/icons/mob/screen1.dmi and /dev/null differ
diff --git a/icons/mob/screen1_construct.dmi b/icons/mob/screen1_construct.dmi
deleted file mode 100644
index 67a37ccd738..00000000000
Binary files a/icons/mob/screen1_construct.dmi and /dev/null differ
diff --git a/icons/mob/screen1_health.dmi b/icons/mob/screen1_health.dmi
deleted file mode 100644
index 9cd7a413420..00000000000
Binary files a/icons/mob/screen1_health.dmi and /dev/null differ
diff --git a/icons/mob/screen1_robot.dmi b/icons/mob/screen1_robot.dmi
deleted file mode 100644
index c6aa98f2b1f..00000000000
Binary files a/icons/mob/screen1_robot.dmi and /dev/null differ
diff --git a/icons/mob/screen_gen.dmi b/icons/mob/screen_gen.dmi
deleted file mode 100644
index 436fb1169a2..00000000000
Binary files a/icons/mob/screen_gen.dmi and /dev/null differ
diff --git a/icons/mob/screen_spells.dmi b/icons/mob/screen_spells.dmi
deleted file mode 100644
index 50be07d787b..00000000000
Binary files a/icons/mob/screen_spells.dmi and /dev/null differ
diff --git a/icons/mob/status_hunger.dmi b/icons/mob/status_hunger.dmi
deleted file mode 100644
index db92eb35581..00000000000
Binary files a/icons/mob/status_hunger.dmi and /dev/null differ
diff --git a/icons/mob/status_indicators.dmi b/icons/mob/status_indicators.dmi
deleted file mode 100644
index 80baa88177f..00000000000
Binary files a/icons/mob/status_indicators.dmi and /dev/null differ
diff --git a/maps/away/bearcat/bearcat.dm b/maps/away/bearcat/bearcat.dm
index 4b6c1a159e2..86090d73d9c 100644
--- a/maps/away/bearcat/bearcat.dm
+++ b/maps/away/bearcat/bearcat.dm
@@ -117,8 +117,9 @@
corpse.name = "Captain"
var/decl/hierarchy/outfit/outfit = outfit_by_type(/decl/hierarchy/outfit/deadcap)
outfit.equip_outfit(corpse)
- corpse.adjustOxyLoss(corpse.maxHealth)
- corpse.setBrainLoss(corpse.maxHealth)
+ var/corpse_health = corpse.get_max_health()
+ corpse.adjustOxyLoss(corpse_health)
+ corpse.setBrainLoss(corpse_health)
var/obj/structure/bed/chair/C = locate() in T
if(C)
C.buckle_mob(corpse)
diff --git a/maps/away/errant_pisces/errant_pisces.dm b/maps/away/errant_pisces/errant_pisces.dm
index 49a0ecdb69e..a63c53bc040 100644
--- a/maps/away/errant_pisces/errant_pisces.dm
+++ b/maps/away/errant_pisces/errant_pisces.dm
@@ -24,8 +24,7 @@
turns_per_move = 5
meat_type = /obj/item/chems/food/sharkmeat
speed = 2
- maxHealth = 100
- health = 100
+ mob_default_max_health = 100
natural_weapon = /obj/item/natural_weapon/bite/strong
break_stuff_probability = 35
faction = "shark"
diff --git a/maps/away/slavers/slavers_base.dm b/maps/away/slavers/slavers_base.dm
index b7b2cf50157..e83c80e7cd7 100644
--- a/maps/away/slavers/slavers_base.dm
+++ b/maps/away/slavers/slavers_base.dm
@@ -134,17 +134,16 @@
turns_per_move = 5
speed = 4
stop_automated_movement_when_pulled = 0
- maxHealth = 100
- health = 100
+ mob_default_max_health = 100
natural_weapon = /obj/item/natural_weapon/punch
can_escape = TRUE
unsuitable_atmos_damage = 15
- var/corpse = /obj/abstract/landmark/corpse/abolitionist
- var/weapon = /obj/item/gun/energy/laser
projectilesound = 'sound/weapons/laser.ogg'
ranged = 1
projectiletype = /obj/item/projectile/beam
faction = "extremist abolitionists"
+ var/corpse = /obj/abstract/landmark/corpse/abolitionist
+ var/weapon = /obj/item/gun/energy/laser
/mob/living/simple_animal/hostile/abolition_extremist/death(gibbed, deathmessage, show_dead_message)
. = ..(gibbed, deathmessage, show_dead_message)
diff --git a/maps/random_ruins/exoplanet_ruins/hydrobase/hydrobase.dm b/maps/random_ruins/exoplanet_ruins/hydrobase/hydrobase.dm
index a5b3ed11b3c..453e7fb4ffb 100644
--- a/maps/random_ruins/exoplanet_ruins/hydrobase/hydrobase.dm
+++ b/maps/random_ruins/exoplanet_ruins/hydrobase/hydrobase.dm
@@ -84,8 +84,7 @@
/mob/living/simple_animal/hostile/retaliate/goat/hydro
name = "goat"
desc = "An impressive goat, in size and coat. His horns look pretty serious!"
- health = 100
- maxHealth = 100
+ mob_default_max_health = 100
natural_weapon = /obj/item/natural_weapon/hooves/strong
faction = "farmbots"
@@ -99,8 +98,7 @@
speak = list("Initiating harvesting subrout-ine-ine.", "Connection timed out.", "Connection with master AI syst-tem-tem lost.", "Core systems override enab-...")
emote_see = list("beeps repeatedly", "whirrs violently", "flashes its indicator lights", "emits a ping sound")
faction = "farmbots"
- health = 225
- maxHealth = 225
+ mob_default_max_health = 225
malfunctioning = 0
/mob/living/simple_animal/hostile/retaliate/malf_drone/hydro/Initialize()
@@ -109,7 +107,7 @@
projectiletype = /obj/item/projectile/beam/drone/weak
/mob/living/simple_animal/hostile/retaliate/malf_drone/hydro/emp_act(severity)
- health -= rand(5,10) * (severity + 1)
+ adjustFireLoss(rand(5,10) * (severity + 1))
disabled = rand(15, 30)
malfunctioning = 1
hostile_drone = 1
diff --git a/mods/content/corporate/away_sites/lar_maria/lar_maria.dm b/mods/content/corporate/away_sites/lar_maria/lar_maria.dm
index 753bfa58244..59f75b91501 100644
--- a/mods/content/corporate/away_sites/lar_maria/lar_maria.dm
+++ b/mods/content/corporate/away_sites/lar_maria/lar_maria.dm
@@ -54,8 +54,7 @@
/mob/living/simple_animal/hostile/lar_maria/test_subject
name = "test subject"
desc = "Sick, filthy, angry and probably crazy human in an orange robe."
- maxHealth = 40
- health = 40
+ mob_default_max_health = 40
corpse = /obj/abstract/landmark/corpse/lar_maria/test_subject
icon = 'mods/content/corporate/away_sites/lar_maria/lar_maria_test_subject.dmi'
@@ -88,8 +87,7 @@
/mob/living/simple_animal/hostile/lar_maria/guard//angry guards armed with batons and shotguns. Still bite
name = "security"
desc = "Guard dressed at Zeng-Hu Pharmaceuticals uniform."
- maxHealth = 60
- health = 60
+ mob_default_max_health = 60
natural_weapon = /obj/item/baton
weapon = /obj/item/baton
corpse = /obj/abstract/landmark/corpse/lar_maria/zhp_guard
@@ -124,8 +122,7 @@
name = "virologist"
desc = "Virologist dressed at Zeng-Hu Pharmaceuticals uniform."
icon = 'mods/content/corporate/away_sites/lar_maria/lar_maria_virologist_m.dmi'
- maxHealth = 50
- health = 50
+ mob_default_max_health = 50
corpse = /obj/abstract/landmark/corpse/lar_maria/virologist
/obj/abstract/landmark/corpse/lar_maria/virologist
diff --git a/mods/content/xenobiology/circuit.dm b/mods/content/xenobiology/circuit.dm
index 81e12500a02..2ec922fceb3 100644
--- a/mods/content/xenobiology/circuit.dm
+++ b/mods/content/xenobiology/circuit.dm
@@ -30,7 +30,7 @@
set_pin_data(IC_OUTPUT, 2, T.is_adult)
set_pin_data(IC_OUTPUT, 3, T.nutrition/T.get_max_nutrition())
set_pin_data(IC_OUTPUT, 4, T.powerlevel)
- set_pin_data(IC_OUTPUT, 5, round(T.health/T.maxHealth,0.01)*100)
+ set_pin_data(IC_OUTPUT, 5, T.get_health_percent(0.001))
set_pin_data(IC_OUTPUT, 6, slime_data.descendants?.Copy())
set_pin_data(IC_OUTPUT, 7, T.mutation_chance)
set_pin_data(IC_OUTPUT, 8, T.cores)
diff --git a/mods/content/xenobiology/mobs/critter_slime.dm b/mods/content/xenobiology/mobs/critter_slime.dm
index 4210eed8fc8..16d870872f5 100644
--- a/mods/content/xenobiology/mobs/critter_slime.dm
+++ b/mods/content/xenobiology/mobs/critter_slime.dm
@@ -3,8 +3,7 @@
desc = "A lovable, domesticated slime."
icon = 'mods/content/xenobiology/icons/slimes/slime_baby.dmi'
speak_emote = list("chirps")
- health = 100
- maxHealth = 100
+ mob_default_max_health = 100
response_harm = "stamps on"
emote_see = list("jiggles", "bounces in place")
gene_damage = -1
@@ -25,7 +24,7 @@
SHOULD_CALL_PARENT(FALSE)
icon = get_slime_icon()
icon_state = (stat == DEAD ? "slime_dead" : "slime")
-
+
/mob/living/simple_animal/slime/proc/get_slime_icon()
var/decl/slime_colour/slime_data = GET_DECL(slime_type)
return slime_data.baby_icon
diff --git a/mods/content/xenobiology/mobs/slime_feeding_helpers.dm b/mods/content/xenobiology/mobs/slime_feeding_helpers.dm
index d8bfbee4803..c335ffdc7ed 100644
--- a/mods/content/xenobiology/mobs/slime_feeding_helpers.dm
+++ b/mods/content/xenobiology/mobs/slime_feeding_helpers.dm
@@ -72,10 +72,10 @@ var/global/list/slime_pain_messages = list(
var/protection = (1 - get_blocked_ratio(null, TOX, damage_flags = DAM_DISPERSED | DAM_BIO))
adjustCloneLoss((attacker.is_adult ? 10 : 5) * protection)
adjustToxLoss(1 * protection)
- if(health <= 0)
+ if(current_health <= 0)
adjustToxLoss(1 * protection)
if(prob(15) && client)
handle_additional_slime_effects()
. = 15 * protection
- if(stat == DEAD || getCloneLoss() >= maxHealth)
+ if(stat == DEAD || getCloneLoss() >= get_max_health())
eaten_by_slime()
diff --git a/mods/content/xenobiology/slime/_slime.dm b/mods/content/xenobiology/slime/_slime.dm
index 5f7c26441b7..baf52a70476 100644
--- a/mods/content/xenobiology/slime/_slime.dm
+++ b/mods/content/xenobiology/slime/_slime.dm
@@ -8,8 +8,7 @@
icon_state = ICON_STATE_WORLD
pass_flags = PASS_FLAG_TABLE
speak_emote = list("chirps")
- maxHealth = 150
- health = 150
+ mob_default_max_health = 150
gender = NEUTER
update_icon = 0
see_in_dark = 8
@@ -21,7 +20,7 @@
bone_material = null
bone_amount = 0
ai = /datum/ai/slime
- hud_type = /datum/hud/slime
+ hud_used = /datum/hud/slime
nutrition = 800
var/is_adult = FALSE
@@ -50,8 +49,10 @@
/mob/living/slime/get_digestion_product()
return /decl/material/liquid/slimejelly
-/mob/living/slime/adjustToxLoss(var/amount)
- toxloss = clamp(toxloss + amount, 0, maxHealth)
+/mob/living/slime/adjustToxLoss(var/amount, var/do_update_health)
+ toxloss = clamp(toxloss + amount, 0, get_max_health())
+ if(do_update_health)
+ update_health()
/mob/living/slime/setToxLoss(var/amount)
adjustToxLoss(amount-getToxLoss())
@@ -87,7 +88,7 @@
var/tally = ..()
- var/health_deficiency = (maxHealth - health)
+ var/health_deficiency = (get_max_health() - current_health)
if(health_deficiency >= 30) tally += (health_deficiency / 25)
if (bodytemperature < 183.222)
@@ -100,7 +101,7 @@
if(reagents.has_reagent(/decl/material/liquid/frostoil)) // Frostoil also makes them move VEEERRYYYYY slow
tally *= 5
- if(health <= 0) // if damaged, the slime moves twice as slow
+ if(current_health <= 0) // if damaged, the slime moves twice as slow
tally *= 2
return tally + config.slime_delay
@@ -146,7 +147,7 @@
. = ..()
statpanel("Status")
- stat(null, "Health: [round((health / maxHealth) * 100)]%")
+ stat(null, "Health: [get_health_percent()]%")
stat(null, "Intent: [a_intent]")
if (client.statpanel == "Status")
@@ -159,8 +160,8 @@
stat(null,"Power Level: [powerlevel]")
-/mob/living/slime/adjustFireLoss(amount)
- ..(-abs(amount)) // Heals them
+/mob/living/slime/adjustFireLoss(amount, do_update_health)
+ ..(-abs(amount), do_update_health) // Heals them
/mob/living/slime/bullet_act(var/obj/item/projectile/Proj)
var/datum/ai/slime/slime_ai = ai
@@ -344,7 +345,7 @@
else if (nutrition < get_hunger_nutrition())
. += "Warning:\tthe slime is hungry."
. += "Electric charge strength:\t[powerlevel]"
- . += "Health:\t[round((health * 100) / maxHealth)]%"
+ . += "Health:\t[get_health_percent()]%"
var/list/mutations = slime_data.descendants?.Copy()
if(!mutations.len)
diff --git a/mods/content/xenobiology/slime/feeding.dm b/mods/content/xenobiology/slime/feeding.dm
index fd88d5c3caf..421f943f780 100644
--- a/mods/content/xenobiology/slime/feeding.dm
+++ b/mods/content/xenobiology/slime/feeding.dm
@@ -31,7 +31,7 @@
if(!silent)
to_chat(src, SPAN_WARNING("\The [src] is dead."))
return FEED_RESULT_DEAD
- if(M.getCloneLoss() >= M.maxHealth * 1.5)
+ if(M.getCloneLoss() >= M.get_max_health() * 1.5)
if(!silent)
to_chat(src, SPAN_WARNING("\The [M] is too degraded to feed upon."))
return FEED_RESULT_DEAD
diff --git a/mods/content/xenobiology/slime/life.dm b/mods/content/xenobiology/slime/life.dm
index 623affe8304..bdab275be05 100644
--- a/mods/content/xenobiology/slime/life.dm
+++ b/mods/content/xenobiology/slime/life.dm
@@ -1,55 +1,17 @@
-/mob/living/slime/Life()
+/mob/living/slime/handle_environment(datum/gas_mixture/environment)
. = ..()
- if(. && stat != DEAD)
- handle_turf_contents()
- handle_local_conditions()
- if(feeding_on)
- slime_feed()
- ingested.metabolize()
-
-/mob/living/slime/updatehealth()
- . = ..()
- if(stat != DEAD && health <= 0)
- death()
-/mob/living/slime/fluid_act(datum/reagents/fluids)
- . = ..()
- if(!QDELETED(src) && fluids?.total_volume >= FLUID_SHALLOW && stat == DEAD)
- var/turf/T = get_turf(src)
- if(T)
- T.add_fluid(/decl/material/liquid/slimejelly, (is_adult ? rand(30, 40) : rand(10, 30)))
- visible_message(SPAN_DANGER("\The [src] melts away...")) // Slimes are water soluble.
- qdel(src)
-
-/mob/living/slime/proc/handle_local_conditions()
- var/datum/gas_mixture/environment = loc?.return_air()
- adjust_body_temperature(bodytemperature, (environment?.temperature || T0C), 1)
+ if(environment)
+ var/delta = abs(bodytemperature - environment.temperature)
+ var/change = (delta / (delta > 50 ? 5 : 10))
+ if(bodytemperature > environment.temperature)
+ change = -(change)
+ bodytemperature += (min(environment.temperature, bodytemperature + change) - bodytemperature)
if(bodytemperature <= die_temperature)
adjustToxLoss(200)
- death()
else if(bodytemperature <= hurt_temperature)
- adjustToxLoss(30)
- updatehealth()
+ adjustToxLoss(30, do_update_health = TRUE)
-/mob/living/slime/proc/adjust_body_temperature(current, loc_temp, boost)
- var/delta = abs(current-loc_temp)
- var/change = (delta / (delta > 50 ? 5 : 10)) * boost
- if(current > loc_temp)
- change = -(change)
- bodytemperature += (min(loc_temp, current + change) - current)
-
-/mob/living/slime/handle_regular_status_updates()
- . = ..()
- if(stat != DEAD)
- set_stat(CONSCIOUS)
- if(prob(30))
- adjustOxyLoss(-1)
- adjustToxLoss(-1)
- adjustFireLoss(-1)
- adjustCloneLoss(-1)
- adjustBruteLoss(-1)
-
-/mob/living/slime/proc/handle_turf_contents()
// If we're standing on top of a dead mob or small items, we can
// ingest it (or just melt it a little if we're too small)
// Also helps to keep our cell tidy!
@@ -80,13 +42,51 @@
if(length(contents) != last_contents_length)
queue_icon_update()
+/mob/living/slime/handle_nutrition_and_hydration()
+ . = ..()
+ if(feeding_on)
+ slime_feed()
+ ingested.metabolize()
+
+/mob/living/slime/fluid_act(datum/reagents/fluids)
+ . = ..()
+ if(!QDELETED(src) && fluids?.total_volume >= FLUID_SHALLOW && stat == DEAD)
+ var/turf/T = get_turf(src)
+ if(T)
+ T.add_fluid(/decl/material/liquid/slimejelly, (is_adult ? rand(30, 40) : rand(10, 30)))
+ visible_message(SPAN_DANGER("\The [src] melts away...")) // Slimes are water soluble.
+ qdel(src)
+
/mob/living/slime/get_hunger_factor()
return (0.1 + 0.05 * is_adult)
/mob/living/slime/get_thirst_factor()
return 0
+/mob/living/slime/fluid_act(datum/reagents/fluids)
+ . = ..()
+ if(stat == DEAD)
+ var/obj/effect/fluid/F = locate() in loc
+ if(F && F.reagents?.total_volume >= FLUID_SHALLOW)
+ F.reagents.add_reagent(/decl/material/liquid/slimejelly, (is_adult ? rand(30, 40) : rand(10, 30)))
+ visible_message(SPAN_DANGER("\The [src] melts away...")) // Slimes are water soluble.
+ qdel(src)
+
+/mob/living/slime/handle_living_non_stasis_processes()
+ . = ..()
+ set_stat(CONSCIOUS)
+ if(prob(30))
+ adjustOxyLoss(-1)
+ adjustToxLoss(-1)
+ adjustFireLoss(-1)
+ adjustCloneLoss(-1)
+ adjustBruteLoss(-1)
+
/mob/living/slime/handle_nutrition_and_hydration()
+ . = ..()
+ if(feeding_on)
+ slime_feed()
+ ingested.metabolize()
// Digest whatever we've got floating around in our goop.
if(length(contents))
diff --git a/mods/content/xenobiology/slime/powers.dm b/mods/content/xenobiology/slime/powers.dm
index cac27ead4e2..a90c4b879f9 100644
--- a/mods/content/xenobiology/slime/powers.dm
+++ b/mods/content/xenobiology/slime/powers.dm
@@ -16,7 +16,7 @@
return
is_adult = TRUE
- maxHealth = 200
+ mob_default_max_health = 200
amount_grown = 0
update_name()
update_icon()
diff --git a/mods/content/xenobiology/slime/slime_hud.dm b/mods/content/xenobiology/slime/slime_hud.dm
index d5162603531..7e8edc17290 100644
--- a/mods/content/xenobiology/slime/slime_hud.dm
+++ b/mods/content/xenobiology/slime/slime_hud.dm
@@ -1,6 +1 @@
-/datum/hud/slime/FinalizeInstantiation()
- var/obj/screen/using
- using = new /obj/screen/intent()
- src.adding += using
- action_intent = using
- ..()
+/datum/hud/slime
diff --git a/mods/mobs/borers/mob/borer/borer.dm b/mods/mobs/borers/mob/borer/borer.dm
index dc3ff9d818b..3931a684a5e 100644
--- a/mods/mobs/borers/mob/borer/borer.dm
+++ b/mods/mobs/borers/mob/borer/borer.dm
@@ -25,6 +25,8 @@
bleed_colour = "#816e12"
+ hud_used = /datum/hud/borer
+
var/static/list/chemical_types = list(
"anti-trauma" = /decl/material/liquid/brute_meds,
"amphetamines" = /decl/material/liquid/amphetamines,
@@ -60,12 +62,14 @@
/mob/living/simple_animal/borer/Login()
. = ..()
+ if(hud_used)
+ hud_used.refresh_ability_hud()
if(mind && !neutered)
var/decl/special_role/borer/borers = GET_DECL(/decl/special_role/borer)
borers.add_antagonist(mind)
/mob/living/simple_animal/borer/Initialize(var/mapload, var/gen=1)
-
+ hud_used = neutered ? /datum/hud/borer : /datum/hud/borer/sterile
. = ..()
add_language(/decl/language/corticalborer)
@@ -81,63 +85,57 @@
/mob/living/simple_animal/borer/proc/set_borer_name()
truename = "[borer_names[min(generation, borer_names.len)]] [random_id("borer[generation]", 1000, 9999)]"
-/mob/living/simple_animal/borer/Life()
+/mob/living/simple_animal/borer/handle_vision()
+ . = ..()
+ set_status(STAT_BLIND, host ? GET_STATUS(host, STAT_BLIND) : 0)
+ set_status(STAT_BLURRY, host ? GET_STATUS(host, STAT_BLURRY) : 0)
+ . = ..()
+ if(. == PROCESS_KILL)
+ return
+/mob/living/simple_animal/borer/handle_disabilities()
+ . = ..()
sdisabilities = 0
if(host)
- set_status(STAT_BLIND, GET_STATUS(host, STAT_BLIND))
- set_status(STAT_BLURRY, GET_STATUS(host, STAT_BLURRY))
if(host.sdisabilities & BLINDED)
sdisabilities |= BLINDED
if(host.sdisabilities & DEAFENED)
sdisabilities |= DEAFENED
- else
- set_status(STAT_BLIND, 0)
- set_status(STAT_BLURRY, 0)
+/mob/living/simple_animal/borer/handle_living_non_stasis_processes()
. = ..()
- if(!.)
- return FALSE
-
- if(host)
-
- if(!stat && !host.stat)
-
- if(host.reagents.has_reagent(/decl/material/liquid/nutriment/sugar))
- if(!docile)
- if(controlling)
- to_chat(host, SPAN_NOTICE("You feel the soporific flow of sugar in your host's blood, lulling you into docility."))
- else
- to_chat(src, SPAN_NOTICE("You feel the soporific flow of sugar in your host's blood, lulling you into docility."))
- docile = 1
+ if(!. || !host || host.stat)
+ return
+ if(host.reagents.has_reagent(/decl/material/liquid/nutriment/sugar))
+ if(!docile)
+ if(controlling)
+ to_chat(host, SPAN_NOTICE("You feel the soporific flow of sugar in your host's blood, lulling you into docility."))
else
- if(docile)
- if(controlling)
- to_chat(host, SPAN_NOTICE("You shake off your lethargy as the sugar leaves your host's blood."))
- else
- to_chat(src, SPAN_NOTICE("You shake off your lethargy as the sugar leaves your host's blood."))
- docile = 0
-
- if(chemicals < 250 && host.nutrition >= (neutered ? 200 : 50))
- host.nutrition--
- chemicals++
-
+ to_chat(src, SPAN_NOTICE("You feel the soporific flow of sugar in your host's blood, lulling you into docility."))
+ docile = 1
+ else
+ if(docile)
if(controlling)
-
- if(neutered)
- host.release_control()
- return
-
- if(docile)
- to_chat(host, SPAN_NOTICE("You are feeling far too docile to continue controlling your host..."))
- host.release_control()
- return
-
- if(prob(5))
- host.adjustBrainLoss(0.1)
-
- if(prob(host.getBrainLoss()/20))
- INVOKE_ASYNC(host, /mob/proc/say, "*[pick(list("blink","blink_r","choke","aflap","drool","twitch","twitch_v","gasp"))]")
+ to_chat(host, SPAN_NOTICE("You shake off your lethargy as the sugar leaves your host's blood."))
+ else
+ to_chat(src, SPAN_NOTICE("You shake off your lethargy as the sugar leaves your host's blood."))
+ docile = 0
+ if(chemicals < 250 && host.nutrition >= (neutered ? 200 : 50))
+ host.nutrition--
+ chemicals++
+ if(!controlling)
+ return
+ if(neutered)
+ host.release_control()
+ return
+ if(docile)
+ to_chat(host, SPAN_NOTICE("You are feeling far too docile to continue controlling your host..."))
+ host.release_control()
+ return
+ if(prob(5))
+ host.adjustBrainLoss(0.1)
+ if(prob(host.getBrainLoss()/20))
+ INVOKE_ASYNC(host, /mob/proc/say, "*[pick(list("blink","blink_r","choke","aflap","drool","twitch","twitch_v","gasp"))]")
/mob/living/simple_animal/borer/Stat()
. = ..()
@@ -202,23 +200,10 @@
qdel(host_brain)
-#define COLOR_BORER_RED "#ff5555"
-/mob/living/simple_animal/borer/proc/set_ability_cooldown(var/amt)
- set_special_ability_cooldown(amt)
- var/datum/hud/borer/borer_hud = hud_used
- if(istype(borer_hud))
- for(var/obj/thing in borer_hud.borer_hud_elements)
- thing.color = COLOR_BORER_RED
- addtimer(CALLBACK(src, /mob/living/simple_animal/borer/proc/reset_ui_callback), amt)
-#undef COLOR_BORER_RED
-
/mob/living/simple_animal/borer/proc/leave_host()
- var/datum/hud/borer/borer_hud = hud_used
- if(istype(borer_hud))
- for(var/obj/thing in borer_hud.borer_hud_elements)
- thing.alpha = 0
- thing.set_invisibility(INVISIBILITY_ABSTRACT)
+ if(hud_used)
+ hud_used.hide_ability_hud()
if(!host) return
diff --git a/mods/mobs/borers/mob/borer/borer_attacks.dm b/mods/mobs/borers/mob/borer/borer_attacks.dm
index 28ffd23fbe9..6fbe780cfd4 100644
--- a/mods/mobs/borers/mob/borer/borer_attacks.dm
+++ b/mods/mobs/borers/mob/borer/borer_attacks.dm
@@ -31,7 +31,7 @@
to_chat(M, SPAN_WARNING("Something slimy begins probing at the opening of your ear canal..."))
to_chat(src, SPAN_NOTICE("You slither up [M] and begin probing at their ear canal..."))
- set_ability_cooldown(5 SECONDS)
+ set_special_ability_cooldown(5 SECONDS)
if(!do_after(src, 3 SECONDS, M))
return
@@ -44,11 +44,8 @@
host.status_flags |= PASSEMOTES
forceMove(host)
- var/datum/hud/borer/borer_hud = hud_used
- if(istype(borer_hud))
- for(var/obj/thing in borer_hud.borer_hud_elements)
- thing.alpha = 255
- thing.set_invisibility(INVISIBILITY_NONE)
+ if(hud_used)
+ hud_used.show_ability_hud()
//Update their traitor status.
if(host.mind && !neutered)
diff --git a/mods/mobs/borers/mob/borer/borer_hud.dm b/mods/mobs/borers/mob/borer/borer_hud.dm
index a215aef94de..403bd095de9 100644
--- a/mods/mobs/borers/mob/borer/borer_hud.dm
+++ b/mods/mobs/borers/mob/borer/borer_hud.dm
@@ -1,55 +1,39 @@
+#define COLOR_BORER_RED "#ff5555"
+
/datum/hud/borer
- var/list/borer_hud_elements = list()
- var/obj/screen/intent/hud_intent_selector
- var/obj/screen/borer/toggle_host_control/hud_toggle_control
- var/obj/screen/borer/inject_chemicals/hud_inject_chemicals
- var/obj/screen/borer/leave_host/hud_leave_host
-
-/datum/hud/borer/Destroy()
- QDEL_NULL_LIST(borer_hud_elements)
- hud_toggle_control = null
- hud_inject_chemicals = null
- hud_leave_host = null
- QDEL_NULL(hud_intent_selector)
- . = ..()
+ hud_elements = list(
+ /decl/hud_element/borer/inject_chems,
+ /decl/hud_element/borer/leave_host,
+ /decl/hud_element/borer/toggle_control
+ )
-/datum/hud/borer/FinalizeInstantiation()
- hud_intent_selector = new
- adding += hud_intent_selector
- hud_inject_chemicals = new
- hud_leave_host = new
- borer_hud_elements = list(
- hud_inject_chemicals,
- hud_leave_host
+/datum/hud/borer/sterile
+ hud_elements = list(
+ /decl/hud_element/borer/inject_chems,
+ /decl/hud_element/borer/leave_host
)
- if(isborer(mymob))
- var/mob/living/simple_animal/borer/borer = mymob
- if(!borer.neutered)
- hud_toggle_control = new
- borer_hud_elements += hud_toggle_control
- adding += borer_hud_elements
- if(mymob)
- var/mob/living/simple_animal/borer/borer = mymob
- if(istype(borer) && borer.host)
- for(var/obj/thing in borer_hud_elements)
- thing.alpha = 255
- thing.set_invisibility(INVISIBILITY_NONE)
- ..()
-
-/mob/living/simple_animal/borer
- hud_type = /datum/hud/borer
-
-/mob/living/simple_animal/borer/proc/reset_ui_callback()
- if(!is_on_special_ability_cooldown())
- var/datum/hud/borer/borer_hud = hud_used
- if(istype(borer_hud))
- for(var/obj/thing in borer_hud.borer_hud_elements)
- thing.color = null
+
+/datum/hud/borer/should_show_ability_hud()
+ var/mob/living/simple_animal/borer/borer = mymob
+ return istype(borer) && borer.host
+
+/decl/hud_element/borer
+ abstract_type = /decl/hud_element/borer
+ apply_color_on_cooldown = TRUE
+ hidable = TRUE
+
+/decl/hud_element/borer/inject_chems
+ screen_object_type = /obj/screen/borer/inject_chemicals
+
+/decl/hud_element/borer/leave_host
+ screen_object_type = /obj/screen/borer/leave_host
+
+/decl/hud_element/borer/toggle_control
+ screen_object_type = /obj/screen/borer/toggle_host_control
/obj/screen/borer
icon = 'mods/mobs/borers/icons/borer_ui.dmi'
alpha = 0
- invisibility = INVISIBILITY_MAXIMUM
/obj/screen/borer/Click(location, control, params)
if(!isborer(usr))
diff --git a/mods/mobs/dionaea/mob/_nymph.dm b/mods/mobs/dionaea/mob/_nymph.dm
index 379a444e84f..e9cb3750d89 100644
--- a/mods/mobs/dionaea/mob/_nymph.dm
+++ b/mods/mobs/dionaea/mob/_nymph.dm
@@ -1,7 +1,6 @@
#define DIONA_SCREEN_LOC_HELD "RIGHT-8:16,BOTTOM:5"
#define DIONA_SCREEN_LOC_HAT "RIGHT-7:16,BOTTOM:5"
#define DIONA_SCREEN_LOC_INTENT "RIGHT-2,BOTTOM:5"
-#define DIONA_SCREEN_LOC_HEALTH ui_alien_health
/mob/living/carbon/alien/diona
name = "diona nymph"
@@ -9,8 +8,7 @@
icon = 'mods/mobs/dionaea/icons/nymph.dmi'
icon_state = ICON_STATE_WORLD
death_msg = "expires with a pitiful chirrup..."
- health = 60
- maxHealth = 60
+ mob_default_max_health = 60
available_maneuvers = list(/decl/maneuver/leap)
status_flags = NO_ANTAG
@@ -28,7 +26,7 @@
holder_type = /obj/item/holder/diona
possession_candidate = 1
atom_flags = ATOM_FLAG_NO_TEMP_CHANGE | ATOM_FLAG_NO_CHEM_CHANGE
- hud_type = /datum/hud/diona_nymph
+ hud_used = /datum/hud/diona_nymph
ai = /datum/ai/nymph
diff --git a/mods/mobs/dionaea/mob/nymph_life.dm b/mods/mobs/dionaea/mob/nymph_life.dm
index d39dbadbd3b..fc3424c0685 100644
--- a/mods/mobs/dionaea/mob/nymph_life.dm
+++ b/mods/mobs/dionaea/mob/nymph_life.dm
@@ -3,7 +3,7 @@
..()
- if(health <= 0 || stat == DEAD)
+ if(stat == DEAD)
return
var/turf/checking = get_turf(src)
diff --git a/mods/mobs/dionaea/mob/nymph_ui.dm b/mods/mobs/dionaea/mob/nymph_ui.dm
index 4eccaa1cf39..4b4b19355af 100644
--- a/mods/mobs/dionaea/mob/nymph_ui.dm
+++ b/mods/mobs/dionaea/mob/nymph_ui.dm
@@ -1,3 +1,6 @@
+/decl/hud_element/action_intent/diona_nymph
+ screen_object_type = /obj/screen/intent/diona_nymph
+
/obj/screen/intent/diona_nymph
icon_state = "intent_harm"
screen_loc = DIONA_SCREEN_LOC_INTENT
@@ -32,30 +35,17 @@
return 255
/datum/hud/diona_nymph/FinalizeInstantiation()
-
var/ui_style = get_ui_style()
var/ui_color = get_ui_color()
var/ui_alpha = get_ui_alpha()
-
+ hat = new
+ hat.icon = ui_style
+ hat.color = ui_color
+ hat.alpha = ui_alpha
+ misc_hud_elements += hat
held = new
held.icon = ui_style
held.color = ui_color
held.alpha = ui_alpha
- adding += held
-
- action_intent = new /obj/screen/intent/diona_nymph()
- action_intent.icon = ui_style
- action_intent.color = ui_color
- action_intent.alpha = ui_alpha
- adding += action_intent
-
- mymob.healths = new /obj/screen()
- mymob.healths.icon = ui_style
- mymob.healths.color = ui_color
- mymob.healths.alpha = ui_alpha
- mymob.healths.icon_state = "health0"
- mymob.healths.SetName("health")
- mymob.healths.screen_loc = DIONA_SCREEN_LOC_HEALTH
- adding += mymob.healths
-
- ..()
\ No newline at end of file
+ misc_hud_elements += held
+ return ..()
diff --git a/mods/mobs/dionaea/mob/~diona.dm b/mods/mobs/dionaea/mob/~diona.dm
index 0df03ea0e90..f30cb151165 100644
--- a/mods/mobs/dionaea/mob/~diona.dm
+++ b/mods/mobs/dionaea/mob/~diona.dm
@@ -1,4 +1,3 @@
#undef DIONA_SCREEN_LOC_HELD
#undef DIONA_SCREEN_LOC_HAT
#undef DIONA_SCREEN_LOC_INTENT
-#undef DIONA_SCREEN_LOC_HEALTH
\ No newline at end of file
diff --git a/mods/species/ascent/mobs/nymph/_nymph.dm b/mods/species/ascent/mobs/nymph/_nymph.dm
index 338b11625f1..b3f64fe4ec3 100644
--- a/mods/species/ascent/mobs/nymph/_nymph.dm
+++ b/mods/species/ascent/mobs/nymph/_nymph.dm
@@ -2,7 +2,6 @@
#define ANYMPH_SCREEN_LOC_HAT "RIGHT-7:16,BOTTOM:5"
#define ANYMPH_SCREEN_LOC_MOLT "RIGHT-6:16,BOTTOM:5"
#define ANYMPH_SCREEN_LOC_INTENT "RIGHT-2,BOTTOM:5"
-#define ANYMPH_SCREEN_LOC_HEALTH ui_alien_health
#define ANYMPH_MAX_CRYSTALS 20000
#define ANYMPH_CRYSTAL_MOLT 2000 // How much it takes to molt.
@@ -15,8 +14,7 @@
icon = 'mods/species/ascent/icons/species/nymph.dmi'
icon_state = ICON_STATE_WORLD
death_msg = "expires with a pitiful hiss..."
- health = 60
- maxHealth = 60
+ mob_default_max_health = 60
available_maneuvers = list(/decl/maneuver/leap)
only_species_language = 1
@@ -31,7 +29,7 @@
holder_type = /obj/item/holder/ascent_nymph
possession_candidate = 1
atom_flags = ATOM_FLAG_NO_TEMP_CHANGE | ATOM_FLAG_NO_CHEM_CHANGE
- hud_type = /datum/hud/ascent_nymph
+ hud_used = /datum/hud/ascent_nymph
var/obj/item/holding_item
var/crystal_reserve = 1000
diff --git a/mods/species/ascent/mobs/nymph/nymph_life.dm b/mods/species/ascent/mobs/nymph/nymph_life.dm
index 3eba226e5b5..2fdb7bff803 100644
--- a/mods/species/ascent/mobs/nymph/nymph_life.dm
+++ b/mods/species/ascent/mobs/nymph/nymph_life.dm
@@ -1,9 +1,11 @@
-/mob/living/carbon/alien/ascent_nymph/Life()
+/mob/living/carbon/alien/ascent_nymph/handle_regular_hud_updates()
. = ..()
- if(stat == DEAD)
+ if(. == PROCESS_KILL || stat == DEAD)
return
+/mob/living/carbon/alien/ascent_nymph/handle_nutrition_and_hydration()
+ . = ..()
// Generate some crystals over time.
if(nutrition >= 300 && crystal_reserve < ANYMPH_MAX_CRYSTALS)
crystal_reserve = min(ANYMPH_MAX_CRYSTALS, crystal_reserve + 15)
@@ -16,32 +18,9 @@
adjust_nutrition(DEFAULT_HUNGER_FACTOR * -2)
else
adjust_nutrition(DEFAULT_HUNGER_FACTOR * -1)
-
if(hydration > 0)
adjust_hydration(DEFAULT_THIRST_FACTOR * -1)
- update_nymph_hud()
-
-/mob/living/carbon/alien/ascent_nymph/proc/update_nymph_hud()
- // Update the HUD.
- var/datum/hud/ascent_nymph/nymph_hud = hud_used
- if(istype(nymph_hud))
- if(nymph_hud.food)
- switch(nutrition)
- if(450 to INFINITY) nymph_hud.food.icon_state = "nutrition0"
- if(350 to 450) nymph_hud.food.icon_state = "nutrition1"
- if(250 to 350) nymph_hud.food.icon_state = "nutrition2"
- if(150 to 250) nymph_hud.food.icon_state = "nutrition3"
- else nymph_hud.food.icon_state = "nutrition4"
-
- if(nymph_hud.drink)
- switch(hydration)
- if(450 to INFINITY) nymph_hud.drink.icon_state = "hydration0"
- if(350 to 450) nymph_hud.drink.icon_state = "hydration1"
- if(250 to 350) nymph_hud.drink.icon_state = "hydration2"
- if(150 to 250) nymph_hud.drink.icon_state = "hydration3"
- else nymph_hud.drink.icon_state = "hydration4"
-
/mob/living/carbon/alien/ascent_nymph/Stat()
. = ..()
if(client && statpanel("Status"))
diff --git a/mods/species/ascent/mobs/nymph/nymph_ui.dm b/mods/species/ascent/mobs/nymph/nymph_ui.dm
index 06054830a9b..97ff0507a67 100644
--- a/mods/species/ascent/mobs/nymph/nymph_ui.dm
+++ b/mods/species/ascent/mobs/nymph/nymph_ui.dm
@@ -1,3 +1,6 @@
+/decl/hud_element/action_intent/ascent_nymph
+ screen_object_type = /obj/screen/intent/ascent_nymph
+
/obj/screen/intent/ascent_nymph
icon_state = "intent_harm"
screen_loc = ANYMPH_SCREEN_LOC_INTENT
@@ -30,10 +33,15 @@
if(istype(nymph)) nymph.molt()
/datum/hud/ascent_nymph
+ health_hud_type = /decl/hud_element/health/ascent_nymph
+ hud_elements = list(
+ /decl/hud_element/health/ascent_nymph
+ )
var/obj/screen/ascent_nymph_held/held
var/obj/screen/ascent_nymph_molt/molt
- var/obj/screen/food/food
- var/obj/screen/drink/drink
+
+/decl/hud_element/health/ascent_nymph
+ screen_loc = ui_alien_health
/datum/hud/ascent_nymph/get_ui_style()
return 'mods/species/ascent/icons/ui.dmi'
@@ -45,49 +53,17 @@
return 255
/datum/hud/ascent_nymph/FinalizeInstantiation()
-
var/ui_style = get_ui_style()
var/ui_color = get_ui_color()
var/ui_alpha = get_ui_alpha()
-
held = new
held.icon = ui_style
held.color = ui_color
held.alpha = ui_alpha
- adding += held
-
+ misc_hud_elements += held
molt = new
molt.icon = ui_style
molt.color = ui_color
molt.alpha = ui_alpha
- adding += molt
-
- food = new
- food.icon = 'icons/mob/status_hunger.dmi'
- food.SetName("nutrition")
- food.icon_state = "nutrition1"
- food.pixel_w = 8
- food.screen_loc = ui_nutrition_small
- adding += food
-
- drink = new
- drink.icon = 'icons/mob/status_hunger.dmi'
- drink.icon_state = "hydration1"
- drink.SetName("hydration")
- drink.screen_loc = ui_nutrition_small
- adding += drink
-
- action_intent = new /obj/screen/intent/ascent_nymph()
- action_intent.icon = ui_style
- action_intent.color = ui_color
- action_intent.alpha = ui_alpha
- adding += action_intent
-
- mymob.healths = new /obj/screen()
- mymob.healths.icon = ui_style
- mymob.healths.color = ui_color
- mymob.healths.alpha = ui_alpha
- mymob.healths.SetName("health")
- mymob.healths.screen_loc = ANYMPH_SCREEN_LOC_HEALTH
- adding += mymob.healths
- ..()
+ misc_hud_elements += molt
+ return ..()
diff --git a/mods/species/bayliens/adherent/datum/species.dm b/mods/species/bayliens/adherent/datum/species.dm
index d378482d7cd..c6629c7abcb 100644
--- a/mods/species/bayliens/adherent/datum/species.dm
+++ b/mods/species/bayliens/adherent/datum/species.dm
@@ -63,7 +63,7 @@
spawn_flags = SPECIES_CAN_JOIN
flesh_color = "#90edeb"
- hud_type = /datum/hud_data/adherent
+ species_hud_type = /datum/hud_data/adherent
available_cultural_info = list(
TAG_CULTURE = list(
@@ -122,7 +122,6 @@
if(can_overcome_gravity(H)) return "\nThey are floating on a cloud of shimmering distortion."
/datum/hud_data/adherent
- has_internals = FALSE
inventory_slots = list(
/datum/inventory_slot/handcuffs,
/datum/inventory_slot/ear/adherent,
diff --git a/mods/species/serpentid/datum/species.dm b/mods/species/serpentid/datum/species.dm
index ac5177ae5f6..477219f939f 100644
--- a/mods/species/serpentid/datum/species.dm
+++ b/mods/species/serpentid/datum/species.dm
@@ -39,7 +39,7 @@
)
rarity_value = 4
- hud_type = /datum/hud_data/serpentid
+ species_hud_type = /datum/hud_data/serpentid
total_health = 200
brute_mod = 0.9
burn_mod = 1.35
diff --git a/mods/species/serpentid/mobs/bodyparts_serpentid.dm b/mods/species/serpentid/mobs/bodyparts_serpentid.dm
index f75c02d8631..e8ab003c569 100644
--- a/mods/species/serpentid/mobs/bodyparts_serpentid.dm
+++ b/mods/species/serpentid/mobs/bodyparts_serpentid.dm
@@ -83,13 +83,13 @@
H.adjustOxyLoss(-(HUMAN_MAX_OXYLOSS * oxygenated))
if(breath_fail_ratio < 0.25 && oxygenated)
- H.oxygen_alert = 0
+ SET_HUD_ALERT(H, /decl/hud_element/condition/oxygen, 0)
if(breath_fail_ratio >= 0.25 && (damage || world.time > last_successful_breath + 2 MINUTES))
H.adjustOxyLoss(HUMAN_MAX_OXYLOSS * breath_fail_ratio)
if(oxygenated)
- H.oxygen_alert = 1
+ SET_HUD_ALERT(H, /decl/hud_element/condition/oxygen, 1)
else
- H.oxygen_alert = 2
+ SET_HUD_ALERT(H, /decl/hud_element/condition/oxygen, 2)
/obj/item/organ/internal/brain/insectoid/serpentid
var/lowblood_tally = 0
diff --git a/nebula.dme b/nebula.dme
index 2b5f05e082a..ede02880e02 100644
--- a/nebula.dme
+++ b/nebula.dme
@@ -49,6 +49,7 @@
#include "code\__defines\gamemode.dm"
#include "code\__defines\guns.dm"
#include "code\__defines\holomap.dm"
+#include "code\__defines\hud.dm"
#include "code\__defines\hydroponics.dm"
#include "code\__defines\integrated_circuits.dm"
#include "code\__defines\interactions.dm"
@@ -165,25 +166,45 @@
#include "code\_onclick\other_mobs.dm"
#include "code\_onclick\rig.dm"
#include "code\_onclick\hud\_defines.dm"
+#include "code\_onclick\hud\_hud.dm"
#include "code\_onclick\hud\ability_screen_objects.dm"
#include "code\_onclick\hud\action.dm"
#include "code\_onclick\hud\ai.dm"
#include "code\_onclick\hud\ai_hud.dm"
#include "code\_onclick\hud\ai_screen_objects.dm"
-#include "code\_onclick\hud\animal.dm"
+#include "code\_onclick\hud\constructs.dm"
#include "code\_onclick\hud\deity.dm"
#include "code\_onclick\hud\fullscreen.dm"
#include "code\_onclick\hud\global_hud.dm"
-#include "code\_onclick\hud\gun_mode.dm"
-#include "code\_onclick\hud\hud.dm"
#include "code\_onclick\hud\human.dm"
-#include "code\_onclick\hud\other_mobs.dm"
#include "code\_onclick\hud\pai.dm"
#include "code\_onclick\hud\radial.dm"
#include "code\_onclick\hud\radial_persistent.dm"
#include "code\_onclick\hud\robot.dm"
#include "code\_onclick\hud\screen_objects.dm"
#include "code\_onclick\hud\skybox.dm"
+#include "code\_onclick\hud\hud_elements\_hud_element.dm"
+#include "code\_onclick\hud\hud_elements\ability_master.dm"
+#include "code\_onclick\hud\hud_elements\action_intent.dm"
+#include "code\_onclick\hud\hud_elements\bodytemp.dm"
+#include "code\_onclick\hud\hud_elements\cells.dm"
+#include "code\_onclick\hud\hud_elements\drop.dm"
+#include "code\_onclick\hud\hud_elements\fire.dm"
+#include "code\_onclick\hud\hud_elements\gun_mode.dm"
+#include "code\_onclick\hud\hud_elements\health.dm"
+#include "code\_onclick\hud\hud_elements\hydration.dm"
+#include "code\_onclick\hud\hud_elements\internals.dm"
+#include "code\_onclick\hud\hud_elements\move_intent.dm"
+#include "code\_onclick\hud\hud_elements\nutrition.dm"
+#include "code\_onclick\hud\hud_elements\oxygen.dm"
+#include "code\_onclick\hud\hud_elements\pain.dm"
+#include "code\_onclick\hud\hud_elements\pressure.dm"
+#include "code\_onclick\hud\hud_elements\resist.dm"
+#include "code\_onclick\hud\hud_elements\stamina.dm"
+#include "code\_onclick\hud\hud_elements\throwing.dm"
+#include "code\_onclick\hud\hud_elements\toxins.dm"
+#include "code\_onclick\hud\hud_elements\up_hint.dm"
+#include "code\_onclick\hud\hud_elements\zone_selector.dm"
#include "code\controllers\admin.dm"
#include "code\controllers\autotransfer.dm"
#include "code\controllers\communications.dm"
@@ -2391,7 +2412,6 @@
#include "code\modules\mob\living\carbon\give.dm"
#include "code\modules\mob\living\carbon\hallucinations.dm"
#include "code\modules\mob\living\carbon\internals.dm"
-#include "code\modules\mob\living\carbon\life.dm"
#include "code\modules\mob\living\carbon\resist.dm"
#include "code\modules\mob\living\carbon\taste.dm"
#include "code\modules\mob\living\carbon\alien\alien.dm"