"
for(var/datum/achievement_report/cheevo_report in GLOB.achievements_unlocked)
- parts += " [cheevo_report.winner_key] was [cheevo_report.winner], who earned the [span_greentext("'[cheevo_report.cheevo]'")] achievement at [cheevo_report.award_location]! "
+ parts += "[cheevo_report.winner] earned the [span_greentext("'[cheevo_report.cheevo]'")] achievement at [cheevo_report.award_location]! " // SKYRAT EDIT - No ckeys in the round end report - ORIGINAL: parts += " [cheevo_report.winner_key] was [cheevo_report.winner], who earned the [span_greentext("'[cheevo_report.cheevo]'")] achievement at [cheevo_report.award_location]! "
parts += "
"
return "
[parts.Join()]
"
diff --git a/code/_onclick/hud/fullscreen.dm b/code/_onclick/hud/fullscreen.dm
index ef184e18b1d..79f857e8cbe 100644
--- a/code/_onclick/hud/fullscreen.dm
+++ b/code/_onclick/hud/fullscreen.dm
@@ -26,7 +26,7 @@
screens -= category
- if(animated)
+ if(!QDELETED(src) && animated)
animate(screen, alpha = 0, time = animated)
addtimer(CALLBACK(src, PROC_REF(clear_fullscreen_after_animate), screen), animated, TIMER_CLIENT_TIME)
else
diff --git a/code/datums/armor/_armor.dm b/code/datums/armor/_armor.dm
index c6dbf1d5fdd..bfd15af4189 100644
--- a/code/datums/armor/_armor.dm
+++ b/code/datums/armor/_armor.dm
@@ -62,6 +62,7 @@ GLOBAL_LIST_INIT(armor_by_type, generate_armor_type_cache())
return FALSE
/datum/armor/vv_get_dropdown()
+ SHOULD_CALL_PARENT(FALSE)
return list("", "MUST MODIFY ARMOR VALUES ON THE PARENT ATOM")
/datum/armor/CanProcCall(procname)
diff --git a/code/datums/brain_damage/split_personality.dm b/code/datums/brain_damage/split_personality.dm
index 4c7b6a46100..f2120505f72 100644
--- a/code/datums/brain_damage/split_personality.dm
+++ b/code/datums/brain_damage/split_personality.dm
@@ -11,6 +11,8 @@
var/initialized = FALSE //to prevent personalities deleting themselves while we wait for ghosts
var/mob/living/split_personality/stranger_backseat //there's two so they can swap without overwriting
var/mob/living/split_personality/owner_backseat
+ ///The role to display when polling ghost
+ var/poll_role = "split personality"
/datum/brain_trauma/severe/split_personality/on_gain()
var/mob/living/M = owner
@@ -33,7 +35,7 @@
/datum/brain_trauma/severe/split_personality/proc/get_ghost()
set waitfor = FALSE
- var/list/mob/dead/observer/candidates = poll_candidates_for_mob("Do you want to play as [owner.real_name]'s split personality?", ROLE_PAI, null, 7.5 SECONDS, stranger_backseat, POLL_IGNORE_SPLITPERSONALITY)
+ var/list/mob/dead/observer/candidates = poll_candidates_for_mob("Do you want to play as [owner.real_name]'s [poll_role]?", ROLE_PAI, null, 7.5 SECONDS, stranger_backseat, POLL_IGNORE_SPLITPERSONALITY)
if(LAZYLEN(candidates))
var/mob/dead/observer/C = pick(candidates)
stranger_backseat.key = C.key
@@ -238,5 +240,53 @@
if(objective)
to_chat(src, span_notice("Your master left you an objective: [objective]. Follow it at all costs when in control."))
+/datum/brain_trauma/severe/split_personality/blackout
+ name = "Alcohol-Induced CNS Impairment"
+ desc = "Patient's CNS has been temporarily impaired by imbibed alcohol, blocking memory formation, and causing reduced cognition and stupefaction."
+ scan_desc = "alcohol-induced CNS impairment"
+ gain_text = span_warning("Crap, that was one drink too many. You black out...")
+ lose_text = "You wake up very, very confused and hungover. All you can remember is drinking a lot of alcohol... what happened?"
+ poll_role = "blacked out drunkard"
+ /// Duration of effect, tracked in seconds, not deciseconds. qdels when reaching 0.
+ var/duration_in_seconds = 180
+
+/datum/brain_trauma/severe/split_personality/blackout/on_gain()
+ . = ..()
+ RegisterSignal(owner, COMSIG_ATOM_SPLASHED, PROC_REF(on_splashed))
+
+/datum/brain_trauma/severe/split_personality/blackout/on_lose()
+ . = ..()
+ owner.add_mood_event("hang_over", /datum/mood_event/hang_over)
+ UnregisterSignal(owner, COMSIG_ATOM_SPLASHED)
+
+/datum/brain_trauma/severe/split_personality/blackout/proc/on_splashed()
+ SIGNAL_HANDLER
+ if(prob(20))//we don't want every single splash to wake them up now do we
+ qdel(src)
+
+/datum/brain_trauma/severe/split_personality/blackout/on_life(seconds_per_tick, times_fired)
+ if(current_controller == OWNER)
+ switch_personalities()
+ if(owner.stat == DEAD)
+ if(current_controller != OWNER)
+ switch_personalities(TRUE)
+ qdel(src)
+ return
+ if(duration_in_seconds <= 0)
+ qdel(src)
+ return
+ duration_in_seconds -= seconds_per_tick
+
+/mob/living/split_personality/blackout
+ name = "blacked-out drunkard"
+ real_name = "drunken consciousness"
+
+/mob/living/split_personality/blackout/Login()
+ . = ..()
+ if(!. || !client)
+ return FALSE
+ to_chat(src, span_notice("You're the incredibly inebriated leftovers of your host's consciousness! Make sure to act the part and leave a trail of confusion and chaos in your wake."))
+ to_chat(src, span_boldwarning("Do not commit suicide or put the body in danger, you have a minor liscense to grief just like a clown, do not kill anyone or create a situation leading to the body being in danger or in harm ways. While you're drunk, you're not suicidal."))
+
#undef OWNER
#undef STRANGER
diff --git a/code/datums/components/butchering.dm b/code/datums/components/butchering.dm
index 0ed00e7dd94..97bb2a30ad5 100644
--- a/code/datums/components/butchering.dm
+++ b/code/datums/components/butchering.dm
@@ -99,50 +99,75 @@
*
* Arguments:
* - [butcher][/mob/living]: The mob doing the butchering
- * - [meat][/mob/living]: The mob being butchered
+ * - [target][/mob/living]: The mob being butchered
*/
-/datum/component/butchering/proc/on_butchering(atom/butcher, mob/living/meat)
+/datum/component/butchering/proc/on_butchering(atom/butcher, mob/living/target)
var/list/results = list()
- var/turf/T = meat.drop_location()
- var/final_effectiveness = effectiveness - meat.butcher_difficulty
+ var/turf/location = target.drop_location()
+ var/final_effectiveness = effectiveness - target.butcher_difficulty
var/bonus_chance = max(0, (final_effectiveness - 100) + bonus_modifier) //so 125 total effectiveness = 25% extra chance
- for(var/V in meat.butcher_results)
- var/obj/bones = V
- var/amount = meat.butcher_results[bones]
+
+ for(var/result_typepath in target.butcher_results)
+ var/obj/remains = result_typepath
+ var/amount = target.butcher_results[remains]
for(var/_i in 1 to amount)
if(!prob(final_effectiveness))
if(butcher)
- to_chat(butcher, span_warning("You fail to harvest some of the [initial(bones.name)] from [meat]."))
+ to_chat(butcher, span_warning("You fail to harvest some of the [initial(remains.name)] from [target]."))
continue
if(prob(bonus_chance))
if(butcher)
- to_chat(butcher, span_info("You harvest some extra [initial(bones.name)] from [meat]!"))
- results += new bones (T)
- results += new bones (T)
+ to_chat(butcher, span_info("You harvest some extra [initial(remains.name)] from [target]!"))
+ results += new remains (location)
+ results += new remains (location)
- meat.butcher_results.Remove(bones) //in case you want to, say, have it drop its results on gib
+ target.butcher_results.Remove(remains) //in case you want to, say, have it drop its results on gib
- for(var/V in meat.guaranteed_butcher_results)
- var/obj/sinew = V
- var/amount = meat.guaranteed_butcher_results[sinew]
+ for(var/guaranteed_result_typepath in target.guaranteed_butcher_results)
+ var/obj/guaranteed_remains = guaranteed_result_typepath
+ var/amount = target.guaranteed_butcher_results[guaranteed_remains]
for(var/i in 1 to amount)
- results += new sinew (T)
- meat.guaranteed_butcher_results.Remove(sinew)
+ results += new guaranteed_remains (location)
+ target.guaranteed_butcher_results.Remove(guaranteed_remains)
for(var/obj/item/carrion in results)
var/list/meat_mats = carrion.has_material_type(/datum/material/meat)
if(!length(meat_mats))
continue
- carrion.set_custom_materials((carrion.custom_materials - meat_mats) + list(GET_MATERIAL_REF(/datum/material/meat/mob_meat, meat) = counterlist_sum(meat_mats)))
+ carrion.set_custom_materials((carrion.custom_materials - meat_mats) + list(GET_MATERIAL_REF(/datum/material/meat/mob_meat, target) = counterlist_sum(meat_mats)))
+
+ // transfer delicious reagents to meat
+ if(target.reagents)
+ var/meat_produced = 0
+ for(var/obj/item/food/meat/slab/target_meat in results)
+ meat_produced += 1
+ for(var/obj/item/food/meat/slab/target_meat in results)
+ target.reagents.trans_to(target_meat, target.reagents.total_volume / meat_produced, remove_blacklisted = TRUE)
+
+ // dont forget yummy diseases either!
+ if(iscarbon(target))
+ var/mob/living/carbon/host_target = target
+ var/list/diseases = host_target.get_static_viruses()
+ if(LAZYLEN(diseases))
+ var/list/datum/disease/diseases_to_add = list()
+ for(var/datum/disease/disease as anything in diseases)
+ // admin or special viruses that should not be reproduced
+ if(disease.spread_flags & (DISEASE_SPREAD_SPECIAL | DISEASE_SPREAD_NON_CONTAGIOUS))
+ continue
+
+ diseases_to_add += disease
+ if(LAZYLEN(diseases_to_add))
+ for(var/obj/diseased_remains in results)
+ diseased_remains.AddComponent(/datum/component/infective, diseases_to_add)
if(butcher)
- butcher.visible_message(span_notice("[butcher] butchers [meat]."), \
- span_notice("You butcher [meat]."))
- butcher_callback?.Invoke(butcher, meat)
- meat.harvest(butcher)
- meat.log_message("has been butchered by [key_name(butcher)]", LOG_ATTACK)
- meat.gib(FALSE, FALSE, TRUE)
+ butcher.visible_message(span_notice("[butcher] butchers [target]."), \
+ span_notice("You butcher [target]."))
+ butcher_callback?.Invoke(butcher, target)
+ target.harvest(butcher)
+ target.log_message("has been butchered by [key_name(butcher)]", LOG_ATTACK)
+ target.gib(FALSE, FALSE, TRUE)
///Enables the butchering mechanic for the mob who has equipped us.
/datum/component/butchering/proc/enable_butchering(datum/source)
@@ -207,9 +232,9 @@
))
///When we are ready to drill through a mob
-/datum/component/butchering/mecha/proc/on_drill(datum/source, obj/vehicle/sealed/mecha/chassis, mob/living/meat)
+/datum/component/butchering/mecha/proc/on_drill(datum/source, obj/vehicle/sealed/mecha/chassis, mob/living/target)
SIGNAL_HANDLER
- INVOKE_ASYNC(src, PROC_REF(on_butchering), chassis, meat)
+ INVOKE_ASYNC(src, PROC_REF(on_butchering), chassis, target)
/datum/component/butchering/wearable
diff --git a/code/datums/components/damage_aura.dm b/code/datums/components/damage_aura.dm
index 2438eca8d79..6eec1903eef 100644
--- a/code/datums/components/damage_aura.dm
+++ b/code/datums/components/damage_aura.dm
@@ -91,14 +91,16 @@
/// What effect the damage aura has if it has an owner.
/datum/component/damage_aura/proc/owner_effect(mob/living/owner_mob, seconds_per_tick)
- owner_mob.adjustStaminaLoss(-20 * seconds_per_tick, updating_stamina = FALSE)
- owner_mob.adjustBruteLoss(-1 * seconds_per_tick, updating_health = FALSE)
- owner_mob.adjustFireLoss(-1 * seconds_per_tick, updating_health = FALSE)
- owner_mob.adjustToxLoss(-1 * seconds_per_tick, updating_health = FALSE, forced = TRUE)
- owner_mob.adjustOxyLoss(-1 * seconds_per_tick, updating_health = FALSE)
+ var/need_mob_update = FALSE
+ need_mob_update += owner_mob.adjustStaminaLoss(-20 * seconds_per_tick, updating_stamina = FALSE)
+ need_mob_update += owner_mob.adjustBruteLoss(-1 * seconds_per_tick, updating_health = FALSE)
+ need_mob_update += owner_mob.adjustFireLoss(-1 * seconds_per_tick, updating_health = FALSE)
+ need_mob_update += owner_mob.adjustToxLoss(-1 * seconds_per_tick, updating_health = FALSE, forced = TRUE)
+ need_mob_update += owner_mob.adjustOxyLoss(-1 * seconds_per_tick, updating_health = FALSE)
if (owner_mob.blood_volume < BLOOD_VOLUME_NORMAL)
owner_mob.blood_volume += 2 * seconds_per_tick
- owner_mob.updatehealth()
+ if(need_mob_update)
+ owner_mob.updatehealth()
/datum/component/damage_aura/process(seconds_per_tick)
var/should_show_effect = COOLDOWN_FINISHED(src, last_damage_effect_time)
diff --git a/code/datums/components/focused_attacker.dm b/code/datums/components/focused_attacker.dm
new file mode 100644
index 00000000000..eda6bd17979
--- /dev/null
+++ b/code/datums/components/focused_attacker.dm
@@ -0,0 +1,71 @@
+/**
+ * Increases our attack damage every time we attack the same target
+ * Not compatible with any other component or status effect which modifies attack damage
+ */
+/datum/component/focused_attacker
+ /// Amount of damage we gain per attack
+ var/gain_per_attack
+ /// Maximum amount by which we can increase our attack power
+ var/maximum_gain
+ /// The last thing we attacked
+ var/atom/last_target
+
+/datum/component/focused_attacker/Initialize(gain_per_attack = 5, maximum_gain = 25)
+ . = ..()
+ if (!isliving(parent) && !isitem(parent))
+ return COMPONENT_INCOMPATIBLE
+ src.maximum_gain = maximum_gain
+ src.gain_per_attack = gain_per_attack
+
+/datum/component/focused_attacker/Destroy(force, silent)
+ if (!isnull(last_target))
+ UnregisterSignal(last_target, COMSIG_QDELETING)
+ return ..()
+
+/datum/component/focused_attacker/RegisterWithParent()
+ if (isliving(parent))
+ RegisterSignals(parent, list(COMSIG_LIVING_UNARMED_ATTACK, COMSIG_HUMAN_MELEE_UNARMED_ATTACK), PROC_REF(pre_mob_attack))
+ else
+ RegisterSignal(parent, COMSIG_ITEM_PRE_ATTACK, PROC_REF(pre_item_attack))
+
+/datum/component/focused_attacker/UnregisterFromParent()
+ UnregisterSignal(parent, list(COMSIG_LIVING_UNARMED_ATTACK, COMSIG_HUMAN_MELEE_UNARMED_ATTACK, COMSIG_ITEM_PRE_ATTACK))
+
+/// Before a mob attacks, try increasing its attack power
+/datum/component/focused_attacker/proc/pre_mob_attack(mob/living/attacker, atom/target)
+ SIGNAL_HANDLER
+ if (isnull(target) || isturf(target))
+ return
+ if (target == last_target)
+ if (attacker.melee_damage_lower - initial(attacker.melee_damage_lower) >= maximum_gain)
+ return
+ attacker.melee_damage_lower += gain_per_attack
+ attacker.melee_damage_upper += gain_per_attack
+ return
+
+ attacker.melee_damage_lower = initial(attacker.melee_damage_lower)
+ attacker.melee_damage_upper = initial(attacker.melee_damage_upper)
+ register_new_target(target)
+
+/// Before an item attacks, try increasing its attack power
+/datum/component/focused_attacker/proc/pre_item_attack(obj/item/weapon, atom/target, mob/user, params)
+ SIGNAL_HANDLER
+ if (target == last_target)
+ if (weapon.force - initial(weapon.force) < maximum_gain)
+ weapon.force += gain_per_attack
+ return
+
+ weapon.force = initial(weapon.force)
+ register_new_target(target)
+
+/// Register a new target
+/datum/component/focused_attacker/proc/register_new_target(atom/target)
+ if (!isnull(last_target))
+ UnregisterSignal(last_target, COMSIG_QDELETING)
+ last_target = target
+ RegisterSignal(target, COMSIG_QDELETING, PROC_REF(on_target_deleted))
+
+/// Drop our target ref on deletion
+/datum/component/focused_attacker/proc/on_target_deleted(target)
+ SIGNAL_HANDLER
+ last_target = null
diff --git a/code/datums/components/manual_heart.dm b/code/datums/components/manual_heart.dm
new file mode 100644
index 00000000000..09448acfc67
--- /dev/null
+++ b/code/datums/components/manual_heart.dm
@@ -0,0 +1,179 @@
+/// If a beat is missed, how long to give before the next is missed
+#define MANUAL_HEART_GRACE_PERIOD 2 SECONDS
+
+/**
+ * Manual heart pumping component. Requires the holder to pump their heart manually every
+ * so often or die.
+ *
+ * Mainly used by the cursed heart.
+ */
+/datum/component/manual_heart
+ /// The action for pumping your heart
+ var/datum/action/cooldown/manual_heart/pump_action
+ /// Cooldown before harm is caused to the owner
+ COOLDOWN_DECLARE(heart_timer)
+ /// If true, add a screen tint on the next process
+ var/add_colour = TRUE
+ /// How long between needed pumps; you can pump one second early
+ var/pump_delay = 3 SECONDS
+ /// How much blood volume you lose every missed pump, this is a flat amount not a percentage!
+ var/blood_loss = BLOOD_VOLUME_NORMAL * 0.2 // 20% of normal volume, missing five pumps is instant death
+
+ //How much to heal per pump - negative numbers harm the owner instead
+ /// The amount of brute damage to heal per pump
+ var/heal_brute = 0
+ /// The amount of burn damage to heal per pump
+ var/heal_burn = 0
+ /// The amount of oxygen damage to heal per pump
+ var/heal_oxy = 0
+
+/datum/component/manual_heart/Initialize(pump_delay = 3 SECONDS, blood_loss = BLOOD_VOLUME_NORMAL * 0.2, heal_brute = 0, heal_burn = 0, heal_oxy = 0)
+ //Non-Carbon mobs can't have hearts, and should never receive this component.
+ if (!iscarbon(parent))
+ stack_trace("Manual Heart component added to [parent] ([parent?.type]) which is not a /mob/living/carbon subtype.")
+ return COMPONENT_INCOMPATIBLE
+
+ src.pump_delay = pump_delay
+ src.blood_loss = blood_loss
+ src.heal_brute = heal_brute
+ src.heal_burn = heal_burn
+ src.heal_oxy = heal_oxy
+
+ pump_action = new(src)
+
+/datum/component/manual_heart/Destroy()
+ QDEL_NULL(pump_action)
+ return ..()
+
+/datum/component/manual_heart/RegisterWithParent()
+ RegisterSignal(parent, COMSIG_CARBON_LOSE_ORGAN, PROC_REF(check_removed_organ))
+ RegisterSignal(parent, COMSIG_CARBON_GAIN_ORGAN, PROC_REF(check_added_organ))
+ RegisterSignal(parent, COMSIG_HEART_MANUAL_PULSE, PROC_REF(on_pump))
+ RegisterSignals(parent, list(COMSIG_LIVING_DEATH, SIGNAL_ADDTRAIT(TRAIT_NOBLOOD)), PROC_REF(pause))
+ RegisterSignals(parent, list(COMSIG_LIVING_REVIVE, SIGNAL_REMOVETRAIT(TRAIT_NOBLOOD)), PROC_REF(restart))
+
+ pump_action.cooldown_time = pump_delay - (1 SECONDS) //you can pump up to a second early
+ pump_action.Grant(parent)
+
+ var/mob/living/carbon/carbon_parent = parent
+ var/obj/item/organ/internal/heart/parent_heart = carbon_parent.get_organ_slot(ORGAN_SLOT_HEART)
+ if(parent_heart && !HAS_TRAIT(carbon_parent, TRAIT_NOBLOOD) && carbon_parent.stat != DEAD)
+ START_PROCESSING(SSdcs, src)
+ COOLDOWN_START(src, heart_timer, pump_delay)
+
+ to_chat(parent, span_userdanger("Your heart no longer beats automatically! You have to pump it manually - otherwise you'll die!"))
+
+/datum/component/manual_heart/UnregisterFromParent()
+ UnregisterSignal(parent, list(COMSIG_CARBON_GAIN_ORGAN, COMSIG_CARBON_LOSE_ORGAN, COMSIG_HEART_MANUAL_PULSE, COMSIG_LIVING_REVIVE, COMSIG_LIVING_DEATH, SIGNAL_ADDTRAIT(TRAIT_NOBLOOD), SIGNAL_REMOVETRAIT(TRAIT_NOBLOOD)))
+
+ to_chat(parent, span_userdanger("You feel your heart start beating normally again!"))
+ var/mob/living/carbon/carbon_parent = parent
+ if(istype(carbon_parent))
+ carbon_parent.remove_client_colour(/datum/client_colour/manual_heart_blood)
+
+/datum/component/manual_heart/proc/restart()
+ SIGNAL_HANDLER
+
+ if(!check_valid())
+ return
+ COOLDOWN_START(src, heart_timer, pump_delay)
+ pump_action.build_all_button_icons(UPDATE_BUTTON_STATUS) //make sure the action button always shows as available when it is
+ START_PROCESSING(SSdcs, src)
+
+/datum/component/manual_heart/proc/pause()
+ SIGNAL_HANDLER
+ pump_action.build_all_button_icons(UPDATE_BUTTON_STATUS)
+ var/mob/living/carbon/carbon_parent = parent
+ if(istype(carbon_parent))
+ carbon_parent.remove_client_colour(/datum/client_colour/manual_heart_blood) //prevents red overlay from getting stuck
+ STOP_PROCESSING(SSdcs, src)
+
+/// Worker proc that checks logic for if a pump can happen, and applies effects from doing so
+/datum/component/manual_heart/proc/on_pump(mob/owner)
+ COOLDOWN_START(src, heart_timer, pump_delay)
+ playsound(owner,'sound/effects/singlebeat.ogg', 40, TRUE)
+
+ var/mob/living/carbon/carbon_owner = owner
+
+ if(HAS_TRAIT(carbon_owner, TRAIT_NOBLOOD))
+ return
+ carbon_owner.blood_volume = min(carbon_owner.blood_volume + (blood_loss * 0.5), BLOOD_VOLUME_MAXIMUM)
+ carbon_owner.remove_client_colour(/datum/client_colour/manual_heart_blood)
+ add_colour = TRUE
+ carbon_owner.adjustBruteLoss(-heal_brute)
+ carbon_owner.adjustFireLoss(-heal_burn)
+ carbon_owner.adjustOxyLoss(-heal_oxy)
+
+/datum/component/manual_heart/process()
+ var/mob/living/carbon/carbon_parent = parent
+
+ //If they aren't connected, don't kill them.
+ if(!carbon_parent.client)
+ COOLDOWN_START(src, heart_timer, pump_delay)
+ return
+
+ if(!COOLDOWN_FINISHED(src, heart_timer))
+ return
+
+ carbon_parent.blood_volume = max(carbon_parent.blood_volume - blood_loss, 0)
+ to_chat(carbon_parent, span_userdanger("You have to keep pumping your blood!"))
+ COOLDOWN_START(src, heart_timer, MANUAL_HEART_GRACE_PERIOD) //give two full seconds before losing more blood
+ if(add_colour)
+ carbon_parent.add_client_colour(/datum/client_colour/manual_heart_blood)
+ add_colour = FALSE
+
+///If a new heart is added, start processing.
+/datum/component/manual_heart/proc/check_added_organ(mob/organ_owner, obj/item/organ/new_organ)
+ SIGNAL_HANDLER
+
+ var/obj/item/organ/internal/heart/new_heart = new_organ
+
+ if(!istype(new_heart) || !check_valid())
+ return
+ COOLDOWN_START(src, heart_timer, pump_delay)
+ pump_action.build_all_button_icons(UPDATE_BUTTON_STATUS)
+ var/mob/living/carbon/carbon_parent = parent
+ if(istype(carbon_parent))
+ carbon_parent.remove_client_colour(/datum/client_colour/manual_heart_blood) //prevents red overlay from getting stuck
+ START_PROCESSING(SSdcs, src)
+
+///If the heart is removed, stop processing.
+/datum/component/manual_heart/proc/check_removed_organ(mob/organ_owner, obj/item/organ/removed_organ)
+ SIGNAL_HANDLER
+
+ var/obj/item/organ/internal/heart/removed_heart = removed_organ
+
+ if(istype(removed_heart))
+ pump_action.build_all_button_icons(UPDATE_BUTTON_STATUS)
+ STOP_PROCESSING(SSdcs, src)
+
+///Helper proc to check if processing can be restarted.
+/datum/component/manual_heart/proc/check_valid()
+ var/mob/living/carbon/carbon_parent = parent
+ var/obj/item/organ/internal/heart/parent_heart = carbon_parent.get_organ_slot(ORGAN_SLOT_HEART)
+ return !isnull(parent_heart) && !HAS_TRAIT(carbon_parent, TRAIT_NOBLOOD) && carbon_parent.stat != DEAD
+
+///Action to pump your heart. Cooldown will always be set to 1 second less than the pump delay.
+/datum/action/cooldown/manual_heart
+ name = "Pump your blood"
+ cooldown_time = 2 SECONDS
+ check_flags = NONE
+ button_icon = 'icons/obj/medical/organs/organs.dmi'
+ button_icon_state = "cursedheart-off"
+
+/datum/action/cooldown/manual_heart/Activate(atom/atom_target)
+ . = ..()
+
+ SEND_SIGNAL(owner, COMSIG_HEART_MANUAL_PULSE)
+
+///The action button is only available when you're a living carbon with blood and a heart.
+/datum/action/cooldown/manual_heart/IsAvailable(feedback = FALSE)
+ var/mob/living/carbon/heart_haver = owner
+ if(!istype(heart_haver) || HAS_TRAIT(heart_haver, TRAIT_NOBLOOD) || heart_haver.stat == DEAD)
+ return FALSE
+ var/obj/item/organ/internal/heart/heart_havers_heart = heart_haver.get_organ_slot(ORGAN_SLOT_HEART)
+ if(isnull(heart_havers_heart))
+ return FALSE
+ return ..()
+
+#undef MANUAL_HEART_GRACE_PERIOD
diff --git a/code/datums/components/tackle.dm b/code/datums/components/tackle.dm
index 4ae3a973d7e..a5b5606bf72 100644
--- a/code/datums/components/tackle.dm
+++ b/code/datums/components/tackle.dm
@@ -445,7 +445,7 @@
if(86 to 92)
user.visible_message(span_danger("[user] slams head-first into [hit], suffering major cranial trauma!"), span_userdanger("You slam head-first into [hit], and the world explodes around you!"))
- user.adjustStaminaLoss(30, updating_stamina=FALSE)
+ user.adjustStaminaLoss(30, updating_stamina = FALSE)
user.adjustBruteLoss(30)
user.adjust_confusion(15 SECONDS)
if(prob(80))
@@ -457,7 +457,7 @@
if(68 to 85)
user.visible_message(span_danger("[user] slams hard into [hit], knocking [user.p_them()] senseless!"), span_userdanger("You slam hard into [hit], knocking yourself senseless!"))
- user.adjustStaminaLoss(30, updating_stamina=FALSE)
+ user.adjustStaminaLoss(30, updating_stamina = FALSE)
user.adjustBruteLoss(10)
user.adjust_confusion(10 SECONDS)
user.Knockdown(3 SECONDS)
@@ -465,7 +465,7 @@
if(1 to 67)
user.visible_message(span_danger("[user] slams into [hit]!"), span_userdanger("You slam into [hit]!"))
- user.adjustStaminaLoss(20, updating_stamina=FALSE)
+ user.adjustStaminaLoss(20, updating_stamina = FALSE)
user.adjustBruteLoss(10)
user.Knockdown(2 SECONDS)
shake_camera(user, 2, 2)
@@ -545,10 +545,11 @@
HOW_big_of_a_miss_did_we_just_make = ", making a ginormous mess!" // an extra exclamation point!! for emphasis!!!
owner.visible_message(span_danger("[owner] trips over [kevved] and slams into it face-first[HOW_big_of_a_miss_did_we_just_make]!"), span_userdanger("You trip over [kevved] and slam into it face-first[HOW_big_of_a_miss_did_we_just_make]!"))
- owner.adjustStaminaLoss(15 + messes.len * 2, FALSE)
- owner.adjustBruteLoss(8 + messes.len)
+ owner.adjustStaminaLoss(15 + messes.len * 2, updating_stamina = FALSE)
+ owner.adjustBruteLoss(8 + messes.len, updating_health = FALSE)
owner.Paralyze(0.4 SECONDS * messes.len) // .4 seconds of paralyze for each thing you knock around
owner.Knockdown(2 SECONDS + 0.4 SECONDS * messes.len) // 2 seconds of knockdown after the paralyze
+ owner.updatehealth()
for(var/obj/item/I in messes)
var/dist = rand(1, 3)
diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm
index b8f26a89b3c..aeea8b22cba 100644
--- a/code/datums/datumvars.dm
+++ b/code/datums/datumvars.dm
@@ -4,7 +4,8 @@
/datum/proc/can_vv_get(var_name)
return TRUE
-/datum/proc/vv_edit_var(var_name, var_value) //called whenever a var is edited
+/// Called when a var is edited with the new value to change to
+/datum/proc/vv_edit_var(var_name, var_value)
if(var_name == NAMEOF(src, vars))
return FALSE
vars[var_name] = var_value
@@ -20,9 +21,14 @@
/datum/proc/can_vv_mark()
return TRUE
-//please call . = ..() first and append to the result, that way parent items are always at the top and child items are further down
-//add separaters by doing . += "---"
+/**
+ * Gets all the dropdown options in the vv menu.
+ * When overriding, make sure to call . = ..() first and appent to the result, that way parent items are always at the top and child items are further down.
+ * Add seperators by doing VV_DROPDOWN_OPTION("", "---")
+ */
/datum/proc/vv_get_dropdown()
+ SHOULD_CALL_PARENT(TRUE)
+
. = list()
VV_DROPDOWN_OPTION("", "---")
VV_DROPDOWN_OPTION(VV_HK_CALLPROC, "Call Proc")
@@ -35,9 +41,11 @@
VV_DROPDOWN_OPTION(VV_HK_MASS_REMOVECOMPONENT, "Mass Remove Component/Element")
VV_DROPDOWN_OPTION(VV_HK_MODIFY_TRAITS, "Modify Traits")
-//This proc is only called if everything topic-wise is verified. The only verifications that should happen here is things like permission checks!
-//href_list is a reference, modifying it in these procs WILL change the rest of the proc in topic.dm of admin/view_variables!
-//This proc is for "high level" actions like admin heal/set species/etc/etc. The low level debugging things should go in admin/view_variables/topic_basic.dm incase this runtimes.
+/**
+ * This proc is only called if everything topic-wise is verified. The only verifications that should happen here is things like permission checks!
+ * href_list is a reference, modifying it in these procs WILL change the rest of the proc in topic.dm of admin/view_variables!
+ * This proc is for "high level" actions like admin heal/set species/etc/etc. The low level debugging things should go in admin/view_variables/topic_basic.dm incase this runtimes.
+ */
/datum/proc/vv_do_topic(list/href_list)
if(!usr || !usr.client || !usr.client.holder || !check_rights(NONE))
return FALSE //This is VV, not to be called by anything else.
diff --git a/code/datums/diseases/advance/symptoms/heal.dm b/code/datums/diseases/advance/symptoms/heal.dm
index 8754eb3b71d..55e2cdd6c65 100644
--- a/code/datums/diseases/advance/symptoms/heal.dm
+++ b/code/datums/diseases/advance/symptoms/heal.dm
@@ -161,8 +161,8 @@
if(!parts.len)
return
- for(var/obj/item/bodypart/L in parts)
- if(L.heal_damage(heal_amt/parts.len, heal_amt/parts.len, BODYTYPE_ORGANIC))
+ for(var/obj/item/bodypart/bodypart in parts)
+ if(bodypart.heal_damage(heal_amt/parts.len, heal_amt/parts.len, required_bodytype = BODYTYPE_ORGANIC))
M.update_damage_overlays()
return 1
@@ -303,8 +303,8 @@
if(prob(5))
to_chat(M, span_notice("The darkness soothes and mends your wounds."))
- for(var/obj/item/bodypart/L in parts)
- if(L.heal_damage(heal_amt/parts.len, heal_amt/parts.len * 0.5, BODYTYPE_ORGANIC)) //more effective on brute
+ for(var/obj/item/bodypart/bodypart in parts)
+ if(bodypart.heal_damage(heal_amt/parts.len, heal_amt/parts.len * 0.5, required_bodytype = BODYTYPE_ORGANIC)) //more effective on brute
M.update_damage_overlays()
return 1
@@ -405,8 +405,8 @@
if(!parts.len)
return
- for(var/obj/item/bodypart/L in parts)
- if(L.heal_damage(heal_amt/parts.len, heal_amt/parts.len, BODYTYPE_ORGANIC))
+ for(var/obj/item/bodypart/bodypart in parts)
+ if(bodypart.heal_damage(heal_amt/parts.len, heal_amt/parts.len, required_bodytype = BODYTYPE_ORGANIC))
M.update_damage_overlays()
if(active_coma && M.getBruteLoss() + M.getFireLoss() == 0)
@@ -469,8 +469,8 @@
if(prob(5))
to_chat(M, span_notice("You feel yourself absorbing the water around you to soothe your damaged skin."))
- for(var/obj/item/bodypart/L in parts)
- if(L.heal_damage(heal_amt/parts.len * 0.5, heal_amt/parts.len, BODYTYPE_ORGANIC))
+ for(var/obj/item/bodypart/bodypart in parts)
+ if(bodypart.heal_damage(heal_amt/parts.len * 0.5, heal_amt/parts.len, required_bodytype = BODYTYPE_ORGANIC))
M.update_damage_overlays()
return 1
@@ -592,8 +592,8 @@
return
if(prob(5))
to_chat(M, span_notice("The pain from your wounds fades rapidly."))
- for(var/obj/item/bodypart/L in parts)
- if(L.heal_damage(heal_amt/parts.len, heal_amt/parts.len, BODYTYPE_ORGANIC))
+ for(var/obj/item/bodypart/bodypart in parts)
+ if(bodypart.heal_damage(heal_amt/parts.len, heal_amt/parts.len, required_bodytype = BODYTYPE_ORGANIC))
M.update_damage_overlays()
return 1
@@ -637,10 +637,13 @@
/datum/symptom/heal/radiation/Heal(mob/living/carbon/M, datum/disease/advance/A, actual_power)
var/heal_amt = actual_power
+ var/need_mob_update = FALSE
if(cellular_damage)
- M.adjustCloneLoss(-heal_amt * 0.5)
+ need_mob_update += M.adjustCloneLoss(-heal_amt * 0.5, updating_health = FALSE)
- M.adjustToxLoss(-(2 * heal_amt))
+ need_mob_update += M.adjustToxLoss(-(2 * heal_amt), updating_health = FALSE)
+ if(need_mob_update)
+ M.updatehealth()
var/list/parts = M.get_damaged_bodyparts(1,1, BODYTYPE_ORGANIC)
@@ -650,8 +653,8 @@
if(prob(4))
to_chat(M, span_notice("Your skin glows faintly, and you feel your wounds mending themselves."))
- for(var/obj/item/bodypart/L in parts)
- if(L.heal_damage(heal_amt/parts.len, heal_amt/parts.len, BODYTYPE_ORGANIC))
+ for(var/obj/item/bodypart/bodypart in parts)
+ if(bodypart.heal_damage(heal_amt/parts.len, heal_amt/parts.len, required_bodytype = BODYTYPE_ORGANIC))
M.update_damage_overlays()
return 1
diff --git a/code/datums/diseases/advance/symptoms/oxygen.dm b/code/datums/diseases/advance/symptoms/oxygen.dm
index 89da211b06b..fad70aff23f 100644
--- a/code/datums/diseases/advance/symptoms/oxygen.dm
+++ b/code/datums/diseases/advance/symptoms/oxygen.dm
@@ -38,8 +38,8 @@
var/mob/living/carbon/infected_mob = advanced_disease.affected_mob
switch(advanced_disease.stage)
if(4, 5)
- infected_mob.adjustOxyLoss(-7, 0)
infected_mob.losebreath = max(0, infected_mob.losebreath - 4)
+ infected_mob.adjustOxyLoss(-7)
if(regenerate_blood && infected_mob.blood_volume < BLOOD_VOLUME_NORMAL)
infected_mob.blood_volume += 1
else
diff --git a/code/datums/diseases/chronic_illness.dm b/code/datums/diseases/chronic_illness.dm
index 77c162d6d85..129883c17b5 100644
--- a/code/datums/diseases/chronic_illness.dm
+++ b/code/datums/diseases/chronic_illness.dm
@@ -31,19 +31,23 @@
to_chat(affected_mob, span_notice("You look at your hand. Your vision blurs."))
affected_mob.set_eye_blur_if_lower(10 SECONDS)
if(3)
+ var/need_mob_update = FALSE
if(SPT_PROB(0.5, seconds_per_tick))
to_chat(affected_mob, span_danger("You feel a very sharp pain in your chest!"))
if(prob(45))
affected_mob.vomit(VOMIT_CATEGORY_BLOOD, lost_nutrition = 20)
if(SPT_PROB(0.5, seconds_per_tick))
to_chat(affected_mob, span_userdanger("[pick("You feel your heart slowing...", "You relax and slow your heartbeat.")]"))
- affected_mob.adjustStaminaLoss(70, FALSE)
+ need_mob_update += affected_mob.adjustStaminaLoss(70, updating_stamina = FALSE)
if(SPT_PROB(1, seconds_per_tick))
to_chat(affected_mob, span_danger("You feel a buzzing in your brain."))
SEND_SOUND(affected_mob, sound('sound/weapons/flash_ring.ogg'))
if(SPT_PROB(0.5, seconds_per_tick))
- affected_mob.adjustBruteLoss(1)
+ need_mob_update += affected_mob.adjustBruteLoss(1, updating_health = FALSE)
+ if(need_mob_update)
+ affected_mob.updatehealth()
if(4)
+ var/need_mob_update = FALSE
if(prob(30))
affected_mob.playsound_local(affected_mob, 'sound/effects/singlebeat.ogg', 100, FALSE, use_reverb = FALSE)
if(SPT_PROB(1, seconds_per_tick))
@@ -51,7 +55,7 @@
if(prob(75))
affected_mob.vomit(VOMIT_CATEGORY_BLOOD, lost_nutrition = 45)
if(SPT_PROB(1, seconds_per_tick))
- affected_mob.adjustStaminaLoss(100, FALSE)
+ need_mob_update += affected_mob.adjustStaminaLoss(100, updating_stamina = FALSE)
affected_mob.visible_message(span_warning("[affected_mob] collapses!"))
if(prob(30))
to_chat(affected_mob, span_danger("Your vision blurs as you faint!"))
@@ -59,7 +63,9 @@
if(SPT_PROB(0.5, seconds_per_tick))
to_chat(affected_mob, span_danger("[pick("You feel as though your atoms are accelerating in place.", "You feel like you're being torn apart!")]"))
affected_mob.emote("scream")
- affected_mob.adjustBruteLoss(10)
+ need_mob_update += affected_mob.adjustBruteLoss(10, updating_health = FALSE)
+ if(need_mob_update)
+ affected_mob.updatehealth()
if(5)
switch(rand(1,2))
if(1)
diff --git a/code/datums/diseases/rhumba_beat.dm b/code/datums/diseases/rhumba_beat.dm
index 01188137915..e64002ab528 100644
--- a/code/datums/diseases/rhumba_beat.dm
+++ b/code/datums/diseases/rhumba_beat.dm
@@ -18,7 +18,7 @@
switch(stage)
if(2)
if(SPT_PROB(26, seconds_per_tick))
- affected_mob.adjustFireLoss(5, FALSE)
+ affected_mob.adjustFireLoss(5)
if(SPT_PROB(0.5, seconds_per_tick))
to_chat(affected_mob, span_danger("You feel strange..."))
if(3)
diff --git a/code/datums/diseases/tuberculosis.dm b/code/datums/diseases/tuberculosis.dm
index dd75ea7cc62..de87cab6f3f 100644
--- a/code/datums/diseases/tuberculosis.dm
+++ b/code/datums/diseases/tuberculosis.dm
@@ -28,23 +28,27 @@
if(SPT_PROB(2.5, seconds_per_tick))
to_chat(affected_mob, span_danger("You feel a cold sweat form."))
if(4)
+ var/need_mob_update = FALSE
if(SPT_PROB(1, seconds_per_tick))
to_chat(affected_mob, span_userdanger("You see four of everything!"))
affected_mob.set_dizzy_if_lower(10 SECONDS)
if(SPT_PROB(1, seconds_per_tick))
to_chat(affected_mob, span_danger("You feel a sharp pain from your lower chest!"))
- affected_mob.adjustOxyLoss(5, FALSE)
+ need_mob_update += affected_mob.adjustOxyLoss(5, updating_health = FALSE)
affected_mob.emote("gasp")
if(SPT_PROB(5, seconds_per_tick))
to_chat(affected_mob, span_danger("You feel air escape from your lungs painfully."))
- affected_mob.adjustOxyLoss(25, FALSE)
+ need_mob_update += affected_mob.adjustOxyLoss(25, updating_health = FALSE)
affected_mob.emote("gasp")
+ if(need_mob_update)
+ affected_mob.updatehealth()
if(5)
+ var/need_mob_update = FALSE
if(SPT_PROB(1, seconds_per_tick))
to_chat(affected_mob, span_userdanger("[pick("You feel your heart slowing...", "You relax and slow your heartbeat.")]"))
- affected_mob.adjustStaminaLoss(70, FALSE)
+ need_mob_update += affected_mob.adjustStaminaLoss(70, updating_stamina = FALSE)
if(SPT_PROB(5, seconds_per_tick))
- affected_mob.adjustStaminaLoss(100, FALSE)
+ need_mob_update += affected_mob.adjustStaminaLoss(100, updating_stamina = FALSE)
affected_mob.visible_message(span_warning("[affected_mob] faints!"), span_userdanger("You surrender yourself and feel at peace..."))
affected_mob.AdjustSleeping(100)
if(SPT_PROB(1, seconds_per_tick))
@@ -59,3 +63,5 @@
if(SPT_PROB(7.5, seconds_per_tick))
to_chat(affected_mob, span_danger("[pick("You feel uncomfortably hot...", "You feel like unzipping your jumpsuit...", "You feel like taking off some clothes...")]"))
affected_mob.adjust_bodytemperature(40)
+ if(need_mob_update)
+ affected_mob.updatehealth()
diff --git a/code/datums/elements/waddling.dm b/code/datums/elements/waddling.dm
index 9d9aede83ed..825b0c4e4cb 100644
--- a/code/datums/elements/waddling.dm
+++ b/code/datums/elements/waddling.dm
@@ -4,30 +4,21 @@
. = ..()
if(!ismovable(target))
return ELEMENT_INCOMPATIBLE
- if(isliving(target))
- RegisterSignal(target, COMSIG_MOVABLE_MOVED, PROC_REF(LivingWaddle))
- else
- RegisterSignal(target, COMSIG_MOVABLE_MOVED, PROC_REF(Waddle))
+ RegisterSignal(target, COMSIG_MOVABLE_MOVED, PROC_REF(Waddle))
/datum/element/waddling/Detach(datum/source)
. = ..()
UnregisterSignal(source, COMSIG_MOVABLE_MOVED)
-
-/datum/element/waddling/proc/LivingWaddle(mob/living/target, atom/oldloc, direction, forced)
+/datum/element/waddling/proc/Waddle(atom/movable/moved, atom/oldloc, direction, forced)
SIGNAL_HANDLER
-
- if(forced || target.incapacitated() || target.body_position == LYING_DOWN || CHECK_MOVE_LOOP_FLAGS(target, MOVEMENT_LOOP_OUTSIDE_CONTROL))
- return
- waddling_animation(target)
-
-
-/datum/element/waddling/proc/Waddle(atom/movable/target, atom/oldloc, direction, forced)
- SIGNAL_HANDLER
-
- if(forced || CHECK_MOVE_LOOP_FLAGS(target, MOVEMENT_LOOP_OUTSIDE_CONTROL))
+ if(forced || CHECK_MOVE_LOOP_FLAGS(moved, MOVEMENT_LOOP_OUTSIDE_CONTROL))
return
- waddling_animation(target)
+ if(isliving(moved))
+ var/mob/living/living_moved = moved
+ if (living_moved.incapacitated() || living_moved.body_position == LYING_DOWN)
+ return
+ waddling_animation(moved)
/datum/element/waddling/proc/waddling_animation(atom/movable/target)
animate(target, pixel_z = 4, time = 0)
diff --git a/code/datums/elements/wheel.dm b/code/datums/elements/wheel.dm
new file mode 100644
index 00000000000..2bb8977ca5c
--- /dev/null
+++ b/code/datums/elements/wheel.dm
@@ -0,0 +1,28 @@
+/// Element which spins you as you move
+/datum/element/wheel
+
+/datum/element/wheel/Attach(datum/target)
+ . = ..()
+ if(!ismovable(target))
+ return ELEMENT_INCOMPATIBLE
+ RegisterSignal(target, COMSIG_MOVABLE_MOVED, PROC_REF(on_moved))
+
+/datum/element/wheel/Detach(datum/source)
+ . = ..()
+ UnregisterSignal(source, COMSIG_MOVABLE_MOVED)
+
+/datum/element/wheel/proc/on_moved(atom/movable/moved, atom/oldloc, direction, forced)
+ SIGNAL_HANDLER
+ if(forced || CHECK_MOVE_LOOP_FLAGS(moved, MOVEMENT_LOOP_OUTSIDE_CONTROL))
+ return
+ if(isliving(moved))
+ var/mob/living/living_moved = moved
+ if (living_moved.incapacitated() || living_moved.body_position == LYING_DOWN)
+ return
+ var/rotation_degree = (360 / 3)
+ if(direction & SOUTHWEST)
+ rotation_degree *= -1
+
+ var/matrix/to_turn = matrix(moved.transform)
+ to_turn = turn(moved.transform, rotation_degree)
+ animate(moved, transform = to_turn, time = 0.1 SECONDS, flags = ANIMATION_PARALLEL)
diff --git a/code/datums/id_trim/jobs.dm b/code/datums/id_trim/jobs.dm
index d2939529dc6..6d50347aa3d 100644
--- a/code/datums/id_trim/jobs.dm
+++ b/code/datums/id_trim/jobs.dm
@@ -766,7 +766,7 @@
assignment = "Prisoner"
trim_state = "trim_warden"
department_color = COLOR_PRISONER_BLACK
- subdepartment_color = COLOR_PRISONER_ORANGE
+ subdepartment_color = COLOR_PRISONER_BLACK
sechud_icon_state = SECHUD_PRISONER
template_access = list(
ACCESS_CAPTAIN,
diff --git a/code/datums/lazy_template.dm b/code/datums/lazy_template.dm
index a5ae9e413f3..e3006e13056 100644
--- a/code/datums/lazy_template.dm
+++ b/code/datums/lazy_template.dm
@@ -64,12 +64,18 @@
if(!reservation)
CRASH("Failed to reserve a block for lazy template: '[key]'")
+ // lists kept for overall loading
var/list/loaded_atom_movables = list()
var/list/loaded_turfs = list()
var/list/loaded_areas = list()
+
+ var/list/obj/structure/cable/loaded_cables = list()
+ var/list/obj/machinery/atmospherics/loaded_atmospherics = list()
+
for(var/z_idx in parsed_template.parsed_bounds[MAP_MAXZ] to 1 step -1)
var/turf/bottom_left = reservation.bottom_left_turfs[z_idx]
var/turf/top_right = reservation.top_right_turfs[z_idx]
+
load_map(
file(load_path),
bottom_left.x,
@@ -81,12 +87,20 @@
for(var/turf/turf as anything in block(bottom_left, top_right))
loaded_turfs += turf
loaded_areas |= get_area(turf)
- for(var/thing in turf.get_all_contents())
- // atoms can actually be in the contents of two or more turfs based on its icon/bound size
- // see https://www.byond.com/docs/ref/index.html#/atom/var/contents
+
+ // atoms can actually be in the contents of two or more turfs based on its icon/bound size
+ // see https://www.byond.com/docs/ref/index.html#/atom/var/contents
+ for(var/thing in (turf.get_all_contents() - turf))
+ if(istype(thing, /obj/structure/cable))
+ loaded_cables += thing
+ else if(istype(thing, /obj/machinery/atmospherics))
+ loaded_atmospherics += thing
loaded_atom_movables |= thing
- SSatoms.InitializeAtoms(loaded_atom_movables + loaded_turfs + loaded_areas)
+ SSatoms.InitializeAtoms(loaded_areas + loaded_atom_movables + loaded_turfs)
+ SSmachines.setup_template_powernets(loaded_cables)
+ SSair.setup_template_machinery(loaded_atmospherics)
+
SEND_SIGNAL(src, COMSIG_LAZY_TEMPLATE_LOADED, loaded_atom_movables, loaded_turfs, loaded_areas)
reservations += reservation
return reservation
diff --git a/code/datums/martial/cqc.dm b/code/datums/martial/cqc.dm
index c982f0e086c..e5b959b340f 100644
--- a/code/datums/martial/cqc.dm
+++ b/code/datums/martial/cqc.dm
@@ -80,9 +80,21 @@
return TRUE
/datum/martial_art/cqc/proc/Kick(mob/living/attacker, mob/living/defender)
- if(!can_use(attacker))
+ if(!can_use(attacker) || defender.stat != CONSCIOUS)
return FALSE
- if(!defender.stat || !defender.IsParalyzed())
+
+ if(defender.body_position == LYING_DOWN && !defender.IsUnconscious() && defender.getStaminaLoss() >= 100)
+ log_combat(attacker, defender, "knocked out (Head kick)(CQC)")
+ defender.visible_message(span_danger("[attacker] kicks [defender]'s head, knocking [defender.p_them()] out!"), \
+ span_userdanger("You're knocked unconscious by [attacker]!"), span_hear("You hear a sickening sound of flesh hitting flesh!"), null, attacker)
+ to_chat(attacker, span_danger("You kick [defender]'s head, knocking [defender.p_them()] out!"))
+ playsound(get_turf(attacker), 'sound/weapons/genhit1.ogg', 50, TRUE, -1)
+
+ var/helmet_protection = defender.run_armor_check(BODY_ZONE_HEAD, MELEE)
+ defender.apply_effect(20 SECONDS, EFFECT_KNOCKDOWN, helmet_protection)
+ defender.apply_effect(10 SECONDS, EFFECT_UNCONSCIOUS, helmet_protection)
+ defender.adjustOrganLoss(ORGAN_SLOT_BRAIN, 15, 150)
+ else
defender.visible_message(span_danger("[attacker] kicks [defender] back!"), \
span_userdanger("You're kicked back by [attacker]!"), span_hear("You hear a sickening sound of flesh hitting flesh!"), COMBAT_MESSAGE_RANGE, attacker)
to_chat(attacker, span_danger("You kick [defender] back!"))
@@ -90,17 +102,9 @@
var/atom/throw_target = get_edge_target_turf(defender, attacker.dir)
defender.throw_at(throw_target, 1, 14, attacker)
defender.apply_damage(10, attacker.get_attack_type())
+ defender.adjustStaminaLoss(45)
log_combat(attacker, defender, "kicked (CQC)")
- . = TRUE
- if(defender.IsParalyzed() && !defender.stat)
- log_combat(attacker, defender, "knocked out (Head kick)(CQC)")
- defender.visible_message(span_danger("[attacker] kicks [defender]'s head, knocking [defender.p_them()] out!"), \
- span_userdanger("You're knocked unconscious by [attacker]!"), span_hear("You hear a sickening sound of flesh hitting flesh!"), null, attacker)
- to_chat(attacker, span_danger("You kick [defender]'s head, knocking [defender.p_them()] out!"))
- playsound(get_turf(attacker), 'sound/weapons/genhit1.ogg', 50, TRUE, -1)
- defender.SetSleeping(30 SECONDS)
- defender.adjustOrganLoss(ORGAN_SLOT_BRAIN, 15, 150)
- . = TRUE
+ . = TRUE
/datum/martial_art/cqc/proc/Pressure(mob/living/attacker, mob/living/defender)
if(!can_use(attacker))
@@ -166,6 +170,19 @@
/datum/martial_art/cqc/harm_act(mob/living/attacker, mob/living/defender)
if(!can_use(attacker))
return FALSE
+
+ if(attacker.resting && defender.stat != DEAD && defender.body_position == STANDING_UP)
+ defender.visible_message(span_danger("[attacker] leg sweeps [defender]!"), \
+ span_userdanger("Your legs are sweeped by [attacker]!"), span_hear("You hear a sickening sound of flesh hitting flesh!"), null, attacker)
+ to_chat(attacker, span_danger("You leg sweep [defender]!"))
+ playsound(get_turf(attacker), 'sound/effects/hit_kick.ogg', 50, TRUE, -1)
+ attacker.do_attack_animation(defender)
+ defender.apply_damage(10, BRUTE)
+ defender.Knockdown(5 SECONDS)
+ log_combat(attacker, defender, "sweeped (CQC)")
+ reset_streak()
+ return TRUE
+
add_to_streak("H", defender)
if(check_streak(attacker, defender))
return TRUE
@@ -185,14 +202,7 @@
span_userdanger("You're [picked_hit_type]ed by [attacker]!"), span_hear("You hear a sickening sound of flesh hitting flesh!"), COMBAT_MESSAGE_RANGE, attacker)
to_chat(attacker, span_danger("You [picked_hit_type] [defender]!"))
log_combat(attacker, defender, "[picked_hit_type]s (CQC)")
- if(attacker.resting && !defender.stat && !defender.IsParalyzed())
- defender.visible_message(span_danger("[attacker] leg sweeps [defender]!"), \
- span_userdanger("Your legs are sweeped by [attacker]!"), span_hear("You hear a sickening sound of flesh hitting flesh!"), null, attacker)
- to_chat(attacker, span_danger("You leg sweep [defender]!"))
- playsound(get_turf(attacker), 'sound/effects/hit_kick.ogg', 50, TRUE, -1)
- defender.apply_damage(10, BRUTE)
- defender.Paralyze(6 SECONDS)
- log_combat(attacker, defender, "sweeped (CQC)")
+
return TRUE
/datum/martial_art/cqc/disarm_act(mob/living/attacker, mob/living/defender)
@@ -239,7 +249,7 @@
to_chat(usr, "You try to remember some of the basics of CQC.")
to_chat(usr, "[span_notice("Slam")]: Grab Punch. Slam opponent into the ground, knocking them down.")
- to_chat(usr, "[span_notice("CQC Kick")]: Punch Punch. Knocks opponent away. Knocks out stunned or knocked down opponents.")
+ to_chat(usr, "[span_notice("CQC Kick")]: Punch Punch. Knocks opponent away. Knocks out stunned opponents and does stamina damage.")
to_chat(usr, "[span_notice("Restrain")]: Grab Grab. Locks opponents into a restraining position, disarm to knock them out with a chokehold.")
to_chat(usr, "[span_notice("Pressure")]: Shove Grab. Decent stamina damage.")
to_chat(usr, "[span_notice("Consecutive CQC")]: Shove Shove Punch. Mainly offensive move, huge damage and decent stamina damage.")
diff --git a/code/datums/mood_events/drug_events.dm b/code/datums/mood_events/drug_events.dm
index c734f2797b4..8ac323dda7a 100644
--- a/code/datums/mood_events/drug_events.dm
+++ b/code/datums/mood_events/drug_events.dm
@@ -19,6 +19,10 @@
else
description = initial(description)
+/datum/mood_event/hang_over
+ mood_change = -4
+ description = "I have a killer hang over!"
+ timeout = 1 MINUTES
/datum/mood_event/smoked
description = "I have had a smoke recently."
diff --git a/code/datums/quirks/positive_quirks/drunk_healing.dm b/code/datums/quirks/positive_quirks/drunk_healing.dm
index fbab2503b4e..e1c4ba91125 100644
--- a/code/datums/quirks/positive_quirks/drunk_healing.dm
+++ b/code/datums/quirks/positive_quirks/drunk_healing.dm
@@ -10,13 +10,16 @@
mail_goodies = list(/obj/effect/spawner/random/food_or_drink/booze)
/datum/quirk/drunkhealing/process(seconds_per_tick)
+ var/need_mob_update = FALSE
switch(quirk_holder.get_drunk_amount())
if (6 to 40)
- quirk_holder.adjustBruteLoss(-0.1 * seconds_per_tick, FALSE, required_bodytype = BODYTYPE_ORGANIC)
- quirk_holder.adjustFireLoss(-0.05 * seconds_per_tick, required_bodytype = BODYTYPE_ORGANIC)
+ need_mob_update += quirk_holder.adjustBruteLoss(-0.1 * seconds_per_tick, updating_health = FALSE, required_bodytype = BODYTYPE_ORGANIC)
+ need_mob_update += quirk_holder.adjustFireLoss(-0.05 * seconds_per_tick, updating_health = FALSE, required_bodytype = BODYTYPE_ORGANIC)
if (41 to 60)
- quirk_holder.adjustBruteLoss(-0.4 * seconds_per_tick, FALSE, required_bodytype = BODYTYPE_ORGANIC)
- quirk_holder.adjustFireLoss(-0.2 * seconds_per_tick, required_bodytype = BODYTYPE_ORGANIC)
+ need_mob_update += quirk_holder.adjustBruteLoss(-0.4 * seconds_per_tick, updating_health = FALSE, required_bodytype = BODYTYPE_ORGANIC)
+ need_mob_update += quirk_holder.adjustFireLoss(-0.2 * seconds_per_tick, updating_health = FALSE, required_bodytype = BODYTYPE_ORGANIC)
if (61 to INFINITY)
- quirk_holder.adjustBruteLoss(-0.8 * seconds_per_tick, FALSE, required_bodytype = BODYTYPE_ORGANIC)
- quirk_holder.adjustFireLoss(-0.4 * seconds_per_tick, required_bodytype = BODYTYPE_ORGANIC)
+ need_mob_update += quirk_holder.adjustBruteLoss(-0.8 * seconds_per_tick, updating_health = FALSE, required_bodytype = BODYTYPE_ORGANIC)
+ need_mob_update += quirk_holder.adjustFireLoss(-0.4 * seconds_per_tick, updating_health = FALSE, required_bodytype = BODYTYPE_ORGANIC)
+ if(need_mob_update)
+ quirk_holder.updatehealth()
diff --git a/code/datums/ruins/lavaland.dm b/code/datums/ruins/lavaland.dm
index 968e6df544e..91b964e9d31 100644
--- a/code/datums/ruins/lavaland.dm
+++ b/code/datums/ruins/lavaland.dm
@@ -53,7 +53,7 @@
Probably best to stay clear."
prefix = "_maps/RandomRuins/LavaRuins/skyrat/" // SKYRAT ADDITION
suffix = "lavaland_surface_ash_walker1_skyrat.dmm" // SKYRAT EDIT - ORIGINAL: lavaland_surface_ash_walker1.dmm
- always_place = TRUE //SKYRAT EDIT CHANGE
+ cost = 1000 //SKYRAT EDIT: Original: 20
allow_duplicates = FALSE
//SKYRAT EDIT REMOVAL BEGIN - MAPPING
/*
diff --git a/code/datums/status_effects/buffs.dm b/code/datums/status_effects/buffs.dm
index cb0b55be059..fd9e3d9aee5 100644
--- a/code/datums/status_effects/buffs.dm
+++ b/code/datums/status_effects/buffs.dm
@@ -44,13 +44,15 @@
owner.apply_status_effect(/datum/status_effect/his_wrath)
qdel(src)
return
- var/grace_heal = bloodlust * 0.05
- owner.adjustBruteLoss(-grace_heal)
- owner.adjustFireLoss(-grace_heal)
- owner.adjustToxLoss(-grace_heal, TRUE, TRUE)
- owner.adjustOxyLoss(-(grace_heal * 2))
- owner.adjustCloneLoss(-grace_heal)
-
+ var/grace_heal = bloodlust * 0.02
+ var/need_mob_update = FALSE
+ need_mob_update += owner.adjustBruteLoss(-grace_heal * seconds_between_ticks, updating_health = FALSE, forced = TRUE)
+ need_mob_update += owner.adjustFireLoss(-grace_heal * seconds_between_ticks, updating_health = FALSE, forced = TRUE)
+ need_mob_update += owner.adjustToxLoss(-grace_heal * seconds_between_ticks, forced = TRUE)
+ need_mob_update += owner.adjustOxyLoss(-(grace_heal * 2) * seconds_between_ticks, updating_health = FALSE, forced = TRUE)
+ need_mob_update += owner.adjustCloneLoss(-grace_heal * seconds_between_ticks, updating_health = FALSE, forced = TRUE)
+ if(need_mob_update)
+ owner.updatehealth()
/datum/status_effect/wish_granters_gift //Fully revives after ten seconds.
id = "wish_granters_gift"
@@ -61,7 +63,6 @@
to_chat(owner, span_notice("Death is not your end! The Wish Granter's energy suffuses you, and you begin to rise..."))
return ..()
-
/datum/status_effect/wish_granters_gift/on_remove()
owner.revive(ADMIN_HEAL_ALL)
owner.visible_message(span_warning("[owner] appears to wake from the dead, having healed all wounds!"), span_notice("You have regenerated."))
@@ -140,9 +141,12 @@
if(owner.on_fire)
return
- owner.adjustBruteLoss(-10, FALSE)
- owner.adjustFireLoss(-5, FALSE)
- owner.adjustOxyLoss(-10)
+ var/need_mob_update = FALSE
+ need_mob_update += owner.adjustBruteLoss(-4 * seconds_between_ticks, updating_health = FALSE)
+ need_mob_update += owner.adjustFireLoss(-2 * seconds_between_ticks, updating_health = FALSE)
+ need_mob_update += owner.adjustOxyLoss(-4 * seconds_between_ticks, updating_health = FALSE)
+ if(need_mob_update)
+ owner.updatehealth()
/datum/status_effect/fleshmend/proc/on_ignited(datum/source)
SIGNAL_HANDLER
@@ -254,13 +258,16 @@
//Because a servant of medicines stops at nothing to help others, lets keep them on their toes and give them an additional boost.
if(itemUser.health < itemUser.maxHealth)
new /obj/effect/temp_visual/heal(get_turf(itemUser), "#375637")
- itemUser.adjustBruteLoss(-1.5)
- itemUser.adjustFireLoss(-1.5)
- itemUser.adjustToxLoss(-1.5, forced = TRUE) //Because Slime People are people too
- itemUser.adjustOxyLoss(-1.5, forced = TRUE)
- itemUser.adjustStaminaLoss(-1.5)
- itemUser.adjustOrganLoss(ORGAN_SLOT_BRAIN, -1.5)
- itemUser.adjustCloneLoss(-0.5) //Becasue apparently clone damage is the bastion of all health
+ var/need_mob_update = FALSE
+ need_mob_update += itemUser.adjustBruteLoss(-0.6 * seconds_between_ticks, updating_health = FALSE, forced = TRUE)
+ need_mob_update += itemUser.adjustFireLoss(-0.6 * seconds_between_ticks, updating_health = FALSE, forced = TRUE)
+ need_mob_update += itemUser.adjustToxLoss(-0.6 * seconds_between_ticks, updating_health = FALSE, forced = TRUE) //Because Slime People are people too
+ need_mob_update += itemUser.adjustOxyLoss(-0.6 * seconds_between_ticks, updating_health = FALSE, forced = TRUE)
+ need_mob_update += itemUser.adjustStaminaLoss(-0.6 * seconds_between_ticks, updating_stamina = FALSE, forced = TRUE)
+ need_mob_update += itemUser.adjustOrganLoss(ORGAN_SLOT_BRAIN, -0.6 * seconds_between_ticks)
+ need_mob_update += itemUser.adjustCloneLoss(-0.2 * seconds_between_ticks, updating_health = FALSE, forced = TRUE) //Because apparently clone damage is the bastion of all health
+ if(need_mob_update)
+ itemUser.updatehealth()
/datum/status_effect/hippocratic_oath/proc/consume_owner()
owner.visible_message(span_notice("[owner]'s soul is absorbed into the rod, relieving the previous snake of its duty."))
@@ -274,7 +281,6 @@
owner.investigate_log("has been consumed by the Rod of Asclepius.", INVESTIGATE_DEATHS)
qdel(owner)
-
/datum/status_effect/good_music
id = "Good Music"
alert_type = null
@@ -444,10 +450,13 @@
qdel(src)
return
- owner.adjustBruteLoss(-2 * seconds_between_ticks, updating_health = FALSE)
- owner.adjustFireLoss(-2 * seconds_between_ticks, updating_health = FALSE)
- owner.adjustOxyLoss(-4 * seconds_between_ticks, updating_health = FALSE)
- owner.adjustStaminaLoss(-4 * seconds_between_ticks, updating_stamina = FALSE)
+ var/need_mob_update = FALSE
+ need_mob_update += owner.adjustBruteLoss(-2 * seconds_between_ticks, updating_health = FALSE)
+ need_mob_update += owner.adjustFireLoss(-2 * seconds_between_ticks, updating_health = FALSE)
+ need_mob_update += owner.adjustOxyLoss(-4 * seconds_between_ticks, updating_health = FALSE)
+ need_mob_update += owner.adjustStaminaLoss(-4 * seconds_between_ticks, updating_stamina = FALSE)
+ if(need_mob_update)
+ owner.updatehealth()
owner.adjust_bodytemperature(BODYTEMP_NORMAL, 0, BODYTEMP_NORMAL) //Won't save you from the void of space, but it will stop you from freezing or suffocating in low pressure
diff --git a/code/datums/status_effects/debuffs/debuffs.dm b/code/datums/status_effects/debuffs/debuffs.dm
index 8c8f910fd57..ff3e1762074 100644
--- a/code/datums/status_effects/debuffs/debuffs.dm
+++ b/code/datums/status_effects/debuffs/debuffs.dm
@@ -206,6 +206,7 @@
if(locate(/obj/item/pillow) in owner.loc)
healing += 0.1
+ var/need_mob_update = FALSE
if(healing > 0)
if(iscarbon(owner))
var/mob/living/carbon/carbon_owner = owner
@@ -219,10 +220,12 @@
target_organ.apply_organ_damage(-healing_bonus * target_organ.maxHealth)
if(health_ratio > 0.8) // only heals minor physical damage
- owner.adjustBruteLoss(-1 * healing, required_bodytype = BODYTYPE_ORGANIC)
- owner.adjustFireLoss(-1 * healing, required_bodytype = BODYTYPE_ORGANIC)
- owner.adjustToxLoss(-1 * healing * 0.5, TRUE, TRUE, required_biotype = MOB_ORGANIC)
- owner.adjustStaminaLoss(min(-1 * healing, -1 * HEALING_SLEEP_DEFAULT))
+ need_mob_update += owner.adjustBruteLoss(-0.4 * healing * seconds_between_ticks, updating_health = FALSE, required_bodytype = BODYTYPE_ORGANIC)
+ need_mob_update += owner.adjustFireLoss(-0.4 * healing * seconds_between_ticks, updating_health = FALSE, required_bodytype = BODYTYPE_ORGANIC)
+ need_mob_update += owner.adjustToxLoss(-0.2 * healing * seconds_between_ticks, updating_health = FALSE, forced = TRUE, required_biotype = MOB_ORGANIC)
+ need_mob_update += owner.adjustStaminaLoss(min(-0.4 * healing * seconds_between_ticks, -0.4 * HEALING_SLEEP_DEFAULT * seconds_between_ticks), updating_stamina = FALSE)
+ if(need_mob_update)
+ owner.updatehealth()
// Drunkenness gets reduced by 0.3% per tick (6% per 2 seconds)
owner.set_drunk_effect(owner.get_drunk_amount() * 0.997)
@@ -311,9 +314,12 @@
for(var/obj/item/his_grace/HG in owner.held_items)
qdel(src)
return
- owner.adjustBruteLoss(0.1)
- owner.adjustFireLoss(0.1)
- owner.adjustToxLoss(0.2, TRUE, TRUE)
+ var/need_mob_update
+ need_mob_update = owner.adjustBruteLoss(0.04 * seconds_between_ticks, updating_health = FALSE)
+ need_mob_update += owner.adjustFireLoss(0.04 * seconds_between_ticks, updating_health = FALSE)
+ need_mob_update += owner.adjustToxLoss(0.08 * seconds_between_ticks, updating_health = FALSE, forced = TRUE)
+ if(need_mob_update)
+ owner.updatehealth()
/datum/status_effect/cultghost //is a cult ghost and can't use manifest runes
id = "cult_ghost"
@@ -821,7 +827,8 @@
/datum/status_effect/ants/tick(seconds_between_ticks)
var/mob/living/carbon/human/victim = owner
- victim.adjustBruteLoss(max(0.1, round((ants_remaining * 0.004),0.1))) //Scales with # of ants (lowers with time). Roughly 10 brute over 50 seconds.
+ var/need_mob_update
+ need_mob_update = victim.adjustBruteLoss(max(0.1, round((ants_remaining * 0.0016) * seconds_between_ticks,0.1)), updating_health = FALSE) //Scales with # of ants (lowers with time). Roughly 10 brute over 50 seconds.
if(victim.stat <= SOFT_CRIT) //Makes sure people don't scratch at themselves while they're in a critical condition
if(prob(15))
switch(rand(1,2))
@@ -834,20 +841,22 @@
if (1 to 8) //16% Chance
var/obj/item/bodypart/head/hed = victim.get_bodypart(BODY_ZONE_HEAD)
to_chat(victim, span_danger("You scratch at the ants on your scalp!."))
- hed.receive_damage(1,0)
+ need_mob_update += hed.receive_damage(brute = 0.4 * seconds_between_ticks, burn = 0, updating_health = FALSE)
if (9 to 29) //40% chance
var/obj/item/bodypart/arm = victim.get_bodypart(pick(BODY_ZONE_L_ARM,BODY_ZONE_R_ARM))
to_chat(victim, span_danger("You scratch at the ants on your arms!"))
- arm.receive_damage(3,0)
+ need_mob_update += arm.receive_damage(brute = 1.2 * seconds_between_ticks, burn = 0, updating_health = FALSE)
if (30 to 49) //38% chance
var/obj/item/bodypart/leg = victim.get_bodypart(pick(BODY_ZONE_L_LEG,BODY_ZONE_R_LEG))
to_chat(victim, span_danger("You scratch at the ants on your leg!"))
- leg.receive_damage(3,0)
+ need_mob_update += leg.receive_damage(brute = 1.2 * seconds_between_ticks, burn = 0, updating_health = FALSE)
if(50) // 2% chance
to_chat(victim, span_danger("You rub some ants away from your eyes!"))
victim.set_eye_blur_if_lower(6 SECONDS)
ants_remaining -= 5 // To balance out the blindness, it'll be a little shorter.
ants_remaining--
+ if(need_mob_update)
+ victim.updatehealth()
if(ants_remaining <= 0 || victim.stat >= HARD_CRIT)
victim.remove_status_effect(/datum/status_effect/ants) //If this person has no more ants on them or are dead, they are no longer affected.
@@ -961,5 +970,71 @@
/datum/movespeed_modifier/careful_driving
multiplicative_slowdown = 3
+/datum/status_effect/midas_blight
+ id = "midas_blight"
+ alert_type = /atom/movable/screen/alert/status_effect/midas_blight
+ status_type = STATUS_EFFECT_REPLACE
+ tick_interval = 0.2 SECONDS
+ remove_on_fullheal = TRUE
+
+ /// The visual overlay state, helps tell both you and enemies how much gold is in your system
+ var/midas_state = "midas_1"
+ /// How fast the gold in a person's system scales.
+ var/goldscale = 30 // x2.8 - Gives ~ 15u for 1 second
+
+/datum/status_effect/midas_blight/on_creation(mob/living/new_owner, duration = 1)
+ // Duration is already input in SECONDS
+ src.duration = duration
+ RegisterSignal(new_owner, COMSIG_ATOM_UPDATE_OVERLAYS, PROC_REF(on_update_overlays))
+ return ..()
+
+/atom/movable/screen/alert/status_effect/midas_blight
+ name = "Midas Blight"
+ desc = "Your blood is being turned to gold, slowing your movements!"
+ icon_state = "midas_blight"
+
+/datum/status_effect/midas_blight/tick(seconds_between_ticks)
+ var/mob/living/carbon/human/victim = owner
+ // We're transmuting blood, time to lose some.
+ if(victim.blood_volume > BLOOD_VOLUME_SURVIVE + 50 && !HAS_TRAIT(victim, TRAIT_NOBLOOD))
+ victim.blood_volume -= 5 * seconds_between_ticks
+ // This has been hell to try and balance so that you'll actually get anything out of it
+ victim.reagents.add_reagent(/datum/reagent/gold/cursed, amount = seconds_between_ticks * goldscale, no_react = TRUE)
+ var/current_gold_amount = victim.reagents.get_reagent_amount(/datum/reagent/gold, include_subtypes = TRUE)
+ switch(current_gold_amount)
+ if(-INFINITY to 50)
+ victim.add_movespeed_modifier(/datum/movespeed_modifier/status_effect/midas_blight/soft, update = TRUE)
+ victim.add_actionspeed_modifier(/datum/actionspeed_modifier/status_effect/midas_blight/soft, update = TRUE)
+ midas_state = "midas_1"
+ if(50 to 100)
+ victim.add_movespeed_modifier(/datum/movespeed_modifier/status_effect/midas_blight/medium, update = TRUE)
+ victim.add_actionspeed_modifier(/datum/actionspeed_modifier/status_effect/midas_blight/medium, update = TRUE)
+ midas_state = "midas_2"
+ if(100 to 200)
+ victim.add_movespeed_modifier(/datum/movespeed_modifier/status_effect/midas_blight/hard, update = TRUE)
+ victim.add_actionspeed_modifier(/datum/actionspeed_modifier/status_effect/midas_blight/hard, update = TRUE)
+ midas_state = "midas_3"
+ if(200 to INFINITY)
+ victim.add_movespeed_modifier(/datum/movespeed_modifier/status_effect/midas_blight/gold, update = TRUE)
+ victim.add_actionspeed_modifier(/datum/actionspeed_modifier/status_effect/midas_blight/gold, update = TRUE)
+ midas_state = "midas_4"
+ victim.update_icon()
+ if(victim.stat == DEAD)
+ qdel(src) // Dead people stop being turned to gold. Don't want people sitting on dead bodies.
+
+/datum/status_effect/midas_blight/proc/on_update_overlays(atom/parent_atom, list/overlays)
+ SIGNAL_HANDLER
+
+ if(midas_state)
+ var/mutable_appearance/midas_overlay = mutable_appearance('icons/mob/effects/debuff_overlays.dmi', midas_state)
+ midas_overlay.blend_mode = BLEND_MULTIPLY
+ overlays += midas_overlay
+
+/datum/status_effect/midas_blight/on_remove()
+ owner.remove_movespeed_modifier(MOVESPEED_ID_MIDAS_BLIGHT, update = TRUE)
+ owner.remove_actionspeed_modifier(ACTIONSPEED_ID_MIDAS_BLIGHT, update = TRUE)
+ UnregisterSignal(owner, COMSIG_ATOM_UPDATE_OVERLAYS)
+ owner.update_icon()
+
#undef HEALING_SLEEP_DEFAULT
#undef HEALING_SLEEP_ORGAN_MULTIPLIER
diff --git a/code/datums/status_effects/debuffs/drunk.dm b/code/datums/status_effects/debuffs/drunk.dm
index 705fcc60eeb..cdac6b59225 100644
--- a/code/datums/status_effects/debuffs/drunk.dm
+++ b/code/datums/status_effects/debuffs/drunk.dm
@@ -213,19 +213,28 @@
if(drunk_value >= 91)
owner.adjustToxLoss(1)
owner.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.4)
- if(owner.stat == CONSCIOUS && prob(20))
- // Don't put us in a deep sleep if the shuttle's here. QoL, mainly.
- if(SSshuttle.emergency.mode == SHUTTLE_DOCKED && is_station_level(owner.z))
- to_chat(owner, span_warning("You're so tired... but you can't miss that shuttle..."))
-
- else
- to_chat(owner, span_warning("Just a quick nap..."))
- owner.Sleeping(90 SECONDS)
+ if(owner.stat == CONSCIOUS)
+ attempt_to_blackout()
// And finally, over 100 - let's be honest, you shouldn't be alive by now.
if(drunk_value >= 101)
owner.adjustToxLoss(2)
+/datum/status_effect/inebriated/drunk/proc/attempt_to_blackout()
+ /* SKYRAT EDIT REMOVAL - Blackout drunk begone
+ var/mob/living/carbon/drunkard = owner
+ if(drunkard.gain_trauma(/datum/brain_trauma/severe/split_personality/blackout, TRAUMA_LIMIT_ABSOLUTE))
+ drunk_value -= 50 //So that the drunk personality can spice things up without being killed by liver failure
+ return
+ else if(drunkard.has_trauma_type(/datum/brain_trauma/severe/split_personality/blackout) && prob(10))
+ to_chat(owner, span_warning("You stumbled and fall over!"))
+ owner.slip(1 SECONDS)
+ */ // SKYRAT EDIT REMOVAL END (also removed the else on the line after)
+ if(SSshuttle.emergency.mode == SHUTTLE_DOCKED && is_station_level(owner.z))// Don't put us in a deep sleep if the shuttle's here. QoL, mainly.
+ to_chat(owner, span_warning("You're so tired... but you can't miss that shuttle..."))
+ else
+ owner.Sleeping(90 SECONDS)
+
/// Status effect for being fully drunk (not tipsy).
/atom/movable/screen/alert/status_effect/drunk
name = "Drunk"
diff --git a/code/datums/status_effects/neutral.dm b/code/datums/status_effects/neutral.dm
index 7161946c9ff..a2aa81ebb69 100644
--- a/code/datums/status_effects/neutral.dm
+++ b/code/datums/status_effects/neutral.dm
@@ -109,11 +109,14 @@
for(var/datum/action/cooldown/spell/spell in rewarded.actions)
spell.reset_spell_cooldown()
- rewarded.adjustBruteLoss(-25)
- rewarded.adjustFireLoss(-25)
- rewarded.adjustToxLoss(-25)
- rewarded.adjustOxyLoss(-25)
- rewarded.adjustCloneLoss(-25)
+ var/need_mob_update = FALSE
+ need_mob_update += rewarded.adjustBruteLoss(-25, updating_health = FALSE)
+ need_mob_update += rewarded.adjustFireLoss(-25, updating_health = FALSE)
+ need_mob_update += rewarded.adjustToxLoss(-25, updating_health = FALSE)
+ need_mob_update += rewarded.adjustOxyLoss(-25, updating_health = FALSE)
+ need_mob_update += rewarded.adjustCloneLoss(-25, updating_health = FALSE)
+ if(need_mob_update)
+ rewarded.updatehealth()
// heldup is for the person being aimed at
/datum/status_effect/grouped/heldup
diff --git a/code/datums/weather/weather_types/void_storm.dm b/code/datums/weather/weather_types/void_storm.dm
index becfa9859a8..4d3638c5827 100644
--- a/code/datums/weather/weather_types/void_storm.dm
+++ b/code/datums/weather/weather_types/void_storm.dm
@@ -33,8 +33,11 @@
return FALSE
/datum/weather/void_storm/weather_act(mob/living/victim)
- victim.adjustFireLoss(1)
- victim.adjustOxyLoss(rand(1, 3))
+ var/need_mob_update = FALSE
+ victim.adjustFireLoss(1, updating_health = FALSE)
+ victim.adjustOxyLoss(rand(1, 3), updating_health = FALSE)
+ if(need_mob_update)
+ victim.updatehealth()
victim.adjust_eye_blur(rand(0 SECONDS, 2 SECONDS))
victim.adjust_bodytemperature(-30 * TEMPERATURE_DAMAGE_COEFFICIENT)
diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm
index 6208df36de1..ce64f200458 100644
--- a/code/game/gamemodes/dynamic/dynamic.dm
+++ b/code/game/gamemodes/dynamic/dynamic.dm
@@ -17,6 +17,8 @@ GLOBAL_LIST_EMPTY(dynamic_forced_roundstart_ruleset)
GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
/// Modify the threat level for station traits before dynamic can be Initialized. List(instance = threat_reduction)
GLOBAL_LIST_EMPTY(dynamic_station_traits)
+/// Rulesets which have been forcibly enabled or disabled
+GLOBAL_LIST_EMPTY(dynamic_forced_rulesets)
/datum/game_mode/dynamic
// Threat logging vars
diff --git a/code/game/gamemodes/dynamic/dynamic_midround_rolling.dm b/code/game/gamemodes/dynamic/dynamic_midround_rolling.dm
index 5079035834b..c3e295ae875 100644
--- a/code/game/gamemodes/dynamic/dynamic_midround_rolling.dm
+++ b/code/game/gamemodes/dynamic/dynamic_midround_rolling.dm
@@ -45,7 +45,11 @@
continue
if (!ruleset.acceptable(GLOB.alive_player_list.len, threat_level))
- log_dynamic("FAIL: [ruleset] is not acceptable with the current parameters. Alive players: [GLOB.alive_player_list.len], threat level: [threat_level]")
+ var/ruleset_forced = GLOB.dynamic_forced_rulesets[type] || RULESET_NOT_FORCED
+ if (ruleset_forced == RULESET_NOT_FORCED)
+ log_dynamic("FAIL: [ruleset] is not acceptable with the current parameters. Alive players: [GLOB.alive_player_list.len], threat level: [threat_level]")
+ else
+ log_dynamic("FAIL: [ruleset] was disabled.")
continue
if (mid_round_budget < ruleset.cost)
diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets.dm b/code/game/gamemodes/dynamic/dynamic_rulesets.dm
index 1fe34273fb9..0af18e0b0aa 100644
--- a/code/game/gamemodes/dynamic/dynamic_rulesets.dm
+++ b/code/game/gamemodes/dynamic/dynamic_rulesets.dm
@@ -106,23 +106,39 @@
/// By default, a rule is acceptable if it satisfies the threat level/population requirements.
/// If your rule has extra checks, such as counting security officers, do that in ready() instead
/datum/dynamic_ruleset/proc/acceptable(population = 0, threat_level = 0)
- pop_per_requirement = pop_per_requirement > 0 ? pop_per_requirement : mode.pop_per_requirement
- indice_pop = min(requirements.len,round(population/pop_per_requirement)+1)
-
- if(minimum_players > population)
- log_dynamic("FAIL: [src] failed acceptable: minimum_players ([minimum_players]) > population ([population])")
+ var/ruleset_forced = GLOB.dynamic_forced_rulesets[type] || RULESET_NOT_FORCED
+ if (ruleset_forced != RULESET_NOT_FORCED)
+ if (ruleset_forced == RULESET_FORCE_ENABLED)
+ return TRUE
+ else
+ log_dynamic("FAIL: [src] was disabled in admin panel.")
+ return FALSE
+
+ if(!is_valid_population(population))
+ var/range = maximum_players > 0 ? "([minimum_players] - [maximum_players])" : "(minimum: [minimum_players])"
+ log_dynamic("FAIL: [src] failed acceptable: min/max players out of range [range] vs population ([population])")
return FALSE
- if(maximum_players > 0 && population > maximum_players)
- log_dynamic("FAIL: [src] failed acceptable: maximum_players ([maximum_players]) < population ([population])")
- return FALSE
-
- if (threat_level < requirements[indice_pop])
+ if (!is_valid_threat(population, threat_level))
log_dynamic("FAIL: [src] failed acceptable: threat_level ([threat_level]) < requirement ([requirements[indice_pop]])")
return FALSE
return TRUE
+/// Returns true if we have enough players to run
+/datum/dynamic_ruleset/proc/is_valid_population(population)
+ if(minimum_players > population)
+ return FALSE
+ if(maximum_players > 0 && population > maximum_players)
+ return FALSE
+ return TRUE
+
+/// Sets the current threat indices and returns true if we're inside of them
+/datum/dynamic_ruleset/proc/is_valid_threat(population, threat_level)
+ pop_per_requirement = pop_per_requirement > 0 ? pop_per_requirement : mode.pop_per_requirement
+ indice_pop = min(requirements.len,round(population/pop_per_requirement)+1)
+ return threat_level >= requirements[indice_pop]
+
/// When picking rulesets, if dynamic picks the same one multiple times, it will "scale up".
/// However, doing this blindly would result in lowpop rounds (think under 10 people) where over 80% of the crew is antags!
/// This function is here to ensure the antag ratio is kept under control while scaling up.
@@ -175,7 +191,7 @@
candidates = list()
assigned = list()
antag_datum = null
-
+
/// Here you can perform any additional checks you want. (such as checking the map etc)
/// Remember that on roundstart no one knows what their job is at this point.
/// IMPORTANT: If ready() returns TRUE, that means pre_execute() or execute() should never fail!
diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm
index 3610d8aad91..7b125439d53 100644
--- a/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm
+++ b/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm
@@ -38,8 +38,8 @@
job_check++ // Checking for "enemies" (such as sec officers). To be counters, they must either not be candidates to that rule, or have a job that restricts them from it
var/threat = round(mode.threat_level/10)
-
- if (job_check < required_enemies[threat])
+ var/ruleset_forced = (GLOB.dynamic_forced_rulesets[type] || RULESET_NOT_FORCED) == RULESET_FORCE_ENABLED
+ if (!ruleset_forced && job_check < required_enemies[threat])
log_dynamic("FAIL: [src] is not ready, because there are not enough enemies: [required_enemies[threat]] needed, [job_check] found")
return FALSE
diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm
index 0634c44a4f2..b7c66873aee 100644
--- a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm
+++ b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm
@@ -116,8 +116,8 @@
job_check++ // Checking for "enemies" (such as sec officers). To be counters, they must either not be candidates to that rule, or have a job that restricts them from it
var/threat = round(mode.threat_level/10)
-
- if (job_check < required_enemies[threat])
+ var/ruleset_forced = (GLOB.dynamic_forced_rulesets[type] || RULESET_NOT_FORCED) == RULESET_FORCE_ENABLED
+ if (!ruleset_forced && job_check < required_enemies[threat])
log_dynamic("FAIL: [src] is not ready, because there are not enough enemies: [required_enemies[threat]] needed, [job_check] found")
return FALSE
@@ -387,7 +387,7 @@
var/list/operative_cap = list(2,2,3,3,4,5,5,5,5,5)
-/datum/dynamic_ruleset/midround/from_ghosts/nuclear/acceptable(population=0, threat=0)
+/datum/dynamic_ruleset/midround/from_ghosts/nuclear/acceptable(population=0, threat_level=0)
if (locate(/datum/dynamic_ruleset/roundstart/nuclear) in mode.executed_rules)
return FALSE // Unavailable if nuke ops were already sent at roundstart
indice_pop = min(operative_cap.len, round(living_players.len/5)+1)
@@ -542,7 +542,7 @@
minimum_players = 15
repeatable = TRUE
-/datum/dynamic_ruleset/midround/from_ghosts/nightmare/acceptable(population = 0, threat = 0)
+/datum/dynamic_ruleset/midround/from_ghosts/nightmare/acceptable(population = 0, threat_level = 0)
var/turf/spawn_loc = find_maintenance_spawn(atmos_sensitive = TRUE, require_darkness = TRUE) //Checks if there's a single safe, dark tile on station.
if(!spawn_loc)
return FALSE
@@ -719,7 +719,7 @@
spawn_locs = list()
return ..()
-/datum/dynamic_ruleset/midround/from_ghosts/revenant/acceptable(population=0, threat=0)
+/datum/dynamic_ruleset/midround/from_ghosts/revenant/acceptable(population=0, threat_level=0)
if(GLOB.dead_mob_list.len < dead_mobs_required)
return FALSE
return ..()
@@ -782,7 +782,7 @@
minimum_players = 20
repeatable = TRUE
-/datum/dynamic_ruleset/midround/pirates/acceptable(population=0, threat=0)
+/datum/dynamic_ruleset/midround/pirates/acceptable(population=0, threat_level=0)
if (SSmapping.is_planetary() || GLOB.light_pirate_gangs.len == 0)
return FALSE
return ..()
@@ -804,7 +804,7 @@
minimum_players = 25
repeatable = TRUE
-/datum/dynamic_ruleset/midround/dangerous_pirates/acceptable(population=0, threat=0)
+/datum/dynamic_ruleset/midround/dangerous_pirates/acceptable(population=0, threat_level=0)
if (SSmapping.is_planetary() || GLOB.heavy_pirate_gangs.len == 0)
return FALSE
return ..()
diff --git a/code/game/machinery/computer/aifixer.dm b/code/game/machinery/computer/aifixer.dm
index 87e53ebb368..2bc13e156d4 100644
--- a/code/game/machinery/computer/aifixer.dm
+++ b/code/game/machinery/computer/aifixer.dm
@@ -65,10 +65,12 @@
/obj/machinery/computer/aifixer/proc/Fix()
use_power(1000)
- occupier.adjustOxyLoss(-5, FALSE)
- occupier.adjustFireLoss(-5, FALSE)
- occupier.adjustBruteLoss(-5, FALSE)
- occupier.updatehealth()
+ var/need_mob_update = FALSE
+ need_mob_update += occupier.adjustOxyLoss(-5, updating_health = FALSE)
+ need_mob_update += occupier.adjustFireLoss(-5, updating_health = FALSE)
+ need_mob_update += occupier.adjustBruteLoss(-5, updating_health = FALSE)
+ if(need_mob_update)
+ occupier.updatehealth()
if(occupier.health >= 0 && occupier.stat == DEAD)
occupier.revive()
if(!occupier.radio_enabled)
diff --git a/code/game/objects/effects/temporary_visuals/miscellaneous.dm b/code/game/objects/effects/temporary_visuals/miscellaneous.dm
index e88753d25c1..c736aac35d8 100644
--- a/code/game/objects/effects/temporary_visuals/miscellaneous.dm
+++ b/code/game/objects/effects/temporary_visuals/miscellaneous.dm
@@ -594,11 +594,22 @@
var/datum/weakref/pinged_person
/// The icon state applied to the image created for this ping.
var/real_icon_state = "sonar_ping"
+ /// Does the visual follow the creature?
+ var/follow_creature = TRUE
+ /// Creature's X & Y coords, which can either be overridden or kept the same depending on follow_creature.
+ var/creature_x
+ var/creature_y
-/obj/effect/temp_visual/sonar_ping/Initialize(mapload, mob/living/looker, mob/living/creature)
+/obj/effect/temp_visual/sonar_ping/Initialize(mapload, mob/living/looker, mob/living/creature, ping_state, follow_creatures = TRUE)
. = ..()
if(!looker || !creature)
return INITIALIZE_HINT_QDEL
+ if(ping_state)
+ real_icon_state = ping_state
+ follow_creature = follow_creatures
+ creature_x = creature.x
+ creature_y = creature.y
+
modsuit_image = image(icon = icon, loc = looker.loc, icon_state = real_icon_state, layer = ABOVE_ALL_MOB_LAYER, pixel_x = ((creature.x - looker.x) * 32), pixel_y = ((creature.y - looker.y) * 32))
modsuit_image.plane = ABOVE_LIGHTING_PLANE
SET_PLANE_EXPLICIT(modsuit_image, ABOVE_LIGHTING_PLANE, creature)
@@ -631,8 +642,12 @@
if(isnull(looker) || isnull(creature))
return PROCESS_KILL
modsuit_image.loc = looker.loc
- modsuit_image.pixel_x = ((creature.x - looker.x) * 32)
- modsuit_image.pixel_y = ((creature.y - looker.y) * 32)
+ // Long pings follow, short pings stay put. We still need to update for looker.x&y though
+ if(follow_creature)
+ creature_y = creature.y
+ creature_x = creature.x
+ modsuit_image.pixel_x = ((creature_x - looker.x) * 32)
+ modsuit_image.pixel_y = ((creature_y - looker.y) * 32)
/obj/effect/temp_visual/block //color is white by default, set to whatever is needed
name = "blocking glow"
diff --git a/code/game/objects/items/defib.dm b/code/game/objects/items/defib.dm
index 279f8101007..f86850fbf6f 100644
--- a/code/game/objects/items/defib.dm
+++ b/code/game/objects/items/defib.dm
@@ -636,17 +636,19 @@
var/total_brute = H.getBruteLoss()
var/total_burn = H.getFireLoss()
+ var/need_mob_update = FALSE
//If the body has been fixed so that they would not be in crit when defibbed, give them oxyloss to put them back into crit
if (H.health > HALFWAYCRITDEATH)
- H.adjustOxyLoss(H.health - HALFWAYCRITDEATH, 0)
+ need_mob_update += H.adjustOxyLoss(H.health - HALFWAYCRITDEATH, updating_health = FALSE)
else
var/overall_damage = total_brute + total_burn + H.getToxLoss() + H.getOxyLoss()
var/mobhealth = H.health
- H.adjustOxyLoss((mobhealth - HALFWAYCRITDEATH) * (H.getOxyLoss() / overall_damage), 0)
- H.adjustToxLoss((mobhealth - HALFWAYCRITDEATH) * (H.getToxLoss() / overall_damage), 0, TRUE) // force tox heal for toxin lovers too
- H.adjustFireLoss((mobhealth - HALFWAYCRITDEATH) * (total_burn / overall_damage), 0)
- H.adjustBruteLoss((mobhealth - HALFWAYCRITDEATH) * (total_brute / overall_damage), 0)
- H.updatehealth() // Previous "adjust" procs don't update health, so we do it manually.
+ need_mob_update += H.adjustOxyLoss((mobhealth - HALFWAYCRITDEATH) * (H.getOxyLoss() / overall_damage), updating_health = FALSE)
+ need_mob_update += H.adjustToxLoss((mobhealth - HALFWAYCRITDEATH) * (H.getToxLoss() / overall_damage), updating_health = FALSE, forced = TRUE) // force tox heal for toxin lovers too
+ need_mob_update += H.adjustFireLoss((mobhealth - HALFWAYCRITDEATH) * (total_burn / overall_damage), updating_health = FALSE)
+ need_mob_update += H.adjustBruteLoss((mobhealth - HALFWAYCRITDEATH) * (total_brute / overall_damage), updating_health = FALSE)
+ if(need_mob_update)
+ H.updatehealth() // Previous "adjust" procs don't update health, so we do it manually.
user.visible_message(span_notice("[req_defib ? "[defib]" : "[src]"] pings: Resuscitation successful."))
playsound(src, 'sound/machines/defib_success.ogg', 50, FALSE)
H.set_heartattack(FALSE)
diff --git a/code/game/objects/items/religion.dm b/code/game/objects/items/religion.dm
index f58d3ad93cf..e68a1b8c883 100644
--- a/code/game/objects/items/religion.dm
+++ b/code/game/objects/items/religion.dm
@@ -64,15 +64,18 @@
/obj/item/banner/proc/check_inspiration(mob/living/carbon/human/H) //Banner-specific conditions for being eligible
return
-/obj/item/banner/proc/inspiration(mob/living/carbon/human/H)
- H.adjustBruteLoss(-15)
- H.adjustFireLoss(-15)
- H.AdjustStun(-40)
- H.AdjustKnockdown(-40)
- H.AdjustImmobilized(-40)
- H.AdjustParalyzed(-40)
- H.AdjustUnconscious(-40)
- playsound(H, 'sound/magic/staff_healing.ogg', 25, FALSE)
+/obj/item/banner/proc/inspiration(mob/living/carbon/human/inspired_human)
+ var/need_mob_update = FALSE
+ need_mob_update += inspired_human.adjustBruteLoss(-15, updating_health = FALSE)
+ need_mob_update += inspired_human.adjustFireLoss(-15, updating_health = FALSE)
+ if(need_mob_update)
+ inspired_human.updatehealth()
+ inspired_human.AdjustStun(-40)
+ inspired_human.AdjustKnockdown(-40)
+ inspired_human.AdjustImmobilized(-40)
+ inspired_human.AdjustParalyzed(-40)
+ inspired_human.AdjustUnconscious(-40)
+ playsound(inspired_human, 'sound/magic/staff_healing.ogg', 25, FALSE)
/obj/item/banner/proc/special_inspiration(mob/living/carbon/human/H) //Any banner-specific inspiration effects go here
return
@@ -128,10 +131,13 @@
/obj/item/clothing/under/rank/medical/doctor = 1)
category = CAT_MISC
-/obj/item/banner/medical/special_inspiration(mob/living/carbon/human/H)
- H.adjustToxLoss(-15)
- H.setOxyLoss(0)
- H.reagents.add_reagent(/datum/reagent/medicine/inaprovaline, 5)
+/obj/item/banner/medical/special_inspiration(mob/living/carbon/human/inspired_human)
+ var/need_mob_update = FALSE
+ need_mob_update += inspired_human.adjustToxLoss(-15, updating_health = FALSE)
+ need_mob_update += inspired_human.setOxyLoss(0, updating_health = FALSE)
+ if(need_mob_update)
+ inspired_human.updatehealth()
+ inspired_human.reagents.add_reagent(/datum/reagent/medicine/inaprovaline, 5)
/obj/item/banner/science
name = "sciencia banner"
diff --git a/code/game/objects/items/robot/items/storage.dm b/code/game/objects/items/robot/items/storage.dm
index 6570e159b6a..4995c7d9df6 100644
--- a/code/game/objects/items/robot/items/storage.dm
+++ b/code/game/objects/items/robot/items/storage.dm
@@ -57,18 +57,20 @@
/obj/item/borg/apparatus/pre_attack(atom/atom, mob/living/user, params)
if(!stored)
- var/itemcheck = FALSE
- for(var/storable_type in storable)
- if(istype(atom, storable_type))
- itemcheck = TRUE
- break
- if(itemcheck)
- var/obj/item/item = atom
- item.forceMove(src)
- stored = item
- RegisterSignal(stored, COMSIG_ATOM_UPDATED_ICON, PROC_REF(on_stored_updated_icon))
- update_appearance()
- return TRUE
+ // Borgs should not be grabbing their own modules
+ if(!istype(atom.loc, /mob/living/silicon/robot))
+ var/itemcheck = FALSE
+ for(var/storable_type in storable)
+ if(istype(atom, storable_type))
+ itemcheck = TRUE
+ break
+ if(itemcheck)
+ var/obj/item/item = atom
+ item.forceMove(src)
+ stored = item
+ RegisterSignal(stored, COMSIG_ATOM_UPDATED_ICON, PROC_REF(on_stored_updated_icon))
+ update_appearance()
+ return TRUE
else
stored.melee_attack_chain(user, atom, params)
return TRUE
diff --git a/code/game/objects/items/storage/belt.dm b/code/game/objects/items/storage/belt.dm
index a67d85979f1..dc5f052c13b 100644
--- a/code/game/objects/items/storage/belt.dm
+++ b/code/game/objects/items/storage/belt.dm
@@ -235,7 +235,7 @@
/obj/item/healthanalyzer,
/obj/item/hemostat,
/obj/item/holosign_creator/medical,
- /obj/item/hypospray/mkii, //SKYRAT EDIT HYPOSPRAYS
+ /obj/item/hypospray/mkii, //SKYRAT EDIT ADDITION - HYPOSPRAYS
/obj/item/implant,
/obj/item/implantcase,
/obj/item/implanter,
@@ -248,7 +248,7 @@
/obj/item/reagent_containers/dropper,
/obj/item/reagent_containers/cup/beaker,
/obj/item/reagent_containers/cup/bottle,
- /obj/item/reagent_containers/cup/vial, //SKYRAT EDIT HYPOSPRAYS
+ /obj/item/reagent_containers/cup/vial, //SKYRAT EDIT ADDITION - HYPOSPRAYS
/obj/item/reagent_containers/cup/tube,
/obj/item/reagent_containers/hypospray,
/obj/item/reagent_containers/medigel,
diff --git a/code/game/objects/items/tongs.dm b/code/game/objects/items/tongs.dm
new file mode 100644
index 00000000000..8e7753bf488
--- /dev/null
+++ b/code/game/objects/items/tongs.dm
@@ -0,0 +1,100 @@
+/// Tongs, let you pick up and feed people food from further away.
+/obj/item/kitchen/tongs
+ name = "tongs"
+ desc = "So you never have to touch anything with your dirty, unwashed hands."
+ reach = 2
+ icon_state = "tongs"
+ base_icon_state = "tongs"
+ inhand_icon_state = "fork" // close enough
+ attack_verb_continuous = list("pinches", "tongs", "nips")
+ attack_verb_simple = list("pinch", "tong", "nip")
+ /// What are we holding in our tongs?
+ var/obj/item/tonged
+ /// Sound to play when we click our tongs together
+ var/clack_sound = 'sound/items/handling/component_drop.ogg'
+ /// Time to wait between clacking sounds
+ var/clack_delay = 2 SECONDS
+ /// Have we clacked recently?
+ COOLDOWN_DECLARE(clack_cooldown)
+
+/obj/item/kitchen/tongs/Destroy(force)
+ QDEL_NULL(tonged)
+ return ..()
+
+/obj/item/kitchen/tongs/examine(mob/user)
+ . = ..()
+ if (!isnull(tonged))
+ . += span_notice("It is holding [tonged].")
+
+/obj/item/kitchen/tongs/dropped(mob/user, silent)
+ . = ..()
+ drop_tonged()
+
+/obj/item/kitchen/tongs/attack_self(mob/user, modifiers)
+ . = ..()
+ if(.)
+ return TRUE
+ if (!isnull(tonged))
+ drop_tonged()
+ return TRUE
+ if (!COOLDOWN_FINISHED(src, clack_cooldown))
+ return TRUE
+ user.visible_message(span_notice("[user] clacks [user.p_their()] [src] together like a crab. Click clack!"))
+ click_clack()
+ return TRUE
+
+/// Release the food we are holding
+/obj/item/kitchen/tongs/proc/drop_tonged()
+ if (isnull(tonged))
+ return
+ visible_message(span_notice("[tonged] falls to the ground!"))
+ var/turf/location = drop_location()
+ tonged.forceMove(location)
+ tonged.do_drop_animation(location)
+
+/// Play a clacking sound and appear closed, then open again
+/obj/item/kitchen/tongs/proc/click_clack()
+ COOLDOWN_START(src, clack_cooldown, clack_delay)
+ playsound(src, clack_sound, vol = 100, vary = FALSE)
+ icon_state = "[base_icon_state]_closed"
+ var/delay = min(0.5 SECONDS, clack_delay / 2) // Just in case someone's been fucking with the cooldown
+ addtimer(CALLBACK(src, PROC_REF(clack)), delay, TIMER_DELETE_ME)
+
+/// Plays a clacking sound and appear open
+/obj/item/kitchen/tongs/proc/clack()
+ playsound(src, clack_sound, vol = 100, vary = FALSE)
+ icon_state = base_icon_state
+
+/obj/item/kitchen/tongs/Exited(atom/movable/leaving, direction)
+ . = ..()
+ if (leaving != tonged)
+ return
+ tonged = null
+ update_appearance(UPDATE_ICON)
+
+/obj/item/kitchen/tongs/pre_attack(obj/item/attacked, mob/living/user, params)
+ if (!isnull(tonged))
+ attacked.attackby(tonged, user)
+ return TRUE
+ if (isliving(attacked))
+ if (COOLDOWN_FINISHED(src, clack_cooldown))
+ click_clack()
+ return ..()
+ if (!IsEdible(attacked) || attacked.w_class > WEIGHT_CLASS_NORMAL || !isnull(tonged))
+ return ..()
+ tonged = attacked
+ attacked.do_pickup_animation(src)
+ attacked.forceMove(src)
+ update_appearance(UPDATE_ICON)
+
+/obj/item/kitchen/tongs/update_overlays()
+ . = ..()
+ if (isnull(tonged))
+ return
+ var/mutable_appearance/held_food = new /mutable_appearance(tonged.appearance)
+ held_food.layer = layer
+ held_food.plane = plane
+ held_food.transform = held_food.transform.Scale(0.7, 0.7)
+ held_food.pixel_x = 6
+ held_food.pixel_y = 6
+ . += held_food
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm
index 9700a3e80fa..ec46756140c 100755
--- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm
@@ -17,7 +17,7 @@
new /obj/item/radio/headset/heads/captain/alt(src)
new /obj/item/radio/headset/heads/captain(src)
new /obj/item/storage/belt/sabre(src)
- new /obj/item/storage/box/gunset/pdh(src) // SKYRAT EDIT CHANGE - ORIGINAL: new /obj/item/gun/energy/e_gun(src)
+ new /obj/item/gun/energy/e_gun(src)
new /obj/item/door_remote/captain(src)
new /obj/item/storage/photo_album/captain(src)
@@ -25,7 +25,6 @@
name = "head of personnel's locker"
icon_state = "hop"
req_access = list(ACCESS_HOP)
- storage_capacity = 40 //SKYRAT EDIT ADDITION
/obj/structure/closet/secure_closet/hop/PopulateContents()
..()
diff --git a/code/game/objects/structures/petrified_statue.dm b/code/game/objects/structures/petrified_statue.dm
index 78bd478d523..54896c2e414 100644
--- a/code/game/objects/structures/petrified_statue.dm
+++ b/code/game/objects/structures/petrified_statue.dm
@@ -94,7 +94,7 @@
/mob/proc/petrify(statue_timer)
-/mob/living/carbon/human/petrify(statue_timer, save_brain)
+/mob/living/carbon/human/petrify(statue_timer, save_brain, colorlist)
if(!isturf(loc))
return FALSE
var/obj/structure/statue/petrified/S = new(loc, src, statue_timer, save_brain)
@@ -102,6 +102,8 @@
ADD_TRAIT(src, TRAIT_NOBLOOD, MAGIC_TRAIT)
S.copy_overlays(src)
var/newcolor = list(rgb(77,77,77), rgb(150,150,150), rgb(28,28,28), rgb(0,0,0))
+ if(colorlist)
+ newcolor = colorlist
S.add_atom_colour(newcolor, FIXED_COLOUR_PRIORITY)
return TRUE
diff --git a/code/game/turfs/change_turf.dm b/code/game/turfs/change_turf.dm
index f5b40238ed6..1253d156a2c 100644
--- a/code/game/turfs/change_turf.dm
+++ b/code/game/turfs/change_turf.dm
@@ -252,7 +252,7 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list(
//SKYRAT EDIT END
if(excited || excited_group)
SSair.remove_from_active(src) //Clean up wall excitement, and refresh excited groups
- if(ispath(path,/turf/closed) || ispath(path,/turf/cordon))
+ if(ispath(path, /turf/closed) || ispath(path, /turf/cordon))
flags |= CHANGETURF_RECALC_ADJACENT
return ..()
diff --git a/code/game/turfs/open/lava.dm b/code/game/turfs/open/lava.dm
index 24c690498a6..b8e04949662 100644
--- a/code/game/turfs/open/lava.dm
+++ b/code/game/turfs/open/lava.dm
@@ -392,8 +392,11 @@
if(IS_ROBOTIC_LIMB(burn_limb))
robo_parts += burn_limb
- burn_human.adjustToxLoss(15, required_biotype = MOB_ORGANIC) // This is from plasma, so it should obey plasma biotype requirements
- burn_human.adjustFireLoss(25)
+ var/need_mob_update
+ need_mob_update += burn_human.adjustToxLoss(15, updating_health = FALSE, required_biotype = MOB_ORGANIC) // This is from plasma, so it should obey plasma biotype requirements
+ need_mob_update += burn_human.adjustFireLoss(25, updating_health = FALSE)
+ if(need_mob_update)
+ burn_human.updatehealth()
if(plasma_parts.len)
var/obj/item/bodypart/burn_limb = pick(plasma_parts) //using the above-mentioned list to get a choice of limbs
burn_human.emote("scream")
diff --git a/code/modules/actionspeed/modifiers/status_effects.dm b/code/modules/actionspeed/modifiers/status_effects.dm
index fa080edb8d0..ec7b0dba22e 100644
--- a/code/modules/actionspeed/modifiers/status_effects.dm
+++ b/code/modules/actionspeed/modifiers/status_effects.dm
@@ -12,3 +12,19 @@
/datum/actionspeed_modifier/status_effect/hazard_area
multiplicative_slowdown = 4
+
+/// Get slower the more gold is in your system.
+/datum/actionspeed_modifier/status_effect/midas_blight
+ id = ACTIONSPEED_ID_MIDAS_BLIGHT
+
+/datum/actionspeed_modifier/status_effect/midas_blight/soft
+ multiplicative_slowdown = 0.25
+
+/datum/actionspeed_modifier/status_effect/midas_blight/medium
+ multiplicative_slowdown = 0.75
+
+/datum/actionspeed_modifier/status_effect/midas_blight/hard
+ multiplicative_slowdown = 1.5
+
+/datum/actionspeed_modifier/status_effect/midas_blight/gold
+ multiplicative_slowdown = 2
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index bc6942a9a11..2d2c692ed5f 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -21,6 +21,7 @@
var/dat = "
Game Panel
"
if(SSticker.current_state <= GAME_STATE_PREGAME)
+ dat += "(Manage Dynamic Rulesets) "
dat += "(Force Roundstart Rulesets) "
if (GLOB.dynamic_forced_roundstart_ruleset.len > 0)
for(var/datum/dynamic_ruleset/roundstart/rule in GLOB.dynamic_forced_roundstart_ruleset)
@@ -30,6 +31,8 @@
dat += ""
if(SSticker.IsRoundInProgress())
dat += "(Game Mode Panel) "
+ if(istype(SSticker.mode, /datum/game_mode/dynamic))
+ dat += "(Manage Dynamic Rulesets) "
dat += {"
Create Object
@@ -143,6 +146,111 @@
user << browse(dat, "window=dyn_mode_options;size=900x650")
+/datum/admins/proc/dynamic_ruleset_manager(mob/user)
+ if (SSticker.current_state > GAME_STATE_PREGAME && !istype(SSticker.mode, /datum/game_mode/dynamic))
+ return // Not running dynamic
+
+ var/dat = "
Dynamic Ruleset Management
\
+ Change these options to forcibly enable or disable dynamic rulesets. \
+ Disabled rulesets will never run, even if they would otherwise be valid. \
+ Enabled rulesets will run even if the qualifying minimum of threat or player count is not present, this does not guarantee that they will necessarily be chosen (for example their weight may be set to 0 in config). \
+ \[force enable all / \
+ force disable all / \
+ reset all\]"
+
+ if (SSticker.current_state <= GAME_STATE_PREGAME) // Don't bother displaying after the round has started
+ var/static/list/rulesets_by_context = list()
+ if (!length(rulesets_by_context))
+ for (var/datum/dynamic_ruleset/rule as anything in subtypesof(/datum/dynamic_ruleset))
+ if (initial(rule.name) == "")
+ continue
+ LAZYADD(rulesets_by_context[initial(rule.ruletype)], rule)
+
+ dat += dynamic_ruleset_category_pre_start_display("Roundstart", rulesets_by_context[ROUNDSTART_RULESET])
+ dat += dynamic_ruleset_category_pre_start_display("Latejoin", rulesets_by_context[LATEJOIN_RULESET])
+ dat += dynamic_ruleset_category_pre_start_display("Midround", rulesets_by_context[MIDROUND_RULESET])
+ user << browse(dat, "window=dyn_mode_options;size=900x650")
+ return
+
+ var/datum/game_mode/dynamic/current_mode = SSticker.mode
+ var/pop_count = length(GLOB.alive_player_list)
+ var/threat_level = current_mode.threat_level
+ dat += dynamic_ruleset_category_during_round_display("Latejoin", current_mode.latejoin_rules, pop_count, threat_level)
+ dat += dynamic_ruleset_category_during_round_display("Midround", current_mode.midround_rules, pop_count, threat_level)
+ user << browse(dat, "window=dyn_mode_options;size=900x650")
+
+/datum/admins/proc/dynamic_ruleset_category_pre_start_display(title, list/rules)
+ var/dat = "
[title]
"
+ for (var/datum/dynamic_ruleset/rule as anything in rules)
+ var/forced = GLOB.dynamic_forced_rulesets[rule] || RULESET_NOT_FORCED
+ var/color = COLOR_BLACK
+ switch (forced)
+ if (RULESET_FORCE_ENABLED)
+ color = COLOR_GREEN
+ if (RULESET_FORCE_DISABLED)
+ color = COLOR_RED
+ dat += "
"
+ return dat
+
+
+/datum/admins/proc/force_all_rulesets(mob/user, force_value)
+ if (force_value == RULESET_NOT_FORCED)
+ GLOB.dynamic_forced_rulesets = list()
+ else
+ for (var/datum/dynamic_ruleset/rule as anything in subtypesof(/datum/dynamic_ruleset))
+ GLOB.dynamic_forced_rulesets[rule] = force_value
+ var/logged_message = "[key_name(user)] set all dynamic rulesets to [force_value]."
+ log_admin(logged_message)
+ message_admins(logged_message)
+ dynamic_ruleset_manager(user)
+
+/datum/admins/proc/set_dynamic_ruleset_forced(mob/user, datum/dynamic_ruleset/type, force_value)
+ if (isnull(type))
+ return
+ GLOB.dynamic_forced_rulesets[type] = force_value
+ dynamic_ruleset_manager(user)
+ var/logged_message = "[key_name(user)] set '[initial(type.name)] ([initial(type.ruletype)])' to [GLOB.dynamic_forced_rulesets[type]]."
+ log_admin(logged_message)
+ message_admins(logged_message)
+
/datum/admins/proc/create_or_modify_area()
set category = "Debug"
set name = "Create or modify area"
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index 9db6585799f..c4c09b51adf 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -465,6 +465,39 @@
log_admin("[key_name(usr)] removed [rule] from the forced roundstart rulesets.")
message_admins("[key_name(usr)] removed [rule] from the forced roundstart rulesets.", 1)
+ else if (href_list["f_dynamic_ruleset_manage"])
+ if(!check_rights(R_ADMIN))
+ return
+ dynamic_ruleset_manager(usr)
+ else if (href_list["f_dynamic_ruleset_force_all_on"])
+ if(!check_rights(R_ADMIN))
+ return
+ force_all_rulesets(usr, RULESET_FORCE_ENABLED)
+ else if (href_list["f_dynamic_ruleset_force_all_off"])
+ if(!check_rights(R_ADMIN))
+ return
+ force_all_rulesets(usr, RULESET_FORCE_DISABLED)
+ else if (href_list["f_dynamic_ruleset_force_all_reset"])
+ if(!check_rights(R_ADMIN))
+ return
+ force_all_rulesets(usr, RULESET_NOT_FORCED)
+ else if (href_list["f_dynamic_ruleset_force_on"])
+ if(!check_rights(R_ADMIN))
+ return
+ set_dynamic_ruleset_forced(usr, locate(href_list["f_dynamic_ruleset_force_on"]), RULESET_FORCE_ENABLED)
+ else if (href_list["f_dynamic_ruleset_force_off"])
+ if(!check_rights(R_ADMIN))
+ return
+ set_dynamic_ruleset_forced(usr, locate(href_list["f_dynamic_ruleset_force_off"]), RULESET_FORCE_DISABLED)
+ else if (href_list["f_dynamic_ruleset_force_reset"])
+ if(!check_rights(R_ADMIN))
+ return
+ set_dynamic_ruleset_forced(usr, locate(href_list["f_dynamic_ruleset_force_reset"]), RULESET_NOT_FORCED)
+ else if (href_list["f_inspect_ruleset"])
+ if(!check_rights(R_ADMIN))
+ return
+ usr.client.debug_variables(locate(href_list["f_inspect_ruleset"]))
+
else if (href_list["f_dynamic_options"])
if(!check_rights(R_ADMIN))
return
diff --git a/code/modules/admin/view_variables/debug_variables.dm b/code/modules/admin/view_variables/debug_variables.dm
index 230a0e46284..5196d83b124 100644
--- a/code/modules/admin/view_variables/debug_variables.dm
+++ b/code/modules/admin/view_variables/debug_variables.dm
@@ -41,6 +41,10 @@
item = "[name_part] = /icon ([value])"
#endif
+ else if(isappearance(value))
+ var/image/actually_an_appearance = value
+ item = "[name_part] = /appearance ([actually_an_appearance.icon])"
+
else if (isfile(value))
item = "[name_part] = '[value]'"
@@ -55,6 +59,7 @@
[M.c]
[M.f]
1
"} //TODO link to modify_transform wrapper for all matrices
+
else if (isdatum(value))
var/datum/DV = value
if ("[DV]" != "[DV.type]") //if the thing as a name var, lets use it.
diff --git a/code/modules/antagonists/abductor/equipment/glands/chem.dm b/code/modules/antagonists/abductor/equipment/glands/chem.dm
index 47868841c85..965d8f2fc20 100644
--- a/code/modules/antagonists/abductor/equipment/glands/chem.dm
+++ b/code/modules/antagonists/abductor/equipment/glands/chem.dm
@@ -16,5 +16,5 @@
/obj/item/organ/internal/heart/gland/chem/activate()
var/chem_to_add = pick(possible_reagents)
owner.reagents.add_reagent(chem_to_add, 2)
- owner.adjustToxLoss(-5, TRUE, TRUE)
+ owner.adjustToxLoss(-5, forced = TRUE)
..()
diff --git a/code/modules/antagonists/abductor/equipment/glands/heal.dm b/code/modules/antagonists/abductor/equipment/glands/heal.dm
index 2fa677cba0e..683cb33fc9a 100644
--- a/code/modules/antagonists/abductor/equipment/glands/heal.dm
+++ b/code/modules/antagonists/abductor/equipment/glands/heal.dm
@@ -194,7 +194,7 @@
var/keep_going = FALSE
owner.vomit(vomit_flags = (MOB_VOMIT_BLOOD | MOB_VOMIT_FORCE), lost_nutrition = 0, distance = 3)
owner.Stun(15)
- owner.adjustToxLoss(-15, TRUE, TRUE)
+ owner.adjustToxLoss(-15, forced = TRUE)
owner.blood_volume = min(BLOOD_VOLUME_NORMAL, owner.blood_volume + 20)
if(owner.blood_volume < BLOOD_VOLUME_NORMAL)
diff --git a/code/modules/antagonists/blob/blobstrains/cryogenic_poison.dm b/code/modules/antagonists/blob/blobstrains/cryogenic_poison.dm
index a20ddf89805..a18d802ff7d 100644
--- a/code/modules/antagonists/blob/blobstrains/cryogenic_poison.dm
+++ b/code/modules/antagonists/blob/blobstrains/cryogenic_poison.dm
@@ -26,8 +26,10 @@
exposed_mob.apply_damage(0.2*reac_volume, BRUTE, wound_bonus=CANT_WOUND)
/datum/reagent/blob/cryogenic_poison/on_mob_life(mob/living/carbon/exposed_mob, seconds_per_tick, times_fired)
- exposed_mob.adjustBruteLoss(0.5 * REM * seconds_per_tick, FALSE)
- exposed_mob.adjustFireLoss(0.5 * REM * seconds_per_tick, FALSE)
- exposed_mob.adjustToxLoss(0.5 * REM * seconds_per_tick, FALSE)
- . = 1
- ..()
+ . = ..()
+ var/need_mob_update
+ need_mob_update = exposed_mob.adjustBruteLoss(0.5 * REM * seconds_per_tick, updating_health = FALSE)
+ need_mob_update += exposed_mob.adjustFireLoss(0.5 * REM * seconds_per_tick, updating_health = FALSE)
+ need_mob_update += exposed_mob.adjustToxLoss(0.5 * REM * seconds_per_tick, updating_health = FALSE)
+ if(need_mob_update)
+ . = UPDATE_MOB_HEALTH
diff --git a/code/modules/antagonists/blob/blobstrains/regenerative_materia.dm b/code/modules/antagonists/blob/blobstrains/regenerative_materia.dm
index 78b67dae650..0b70cc9c741 100644
--- a/code/modules/antagonists/blob/blobstrains/regenerative_materia.dm
+++ b/code/modules/antagonists/blob/blobstrains/regenerative_materia.dm
@@ -25,9 +25,9 @@
exposed_mob.apply_damage(0.7*reac_volume, TOX)
/datum/reagent/blob/regenerative_materia/on_mob_life(mob/living/carbon/metabolizer, seconds_per_tick, times_fired)
- metabolizer.adjustToxLoss(1 * REM * seconds_per_tick)
- ..()
- return TRUE
+ . = ..()
+ if(metabolizer.adjustToxLoss(1 * REM * seconds_per_tick, updating_health = FALSE))
+ return UPDATE_MOB_HEALTH
/datum/reagent/blob/regenerative_materia/on_mob_metabolize(mob/living/metabolizer)
. = ..()
diff --git a/code/modules/antagonists/cult/blood_magic.dm b/code/modules/antagonists/cult/blood_magic.dm
index dd5e9a9c661..27a87bee6c2 100644
--- a/code/modules/antagonists/cult/blood_magic.dm
+++ b/code/modules/antagonists/cult/blood_magic.dm
@@ -720,11 +720,13 @@
human_bloodbag.visible_message(span_warning("[human_bloodbag] is partially healed by [human_bloodbag == user ? "[human_bloodbag.p_their()]":"[human_bloodbag]'s"] blood magic."))
uses = 0
ratio *= -1
- human_bloodbag.adjustOxyLoss((overall_damage*ratio) * (human_bloodbag.getOxyLoss() / overall_damage), 0)
- human_bloodbag.adjustToxLoss((overall_damage*ratio) * (human_bloodbag.getToxLoss() / overall_damage), 0)
- human_bloodbag.adjustFireLoss((overall_damage*ratio) * (human_bloodbag.getFireLoss() / overall_damage), 0)
- human_bloodbag.adjustBruteLoss((overall_damage*ratio) * (human_bloodbag.getBruteLoss() / overall_damage), 0)
- human_bloodbag.updatehealth()
+ var/need_mob_update = FALSE
+ need_mob_update += human_bloodbag.adjustOxyLoss((overall_damage*ratio) * (human_bloodbag.getOxyLoss() / overall_damage), updating_health = FALSE)
+ need_mob_update += human_bloodbag.adjustToxLoss((overall_damage*ratio) * (human_bloodbag.getToxLoss() / overall_damage), updating_health = FALSE)
+ need_mob_update += human_bloodbag.adjustFireLoss((overall_damage*ratio) * (human_bloodbag.getFireLoss() / overall_damage), updating_health = FALSE)
+ need_mob_update += human_bloodbag.adjustBruteLoss((overall_damage*ratio) * (human_bloodbag.getBruteLoss() / overall_damage), updating_health = FALSE)
+ if(need_mob_update)
+ human_bloodbag.updatehealth()
playsound(get_turf(human_bloodbag), 'sound/magic/staff_healing.ogg', 25)
new /obj/effect/temp_visual/cult/sparks(get_turf(human_bloodbag))
user.Beam(human_bloodbag, icon_state="sendbeam", time = 15)
diff --git a/code/modules/antagonists/heretic/knowledge/cosmic_lore.dm b/code/modules/antagonists/heretic/knowledge/cosmic_lore.dm
index 75ee0cd5916..4607d78ff5c 100644
--- a/code/modules/antagonists/heretic/knowledge/cosmic_lore.dm
+++ b/code/modules/antagonists/heretic/knowledge/cosmic_lore.dm
@@ -161,8 +161,11 @@
combo_timer = addtimer(CALLBACK(src, PROC_REF(reset_combo), source), combo_duration, TIMER_STOPPABLE)
var/mob/living/second_target_resolved = second_target?.resolve()
var/mob/living/third_target_resolved = third_target?.resolve()
- target.adjustFireLoss(4)
- target.adjustCloneLoss(2)
+ var/need_mob_update = FALSE
+ need_mob_update += target.adjustFireLoss(4, updating_health = FALSE)
+ need_mob_update += target.adjustCloneLoss(2, updating_health = FALSE)
+ if(need_mob_update)
+ target.updatehealth()
if(target == second_target_resolved || target == third_target_resolved)
reset_combo(source)
return
@@ -171,13 +174,19 @@
if(second_target_resolved)
new /obj/effect/temp_visual/cosmic_explosion(get_turf(second_target_resolved))
playsound(get_turf(second_target_resolved), 'sound/magic/cosmic_energy.ogg', 25, FALSE)
- second_target_resolved.adjustFireLoss(10)
- second_target_resolved.adjustCloneLoss(6)
+ need_mob_update = FALSE
+ need_mob_update += second_target_resolved.adjustFireLoss(10, updating_health = FALSE)
+ need_mob_update += second_target_resolved.adjustCloneLoss(6, updating_health = FALSE)
+ if(need_mob_update)
+ target.updatehealth()
if(third_target_resolved)
new /obj/effect/temp_visual/cosmic_domain(get_turf(third_target_resolved))
playsound(get_turf(third_target_resolved), 'sound/magic/cosmic_energy.ogg', 50, FALSE)
- third_target_resolved.adjustFireLoss(20)
- third_target_resolved.adjustCloneLoss(12)
+ need_mob_update = FALSE
+ need_mob_update += third_target_resolved.adjustFireLoss(20, updating_health = FALSE)
+ need_mob_update += third_target_resolved.adjustCloneLoss(12, updating_health = FALSE)
+ if(need_mob_update)
+ target.updatehealth()
if(combo_counter > 3)
target.apply_status_effect(/datum/status_effect/star_mark, source)
if(target.mind && target.stat != DEAD)
diff --git a/code/modules/antagonists/heretic/knowledge/flesh_lore.dm b/code/modules/antagonists/heretic/knowledge/flesh_lore.dm
index 915165ad768..5fa7c3a0b7c 100644
--- a/code/modules/antagonists/heretic/knowledge/flesh_lore.dm
+++ b/code/modules/antagonists/heretic/knowledge/flesh_lore.dm
@@ -251,7 +251,7 @@
/obj/effect/decal/cleanable/blood = 1,
/obj/item/bodypart/arm/left = 1,
)
- mob_to_summon = /mob/living/simple_animal/hostile/heretic_summon/raw_prophet
+ mob_to_summon = /mob/living/basic/heretic_summon/raw_prophet
cost = 1
route = PATH_FLESH
poll_ignore_define = POLL_IGNORE_RAW_PROPHET
diff --git a/code/modules/antagonists/heretic/knowledge/rust_lore.dm b/code/modules/antagonists/heretic/knowledge/rust_lore.dm
index 1eeaab69bdb..966134710b4 100644
--- a/code/modules/antagonists/heretic/knowledge/rust_lore.dm
+++ b/code/modules/antagonists/heretic/knowledge/rust_lore.dm
@@ -126,11 +126,14 @@
return
// Heals all damage + Stamina
- source.adjustBruteLoss(-2, FALSE)
- source.adjustFireLoss(-2, FALSE)
- source.adjustToxLoss(-2, FALSE, forced = TRUE) // Slimes are people to
- source.adjustOxyLoss(-0.5, FALSE)
- source.adjustStaminaLoss(-2)
+ var/need_mob_update = FALSE
+ need_mob_update += source.adjustBruteLoss(-2, updating_health = FALSE)
+ need_mob_update += source.adjustFireLoss(-2, updating_health = FALSE)
+ need_mob_update += source.adjustToxLoss(-2, updating_health = FALSE, forced = TRUE) // Slimes are people too
+ need_mob_update += source.adjustOxyLoss(-0.5, updating_health = FALSE)
+ need_mob_update += source.adjustStaminaLoss(-2, updating_stamina = FALSE)
+ if(need_mob_update)
+ source.updatehealth()
// Reduces duration of stuns/etc
source.AdjustAllImmobility(-0.5 SECONDS)
// Heals blood loss
@@ -297,11 +300,14 @@
if(!HAS_TRAIT(our_turf, TRAIT_RUSTY))
return
- source.adjustBruteLoss(-4, FALSE)
- source.adjustFireLoss(-4, FALSE)
- source.adjustToxLoss(-4, FALSE, forced = TRUE)
- source.adjustOxyLoss(-4, FALSE)
- source.adjustStaminaLoss(-20)
+ var/need_mob_update = FALSE
+ need_mob_update += source.adjustBruteLoss(-4, updating_health = FALSE)
+ need_mob_update += source.adjustFireLoss(-4, updating_health = FALSE)
+ need_mob_update += source.adjustToxLoss(-4, updating_health = FALSE, forced = TRUE)
+ need_mob_update += source.adjustOxyLoss(-4, updating_health = FALSE)
+ need_mob_update += source.adjustStaminaLoss(-20, updating_stamina = FALSE)
+ if(need_mob_update)
+ source.updatehealth()
/**
* #Rust spread datum
diff --git a/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_buff.dm b/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_buff.dm
index 0d2b67daae8..50aaad96cd8 100644
--- a/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_buff.dm
+++ b/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_buff.dm
@@ -27,7 +27,7 @@
/datum/status_effect/unholy_determination/tick(seconds_between_ticks)
// The amount we heal of each damage type per tick. If we're missing legs we heal better because we can't dodge.
- var/healing_amount = 1 + (2 - owner.usable_legs)
+ var/healing_amount = (0.4 + (0.8 - owner.usable_legs))
// In softcrit you're, strong enough to stay up.
if(owner.health <= owner.crit_threshold && owner.health >= owner.hardcrit_threshold)
@@ -48,22 +48,25 @@
if(prob(2))
playsound(owner, pick(GLOB.creepy_ambience), 50, TRUE)
- adjust_all_damages(healing_amount)
+ adjust_all_damages(healing_amount, seconds_between_ticks)
adjust_temperature()
adjust_bleed_wounds()
/*
* Heals up all the owner a bit, fire stacks and losebreath included.
*/
-/datum/status_effect/unholy_determination/proc/adjust_all_damages(amount)
+/datum/status_effect/unholy_determination/proc/adjust_all_damages(amount, seconds_between_ticks)
owner.adjust_fire_stacks(-1)
owner.losebreath = max(owner.losebreath - 0.5, 0)
- owner.adjustToxLoss(-amount, FALSE, TRUE)
- owner.adjustOxyLoss(-amount, FALSE)
- owner.adjustBruteLoss(-amount, FALSE)
- owner.adjustFireLoss(-amount)
+ var/need_mob_update = FALSE
+ need_mob_update += owner.adjustToxLoss(-amount * seconds_between_ticks, updating_health = FALSE, forced = TRUE)
+ need_mob_update += owner.adjustOxyLoss(-amount * seconds_between_ticks, updating_health = FALSE)
+ need_mob_update += owner.adjustBruteLoss(-amount * seconds_between_ticks, updating_health = FALSE)
+ need_mob_update += owner.adjustFireLoss(-amount * seconds_between_ticks, updating_health = FALSE)
+ if(need_mob_update)
+ owner.updatehealth()
/*
* Adjust the owner's temperature up or down to standard body temperatures.
diff --git a/code/modules/antagonists/heretic/magic/ascended_shapeshift.dm b/code/modules/antagonists/heretic/magic/ascended_shapeshift.dm
index 4395b4a54b3..4848635b443 100644
--- a/code/modules/antagonists/heretic/magic/ascended_shapeshift.dm
+++ b/code/modules/antagonists/heretic/magic/ascended_shapeshift.dm
@@ -6,7 +6,7 @@
cooldown_time = 20 SECONDS
die_with_shapeshifted_form = FALSE
possible_shapes = list(
- /mob/living/simple_animal/hostile/heretic_summon/raw_prophet,
+ /mob/living/basic/heretic_summon/raw_prophet/ascended,
/mob/living/simple_animal/hostile/heretic_summon/rust_spirit,
/mob/living/simple_animal/hostile/heretic_summon/ash_spirit,
/mob/living/simple_animal/hostile/heretic_summon/stalker,
diff --git a/code/modules/antagonists/heretic/magic/nightwatcher_rebirth.dm b/code/modules/antagonists/heretic/magic/nightwatcher_rebirth.dm
index 1e65ef88951..64638d7103b 100644
--- a/code/modules/antagonists/heretic/magic/nightwatcher_rebirth.dm
+++ b/code/modules/antagonists/heretic/magic/nightwatcher_rebirth.dm
@@ -46,11 +46,14 @@
victim.apply_damage(20, BURN)
// Heal the caster for every victim damaged
- caster.adjustBruteLoss(-10, FALSE)
- caster.adjustFireLoss(-10, FALSE)
- caster.adjustToxLoss(-10, FALSE)
- caster.adjustOxyLoss(-10, FALSE)
- caster.adjustStaminaLoss(-10)
+ var/need_mob_update = FALSE
+ need_mob_update += caster.adjustBruteLoss(-10, updating_health = FALSE)
+ need_mob_update += caster.adjustFireLoss(-10, updating_health = FALSE)
+ need_mob_update += caster.adjustToxLoss(-10, updating_health = FALSE)
+ need_mob_update += caster.adjustOxyLoss(-10, updating_health = FALSE)
+ need_mob_update += caster.adjustStaminaLoss(-10, updating_stamina = FALSE)
+ if(need_mob_update)
+ caster.updatehealth()
/obj/effect/temp_visual/eldritch_smoke
icon = 'icons/effects/eldritch.dmi'
diff --git a/code/modules/antagonists/heretic/magic/star_touch.dm b/code/modules/antagonists/heretic/magic/star_touch.dm
index ba8c2a56391..f2f2c935bbf 100644
--- a/code/modules/antagonists/heretic/magic/star_touch.dm
+++ b/code/modules/antagonists/heretic/magic/star_touch.dm
@@ -233,16 +233,16 @@
/datum/status_effect/cosmic_beam/proc/on_beam_hit(mob/living/target)
if(!istype(target, /mob/living/basic/heretic_summon/star_gazer))
target.AddElement(/datum/element/effect_trail, /obj/effect/forcefield/cosmic_field/fast)
- return
/// What to process when the beam is connected to a target
/datum/status_effect/cosmic_beam/proc/on_beam_tick(mob/living/target)
- target.adjustFireLoss(3)
- target.adjustCloneLoss(1)
- return
+ var/need_mob_update
+ need_mob_update = target.adjustFireLoss(3, updating_health = FALSE)
+ need_mob_update += target.adjustCloneLoss(1, updating_health = FALSE)
+ if(need_mob_update)
+ target.updatehealth()
/// What to remove when the beam disconnects from a target
/datum/status_effect/cosmic_beam/proc/on_beam_release(mob/living/target)
if(!istype(target, /mob/living/basic/heretic_summon/star_gazer))
target.RemoveElement(/datum/element/effect_trail, /obj/effect/forcefield/cosmic_field/fast)
- return
diff --git a/code/modules/antagonists/pirate/pirate_outfits.dm b/code/modules/antagonists/pirate/pirate_outfits.dm
index d2f648bb1fd..4c73cac107f 100644
--- a/code/modules/antagonists/pirate/pirate_outfits.dm
+++ b/code/modules/antagonists/pirate/pirate_outfits.dm
@@ -36,6 +36,12 @@
id_trim = /datum/id_trim/pirate/captain
head = /obj/item/clothing/head/costume/pirate/armored
+/datum/outfit/pirate/captain/skeleton
+ name = "Space Pirate Captain (Skeleton)"
+
+ belt = /obj/item/gun/magic/midas_hand
+ l_pocket = /obj/item/coin/gold/doubloon
+
/datum/outfit/pirate/space
name = "Space Pirate (EVA)"
diff --git a/code/modules/antagonists/pirate/pirate_roles.dm b/code/modules/antagonists/pirate/pirate_roles.dm
index 68683333c49..64baa724db1 100644
--- a/code/modules/antagonists/pirate/pirate_roles.dm
+++ b/code/modules/antagonists/pirate/pirate_roles.dm
@@ -61,7 +61,7 @@
/obj/effect/mob_spawn/ghost_role/human/pirate/skeleton/captain
rank = "Captain"
- outfit = /datum/outfit/pirate/captain
+ outfit = /datum/outfit/pirate/captain/skeleton
/obj/effect/mob_spawn/ghost_role/human/pirate/skeleton/gunner
rank = "Gunner"
diff --git a/code/modules/antagonists/revenant/revenant_blight.dm b/code/modules/antagonists/revenant/revenant_blight.dm
index 64bd6ce03bb..c56df7bd4ea 100644
--- a/code/modules/antagonists/revenant/revenant_blight.dm
+++ b/code/modules/antagonists/revenant/revenant_blight.dm
@@ -31,20 +31,23 @@
return
if(!finalstage)
+ var/need_mob_update = FALSE
if(affected_mob.body_position == LYING_DOWN && SPT_PROB(3 * stage, seconds_per_tick))
cure()
return FALSE
if(SPT_PROB(1.5 * stage, seconds_per_tick))
to_chat(affected_mob, span_revennotice("You suddenly feel [pick("sick and tired", "disoriented", "tired and confused", "nauseated", "faint", "dizzy")]..."))
affected_mob.adjust_confusion(8 SECONDS)
- affected_mob.adjustStaminaLoss(20, FALSE)
+ need_mob_update += affected_mob.adjustStaminaLoss(20, updating_stamina = FALSE)
new /obj/effect/temp_visual/revenant(affected_mob.loc)
if(stagedamage < stage)
stagedamage++
- affected_mob.adjustToxLoss(1 * stage * seconds_per_tick, FALSE) //should, normally, do about 30 toxin damage.
+ need_mob_update += affected_mob.adjustToxLoss(1 * stage * seconds_per_tick, updating_health = FALSE) //should, normally, do about 30 toxin damage.
new /obj/effect/temp_visual/revenant(affected_mob.loc)
if(SPT_PROB(25, seconds_per_tick))
- affected_mob.adjustStaminaLoss(stage, FALSE)
+ need_mob_update += affected_mob.adjustStaminaLoss(stage, updating_stamina = FALSE)
+ if(need_mob_update)
+ affected_mob.updatehealth()
switch(stage)
if(2)
@@ -60,7 +63,7 @@
if(!finalstage)
finalstage = TRUE
to_chat(affected_mob, span_revenbignotice("You feel like [pick("nothing's worth it anymore", "nobody ever needed your help", "nothing you did mattered", "everything you tried to do was worthless")]."))
- affected_mob.adjustStaminaLoss(22.5 * seconds_per_tick, FALSE)
+ affected_mob.adjustStaminaLoss(22.5 * seconds_per_tick, updating_stamina = FALSE)
new /obj/effect/temp_visual/revenant(affected_mob.loc)
if(affected_mob.dna && affected_mob.dna.species)
affected_mob.dna.species.handle_mutant_bodyparts(affected_mob,"#1d2953")
diff --git a/code/modules/antagonists/wizard/equipment/artefact.dm b/code/modules/antagonists/wizard/equipment/artefact.dm
index 3e4cf0766f5..4783daffb8b 100644
--- a/code/modules/antagonists/wizard/equipment/artefact.dm
+++ b/code/modules/antagonists/wizard/equipment/artefact.dm
@@ -311,7 +311,7 @@
//Provides a decent heal, need to pump every 6 seconds
/obj/item/organ/internal/heart/cursed/wizard
- pump_delay = 60
+ pump_delay = 6 SECONDS
heal_brute = 25
heal_burn = 25
heal_oxy = 25
diff --git a/code/modules/bitrunning/components/netpod_healing.dm b/code/modules/bitrunning/components/netpod_healing.dm
index fc7de89bcf3..2e61b737af5 100644
--- a/code/modules/bitrunning/components/netpod_healing.dm
+++ b/code/modules/bitrunning/components/netpod_healing.dm
@@ -45,15 +45,17 @@
qdel(src)
return
- owner.adjustBruteLoss(-brute_heal * seconds_per_tick, updating_health = FALSE)
- owner.adjustFireLoss(-burn_heal * seconds_per_tick, updating_health = FALSE)
- owner.adjustToxLoss(-toxin_heal * seconds_per_tick, updating_health = FALSE, forced = TRUE)
- owner.adjustCloneLoss(-clone_heal * seconds_per_tick, updating_health = FALSE)
+ var/need_mob_update = FALSE
+ need_mob_update += owner.adjustBruteLoss(-brute_heal * seconds_per_tick, updating_health = FALSE)
+ need_mob_update += owner.adjustFireLoss(-burn_heal * seconds_per_tick, updating_health = FALSE)
+ need_mob_update += owner.adjustToxLoss(-toxin_heal * seconds_per_tick, updating_health = FALSE, forced = TRUE)
+ need_mob_update += owner.adjustCloneLoss(-clone_heal * seconds_per_tick, updating_health = FALSE)
if(owner.blood_volume < BLOOD_VOLUME_NORMAL)
owner.blood_volume += blood_heal * seconds_per_tick
- owner.updatehealth()
+ if(need_mob_update)
+ owner.updatehealth()
/datum/status_effect/embryonic
id = "embryonic"
diff --git a/code/modules/bitrunning/server/util.dm b/code/modules/bitrunning/server/util.dm
index 1d35e86de50..c4f1319cd12 100644
--- a/code/modules/bitrunning/server/util.dm
+++ b/code/modules/bitrunning/server/util.dm
@@ -58,10 +58,10 @@
"health" = creature.health,
"name" = creature.name,
"pilot" = pilot,
- "brute" = creature.get_damage_amount(BRUTE),
- "burn" = creature.get_damage_amount(BURN),
- "tox" = creature.get_damage_amount(TOX),
- "oxy" = creature.get_damage_amount(OXY),
+ "brute" = creature.get_current_damage_of_type(BRUTE),
+ "burn" = creature.get_current_damage_of_type(BURN),
+ "tox" = creature.get_current_damage_of_type(TOX),
+ "oxy" = creature.get_current_damage_of_type(OXY),
))
return hosted_avatars
diff --git a/code/modules/cargo/department_order.dm b/code/modules/cargo/department_order.dm
index b1573c97a5b..46122fd8741 100644
--- a/code/modules/cargo/department_order.dm
+++ b/code/modules/cargo/department_order.dm
@@ -21,12 +21,28 @@ GLOBAL_LIST_INIT(department_order_cooldowns, list(
var/list/department_delivery_areas = list()
///which groups this computer can order from
var/list/dep_groups = list()
+ /// If this departmental order console currently is on cooldown.
+ var/on_cooldown = FALSE
+
+ /// Our radio object we use to talk to our department.
+ var/obj/item/radio/radio
+ /// The radio key typepath that will be instantiated and inserted into our radio.
+ var/obj/item/encryptionkey/radio_key_typepath
+ /// The radio channel we will speak into by default.
+ var/radio_channel
/obj/machinery/computer/department_orders/Initialize(mapload, obj/item/circuitboard/board)
. = ..()
// All maps should have ONLY ONE of each order console roundstart
REGISTER_REQUIRED_MAP_ITEM(1, 1)
+ if (radio_channel && radio_key_typepath)
+ radio = new(src)
+ radio.keyslot = new radio_key_typepath
+ radio.subspace_transmission = TRUE
+ radio.canhear_range = 0
+ radio.recalculateChannels()
+
if(mapload) //check for mapping errors
for(var/delivery_area_type in department_delivery_areas)
if(GLOB.areas_by_type[delivery_area_type])
@@ -35,6 +51,11 @@ GLOBAL_LIST_INIT(department_order_cooldowns, list(
log_mapping("[src] has no valid areas to deliver to on this map, add some more fallback areas to its \"department_delivery_areas\" var.")
department_delivery_areas = list(/area/station/hallway/primary/central) //if this doesn't exist like honestly fuck your map man
+/obj/machinery/computer/department_orders/Destroy()
+ QDEL_NULL(radio)
+
+ return ..()
+
/obj/machinery/computer/department_orders/ui_interact(mob/user, datum/tgui/ui)
. = ..()
ui = SStgui.try_update_ui(user, src, ui)
@@ -172,6 +193,20 @@ GLOBAL_LIST_INIT(department_order_cooldowns, list(
time_y = 10 MINUTES * time_y
GLOB.department_order_cooldowns[type] = world.time + time_y
+/obj/machinery/computer/department_orders/process()
+ . = ..()
+ if (!.)
+ return FALSE
+
+ if (GLOB.department_order_cooldowns[type] > world.time)
+ on_cooldown = TRUE
+ else if (on_cooldown)
+ radio?.talk_into(src, "Order cooldown has expired! A new order may now be placed!", radio_channel)
+ playsound(src, 'sound/machines/ping.ogg', 30, TRUE)
+ on_cooldown = FALSE
+
+ return TRUE
+
/obj/machinery/computer/department_orders/service
name = "service order console"
circuit = /obj/item/circuitboard/computer/service_orders
@@ -179,6 +214,8 @@ GLOBAL_LIST_INIT(department_order_cooldowns, list(
override_access = ACCESS_HOP
req_one_access = list(ACCESS_SERVICE)
dep_groups = list("Service", "Food & Hydroponics", "Livestock", "Costumes & Toys")
+ radio_key_typepath = /obj/item/encryptionkey/headset_service
+ radio_channel = RADIO_CHANNEL_SERVICE
/obj/machinery/computer/department_orders/engineering
name = "engineering order console"
@@ -187,6 +224,8 @@ GLOBAL_LIST_INIT(department_order_cooldowns, list(
override_access = ACCESS_CE
req_one_access = REGION_ACCESS_ENGINEERING
dep_groups = list("Engineering", "Engine Construction", "Canisters & Materials")
+ radio_key_typepath = /obj/item/encryptionkey/headset_eng
+ radio_channel = RADIO_CHANNEL_ENGINEERING
/obj/machinery/computer/department_orders/science
name = "science order console"
@@ -195,6 +234,8 @@ GLOBAL_LIST_INIT(department_order_cooldowns, list(
override_access = ACCESS_RD
req_one_access = REGION_ACCESS_RESEARCH
dep_groups = list("Science", "Livestock", "Canisters & Materials")
+ radio_key_typepath = /obj/item/encryptionkey/headset_sci
+ radio_channel = RADIO_CHANNEL_SCIENCE
/obj/machinery/computer/department_orders/security
name = "security order console"
@@ -207,6 +248,8 @@ GLOBAL_LIST_INIT(department_order_cooldowns, list(
override_access = ACCESS_HOS
req_one_access = REGION_ACCESS_SECURITY
dep_groups = list("Security", "Armory")
+ radio_key_typepath = /obj/item/encryptionkey/headset_sec
+ radio_channel = RADIO_CHANNEL_SECURITY
/obj/machinery/computer/department_orders/medical
name = "medical order console"
@@ -220,3 +263,5 @@ GLOBAL_LIST_INIT(department_order_cooldowns, list(
override_access = ACCESS_CMO
req_one_access = REGION_ACCESS_MEDBAY
dep_groups = list("Medical")
+ radio_key_typepath = /obj/item/encryptionkey/headset_med
+ radio_channel = RADIO_CHANNEL_MEDICAL
diff --git a/code/modules/cargo/exports/materials.dm b/code/modules/cargo/exports/materials.dm
index 46d089b5ac5..c9a88a6edfb 100644
--- a/code/modules/cargo/exports/materials.dm
+++ b/code/modules/cargo/exports/materials.dm
@@ -161,4 +161,4 @@
var/sale_value = sold_block.export_value
SSstock_market.materials_quantity[sold_block.export_mat] += sold_block.quantity
SSstock_market.materials_prices[sold_block.export_mat] -= round((sale_value) * (sold_block.quantity / (sold_block.quantity + SSstock_market.materials_quantity[sold_block.export_mat])))
- SSstock_market.materials_prices[sold_block.export_mat] = round(clamp(SSstock_market.materials_prices[sold_block.export_mat], sold_block.export_mat.value_per_unit * SHEET_MATERIAL_AMOUNT * 0.5 , sold_block.export_mat.value_per_unit * SHEET_MATERIAL_AMOUNT * 3))
+ SSstock_market.materials_prices[sold_block.export_mat] = round(clamp(SSstock_market.materials_prices[sold_block.export_mat], initial(sold_block.export_mat.value_per_unit) * SHEET_MATERIAL_AMOUNT * 0.5 , initial(sold_block.export_mat.value_per_unit) * SHEET_MATERIAL_AMOUNT * 3))
diff --git a/code/modules/cargo/materials_market.dm b/code/modules/cargo/materials_market.dm
index d211df7debd..dd56128241d 100644
--- a/code/modules/cargo/materials_market.dm
+++ b/code/modules/cargo/materials_market.dm
@@ -92,12 +92,12 @@
else if(SSstock_market.materials_trends[traded_mat] == -1)
trend_string = "down"
var/color_string = ""
- if(traded_mat.color)
- color_string = traded_mat.color
- else if (traded_mat.greyscale_colors)
- color_string = splicetext(traded_mat.greyscale_colors, 6, length(traded_mat.greyscale_colors), "") //slice it to a standard 6 char hex
+ if (initial(traded_mat.greyscale_colors))
+ color_string = splicetext(initial(traded_mat.greyscale_colors), 7, length(initial(traded_mat.greyscale_colors)), "") //slice it to a standard 6 char hex
+ else if(initial(traded_mat.color))
+ color_string = initial(traded_mat.color)
material_data += list(list(
- "name" = traded_mat.name,
+ "name" = initial(traded_mat.name),
"price" = SSstock_market.materials_prices[traded_mat],
"quantity" = SSstock_market.materials_quantity[traded_mat],
"trend" = trend_string,
@@ -144,7 +144,7 @@
var/datum/material/material_bought
var/obj/item/stack/sheet/sheet_to_buy
for(var/datum/material/mat as anything in SSstock_market.materials_prices)
- if(mat.name == material_str)
+ if(initial(mat.name) == material_str)
material_bought = mat
break
if(!material_bought)
@@ -159,7 +159,7 @@
var/cost = SSstock_market.materials_prices[material_bought] * quantity
- sheet_to_buy = material_bought.sheet_type
+ sheet_to_buy = initial(material_bought.sheet_type)
if(!sheet_to_buy)
CRASH("Material with no sheet type being sold on materials market!")
if(!account_payable)
@@ -231,7 +231,7 @@
/obj/item/stock_block/examine(mob/user)
. = ..()
- . += span_notice("\The [src] is worth [export_value] cr, from selling [quantity] sheets of [export_mat?.name].")
+ . += span_notice("\The [src] is worth [export_value] cr, from selling [quantity] sheets of [initial(export_mat?.name)].")
if(fluid)
. += span_warning("\The [src] is currently liquid! It's value is based on the market price.")
else
diff --git a/code/modules/cargo/packs/organic.dm b/code/modules/cargo/packs/organic.dm
index 73c98cb4b3a..eb26d5ec907 100644
--- a/code/modules/cargo/packs/organic.dm
+++ b/code/modules/cargo/packs/organic.dm
@@ -299,10 +299,12 @@
ONLY 5000 BUX GET NOW! Contains a grill and fuel."
cost = CARGO_CRATE_VALUE * 8
crate_type = /obj/structure/closet/crate
- contains = list(/obj/item/stack/sheet/mineral/coal/five,
- /obj/machinery/grill/unwrenched,
- /obj/item/reagent_containers/cup/soda_cans/monkey_energy,
- )
+ contains = list(
+ /obj/item/stack/sheet/mineral/coal/five,
+ /obj/item/kitchen/tongs,
+ /obj/item/reagent_containers/cup/soda_cans/monkey_energy,
+ /obj/machinery/grill/unwrenched,
+ )
crate_name = "grilling starter kit crate"
/datum/supply_pack/organic/grillfuel
diff --git a/code/modules/client/client_colour.dm b/code/modules/client/client_colour.dm
index 444b4d7ec12..707267e7143 100644
--- a/code/modules/client/client_colour.dm
+++ b/code/modules/client/client_colour.dm
@@ -221,6 +221,10 @@
override = TRUE
colour = list(0.8,0,0,0, 0,0,0,0, 0,0,1,0, 0,0,0,1, 0,0,0,0)
+/datum/client_colour/manual_heart_blood
+ priority = PRIORITY_ABSOLUTE
+ colour = COLOR_RED
+
#undef PRIORITY_ABSOLUTE
#undef PRIORITY_HIGH
#undef PRIORITY_NORMAL
diff --git a/code/modules/client/preferences/species_features/basic.dm b/code/modules/client/preferences/species_features/basic.dm
index faa86cc07e2..6e34a234e7d 100644
--- a/code/modules/client/preferences/species_features/basic.dm
+++ b/code/modules/client/preferences/species_features/basic.dm
@@ -4,16 +4,13 @@
head_icon = icon('icons/mob/human/bodyparts_greyscale.dmi', "human_head_m")
head_icon.Blend(skintone2hex("caucasian1"), ICON_MULTIPLY)
- if (isnull(sprite_accessory))
- return head_icon
-
- ASSERT(istype(sprite_accessory))
-
var/icon/final_icon = new(head_icon)
+ if (!isnull(sprite_accessory))
+ ASSERT(istype(sprite_accessory))
- var/icon/head_accessory_icon = icon(sprite_accessory.icon, sprite_accessory.icon_state)
- head_accessory_icon.Blend(COLOR_DARK_BROWN, ICON_MULTIPLY)
- final_icon.Blend(head_accessory_icon, ICON_OVERLAY)
+ var/icon/head_accessory_icon = icon(sprite_accessory.icon, sprite_accessory.icon_state)
+ head_accessory_icon.Blend(COLOR_DARK_BROWN, ICON_MULTIPLY)
+ final_icon.Blend(head_accessory_icon, ICON_OVERLAY)
final_icon.Crop(10, 19, 22, 31)
final_icon.Scale(32, 32)
diff --git a/code/modules/events/space_vines/vine_structure.dm b/code/modules/events/space_vines/vine_structure.dm
index 47357d558ac..155a4c5c083 100644
--- a/code/modules/events/space_vines/vine_structure.dm
+++ b/code/modules/events/space_vines/vine_structure.dm
@@ -37,6 +37,7 @@
)
AddElement(/datum/element/connect_loc, loc_connections)
AddElement(/datum/element/atmos_sensitive, mapload)
+ AddComponent(/datum/component/storm_hating)
/obj/structure/spacevine/examine(mob/user)
. = ..()
@@ -147,7 +148,7 @@
break //only capture one mob at a time
/obj/structure/spacevine/proc/entangle(mob/living/victim)
- if(!victim || isvineimmune(victim))
+ if(isnull(victim) || isvineimmune(victim))
return
for(var/datum/spacevine_mutation/mutation in mutations)
mutation.on_buckle(src, victim)
@@ -157,7 +158,7 @@
/// Finds a target tile to spread to. If checks pass it will spread to it and also proc on_spread on target.
/obj/structure/spacevine/proc/spread()
- if(!master) //If we've lost our controller, something has gone terribly wrong.
+ if(isnull(master)) //If we've lost our controller, something has gone terribly wrong.
return
var/direction = pick(GLOB.cardinals)
@@ -165,20 +166,29 @@
if(!istype(stepturf))
return
- if(!isspaceturf(stepturf) && stepturf.Enter(src))
- var/obj/structure/spacevine/spot_taken = locate() in stepturf //Locates any vine on target turf. Calls that vine "spot_taken".
- var/datum/spacevine_mutation/vine_eating/eating = locate() in mutations //Locates the vine eating trait in our own seed and calls it E.
- if(!spot_taken || (eating && (spot_taken && !spot_taken.mutations?.Find(eating)))) //Proceed if there isn't a vine on the target turf, OR we have vine eater AND target vine is from our seed and doesn't. Vines from other seeds are eaten regardless.
- for(var/datum/spacevine_mutation/mutation in mutations)
- mutation.on_spread(src, stepturf) //Only do the on_spread proc if it actually spreads.
- stepturf = get_step(src,direction) //in case turf changes, to make sure no runtimes happen
- var/obj/structure/spacevine/spawning_vine = master.spawn_spacevine_piece(stepturf, src) //Let's do a cool little animate
- if(NSCOMPONENT(direction))
- spawning_vine.pixel_y = direction == NORTH ? -32 : 32
- animate(spawning_vine, pixel_y = 0, time = 1 SECONDS)
- else
- spawning_vine.pixel_x = direction == EAST ? -32 : 32
- animate(spawning_vine, pixel_x = 0, time = 1 SECONDS)
+ if(isspaceturf(stepturf) || isopenspaceturf(stepturf) || !stepturf.Enter(src))
+ return
+ if(ischasm(stepturf) && !HAS_TRAIT(stepturf, TRAIT_CHASM_STOPPED))
+ return
+ if(islava(stepturf) && !HAS_TRAIT(stepturf, TRAIT_LAVA_STOPPED))
+ return
+ var/obj/structure/spacevine/spot_taken = locate() in stepturf
+ var/datum/spacevine_mutation/vine_eating/eating = locate() in mutations
+ if(!isnull(spot_taken)) //Proceed if there isn't a vine on the target turf, OR we have vine eater AND target vine is from our seed and doesn't.
+ if (isnull(eating))
+ return
+ if (spot_taken.mutations?.Find(eating))
+ return
+ for(var/datum/spacevine_mutation/mutation in mutations)
+ mutation.on_spread(src, stepturf)
+ stepturf = get_step(src, direction)
+ var/obj/structure/spacevine/spawning_vine = master.spawn_spacevine_piece(stepturf, src)
+ if(NSCOMPONENT(direction))
+ spawning_vine.pixel_y = direction == NORTH ? -32 : 32
+ animate(spawning_vine, pixel_y = 0, time = 1 SECONDS)
+ else
+ spawning_vine.pixel_x = direction == EAST ? -32 : 32
+ animate(spawning_vine, pixel_x = 0, time = 1 SECONDS)
/// Destroying an explosive vine sets off a chain reaction
/obj/structure/spacevine/ex_act(severity, target)
diff --git a/code/modules/food_and_drinks/machinery/gibber.dm b/code/modules/food_and_drinks/machinery/gibber.dm
index ebb2b85e2b9..45e66f95ed2 100644
--- a/code/modules/food_and_drinks/machinery/gibber.dm
+++ b/code/modules/food_and_drinks/machinery/gibber.dm
@@ -198,6 +198,7 @@
occupant.reagents.trans_to(newmeat, occupant_volume / meat_produced, remove_blacklisted = TRUE)
if(sourcejob)
newmeat.subjectjob = sourcejob
+
allmeat[i] = newmeat
if(typeofskin)
@@ -221,12 +222,24 @@
skin.throw_at(pick(nearby_turfs),meat_produced,3)
for (var/i=1 to meat_produced)
var/obj/item/meatslab = allmeat[i]
+
+ if(LAZYLEN(diseases))
+ var/list/datum/disease/diseases_to_add = list()
+ for(var/datum/disease/disease as anything in diseases)
+ // admin or special viruses that should not be reproduced
+ if(disease.spread_flags & (DISEASE_SPREAD_SPECIAL | DISEASE_SPREAD_NON_CONTAGIOUS))
+ continue
+
+ diseases_to_add += disease
+ if(LAZYLEN(diseases_to_add))
+ meatslab.AddComponent(/datum/component/infective, diseases_to_add)
+
meatslab.forceMove(loc)
meatslab.throw_at(pick(nearby_turfs),i,3)
for (var/turfs=1 to meat_produced)
var/turf/gibturf = pick(nearby_turfs)
if (!gibturf.density && (src in view(gibturf)))
- new gibtype(gibturf,i,diseases)
+ new gibtype(gibturf, i, diseases)
pixel_x = base_pixel_x //return to its spot after shaking
operating = FALSE
diff --git a/code/modules/food_and_drinks/machinery/smartfridge.dm b/code/modules/food_and_drinks/machinery/smartfridge.dm
index 6d6645e3368..dfe3987dfe2 100644
--- a/code/modules/food_and_drinks/machinery/smartfridge.dm
+++ b/code/modules/food_and_drinks/machinery/smartfridge.dm
@@ -630,7 +630,7 @@
/obj/item/reagent_containers/cup/beaker,
/obj/item/reagent_containers/spray,
/obj/item/reagent_containers/medigel,
- /obj/item/reagent_containers/cup/vial, //SKYRAT EDIT HYPOSPRAYS
+ /obj/item/reagent_containers/cup/vial, //SKYRAT EDIT ADDITION - HYPOSPRAYS
/obj/item/reagent_containers/chem_pack
))
diff --git a/code/modules/forensics/_forensics.dm b/code/modules/forensics/_forensics.dm
index 76a051f1d72..5936ce4b5c4 100644
--- a/code/modules/forensics/_forensics.dm
+++ b/code/modules/forensics/_forensics.dm
@@ -232,6 +232,8 @@
/datum/forensics/proc/check_blood()
if(!parent || !isitem(parent.resolve()))
return
+ if(isorgan(parent.resolve())) // organs don't spawn with blood decals by default
+ return
if(!length(blood_DNA))
return
var/atom/parent_atom = parent.resolve()
diff --git a/code/modules/jobs/job_types/cook.dm b/code/modules/jobs/job_types/cook.dm
index a3f03c2d9b1..e96bae827fa 100644
--- a/code/modules/jobs/job_types/cook.dm
+++ b/code/modules/jobs/job_types/cook.dm
@@ -33,13 +33,14 @@
// Adds up to 100, don't mess it up
mail_goodies = list(
/obj/item/storage/box/ingredients/random = 40,
- /obj/item/reagent_containers/cup/bottle/caramel = 8,
- /obj/item/reagent_containers/condiment/flour = 8,
- /obj/item/reagent_containers/condiment/rice = 8,
- /obj/item/reagent_containers/condiment/ketchup = 8,
- /obj/item/reagent_containers/condiment/enzyme = 8,
- /obj/item/reagent_containers/condiment/soymilk = 8,
+ /obj/item/reagent_containers/cup/bottle/caramel = 7,
+ /obj/item/reagent_containers/condiment/flour = 7,
+ /obj/item/reagent_containers/condiment/rice = 7,
+ /obj/item/reagent_containers/condiment/ketchup = 7,
+ /obj/item/reagent_containers/condiment/enzyme = 7,
+ /obj/item/reagent_containers/condiment/soymilk = 7,
/obj/item/kitchen/spoon/soup_ladle = 6,
+ /obj/item/kitchen/tongs = 6,
/obj/item/knife/kitchen = 4,
/obj/item/knife/butcher = 2,
)
diff --git a/code/modules/library/bibles.dm b/code/modules/library/bibles.dm
index 7a69fa27957..3cfc9c8b76b 100644
--- a/code/modules/library/bibles.dm
+++ b/code/modules/library/bibles.dm
@@ -223,7 +223,7 @@ GLOBAL_LIST_INIT(bibleitemstates, list(
var/list/hurt_limbs = built_in_his_image.get_damaged_bodyparts(1, 1, BODYTYPE_ORGANIC)
if(length(hurt_limbs))
for(var/obj/item/bodypart/affecting as anything in hurt_limbs)
- if(affecting.heal_damage(heal_amt, heal_amt, BODYTYPE_ORGANIC))
+ if(affecting.heal_damage(heal_amt, heal_amt, required_bodytype = BODYTYPE_ORGANIC))
built_in_his_image.update_damage_overlays()
built_in_his_image.visible_message(span_notice("[user] heals [built_in_his_image] with the power of [deity_name]!"))
to_chat(built_in_his_image, span_boldnotice("May the power of [deity_name] compel you to be healed!"))
diff --git a/code/modules/mapfluff/ruins/objects_and_mobs/ash_walker_den.dm b/code/modules/mapfluff/ruins/objects_and_mobs/ash_walker_den.dm
index 505b6cd5d79..480b26f5fab 100644
--- a/code/modules/mapfluff/ruins/objects_and_mobs/ash_walker_den.dm
+++ b/code/modules/mapfluff/ruins/objects_and_mobs/ash_walker_den.dm
@@ -57,10 +57,10 @@
visible_message(span_notice("Serrated tendrils eagerly pull [H] apart, but find nothing of interest."))
return
- if(H.mind?.has_antag_datum(/datum/antagonist/ashwalker) && (H.key || H.get_ghost(FALSE, TRUE))) //special interactions for dead lava lizards with ghosts attached
+ if(H.mind?.has_antag_datum(/datum/antagonist/ashwalker) && (H.ckey || H.get_ghost(FALSE, TRUE))) //special interactions for dead lava lizards with ghosts attached
visible_message(span_warning("Serrated tendrils carefully pull [H] to [src], absorbing the body and creating it anew."))
var/datum/mind/deadmind
- if(H.key)
+ if(H.ckey)
deadmind = H
else
deadmind = H.get_ghost(FALSE, TRUE)
@@ -77,8 +77,8 @@
meat_counter++
visible_message(span_warning("Serrated tendrils eagerly pull [H] to [src], tearing the body apart as its blood seeps over the eggs."))
playsound(get_turf(src),'sound/magic/demon_consume.ogg', 100, TRUE)
- var/deliverykey = H.fingerprintslast //key of whoever brought the body
- var/mob/living/deliverymob = get_mob_by_key(deliverykey) //mob of said key
+ var/deliverykey = H.fingerprintslast //ckey of whoever brought the body
+ var/mob/living/deliverymob = get_mob_by_key(deliverykey) //mob of said ckey
//there is a 40% chance that the Lava Lizard unlocks their respawn with each sacrifice
if(deliverymob && (deliverymob.mind?.has_antag_datum(/datum/antagonist/ashwalker)) && (deliverykey in ashies.players_spawned) && (prob(40)))
to_chat(deliverymob, span_warning("The Necropolis is pleased with your sacrifice. You feel confident your existence after death is secure."))
diff --git a/code/modules/mapping/map_template.dm b/code/modules/mapping/map_template.dm
index 237ae9f2d52..7917da4d542 100644
--- a/code/modules/mapping/map_template.dm
+++ b/code/modules/mapping/map_template.dm
@@ -109,7 +109,6 @@
// need these two below?
SSmachines.setup_template_powernets(cables)
SSair.setup_template_machinery(atmos_machines)
- SSshuttle.setup_shuttles(ports)
//calculate all turfs inside the border
var/list/template_and_bordering_turfs = block(
diff --git a/code/modules/mob/living/basic/health_adjustment.dm b/code/modules/mob/living/basic/health_adjustment.dm
index 6355f809cf4..e453bf7306e 100644
--- a/code/modules/mob/living/basic/health_adjustment.dm
+++ b/code/modules/mob/living/basic/health_adjustment.dm
@@ -5,18 +5,16 @@
* * amount The amount that will be used to adjust the mob's health
* * updating_health If the mob's health should be immediately updated to the new value
* * forced If we should force update the adjustment of the mob's health no matter the restrictions, like GODMODE
+ * returns the net change in bruteloss after applying the damage amount
*/
/mob/living/basic/proc/adjust_health(amount, updating_health = TRUE, forced = FALSE)
. = FALSE
if(forced || !(status_flags & GODMODE))
+ . = bruteloss // bruteloss value before applying damage
bruteloss = round(clamp(bruteloss + amount, 0, maxHealth * 2), DAMAGE_PRECISION)
if(updating_health)
updatehealth()
- . = amount
- if(ckey || stat)
- return
- //if(AIStatus == AI_IDLE)
- // toggle_ai(AI_ON)
+ . -= bruteloss
/mob/living/basic/adjustBruteLoss(amount, updating_health = TRUE, forced = FALSE, required_bodytype)
if(forced)
@@ -42,16 +40,18 @@
else if(damage_coeff[TOX])
. = adjust_health(amount * damage_coeff[TOX] * CONFIG_GET(number/damage_multiplier), updating_health, forced)
-/mob/living/basic/adjustCloneLoss(amount, updating_health = TRUE, forced = FALSE)
+/mob/living/basic/adjustCloneLoss(amount, updating_health = TRUE, forced = FALSE, required_biotype)
if(forced)
. = adjust_health(amount * CONFIG_GET(number/damage_multiplier), updating_health, forced)
else if(damage_coeff[CLONE])
. = adjust_health(amount * damage_coeff[CLONE] * CONFIG_GET(number/damage_multiplier), updating_health, forced)
/mob/living/basic/adjustStaminaLoss(amount, updating_stamina = TRUE, forced = FALSE, required_biotype)
+ . = staminaloss
if(forced)
staminaloss = max(0, min(BASIC_MOB_MAX_STAMINALOSS, staminaloss + amount))
else
staminaloss = max(0, min(BASIC_MOB_MAX_STAMINALOSS, staminaloss + (amount * damage_coeff[STAMINA])))
if(updating_stamina)
update_stamina()
+ . -= staminaloss
diff --git a/code/modules/mob/living/basic/heretic/heretic_summon.dm b/code/modules/mob/living/basic/heretic/heretic_summon.dm
index cdae7ea6786..cf1bcf80aad 100644
--- a/code/modules/mob/living/basic/heretic/heretic_summon.dm
+++ b/code/modules/mob/living/basic/heretic/heretic_summon.dm
@@ -1,16 +1,14 @@
/mob/living/basic/heretic_summon
name = "Eldritch Demon"
real_name = "Eldritch Demon"
- desc = "A horror from beyond this realm."
+ desc = "A horror from beyond this realm, summoned by bad code."
icon = 'icons/mob/nonhuman-player/eldritch_mobs.dmi'
faction = list(FACTION_HERETIC)
basic_mob_flags = DEL_ON_DEATH
gender = NEUTER
mob_biotypes = NONE
- unsuitable_atmos_damage = 0
- unsuitable_cold_damage = 0
- unsuitable_heat_damage = 0
+ habitable_atmos = list("min_oxy" = 0, "max_oxy" = 0, "min_plas" = 0, "max_plas" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0)
speed = 0
melee_attack_cooldown = CLICK_CD_MELEE
@@ -20,8 +18,8 @@
response_help_simple = "think better of touching"
response_disarm_continuous = "flails at"
response_disarm_simple = "flail at"
- response_harm_continuous = "reaps"
- response_harm_simple = "tears"
+ response_harm_continuous = "rips"
+ response_harm_simple = "tear"
death_message = "implodes into itself."
combat_mode = TRUE
diff --git a/code/modules/mob/living/basic/heretic/raw_prophet.dm b/code/modules/mob/living/basic/heretic/raw_prophet.dm
new file mode 100644
index 00000000000..1a3b2d1aa92
--- /dev/null
+++ b/code/modules/mob/living/basic/heretic/raw_prophet.dm
@@ -0,0 +1,96 @@
+/**
+ * A funny little rolling guy who is great at scouting.
+ * It can see through walls, jaunt, and create a psychic network to report its findings.
+ * It can blind people to make a getaway, but also get stronger if it attacks the same target consecutively.
+ */
+/mob/living/basic/heretic_summon/raw_prophet
+ name = "Raw Prophet"
+ real_name = "Raw Prophet"
+ desc = "An abomination stitched together from a few severed arms and one swollen, orphaned eye."
+ icon_state = "raw_prophet"
+ icon_living = "raw_prophet"
+ status_flags = CANPUSH
+ melee_damage_lower = 5
+ melee_damage_upper = 10
+ maxHealth = 65
+ health = 65
+ sight = SEE_MOBS|SEE_OBJS|SEE_TURFS
+ /// Some ability we use to make people go blind
+ var/blind_action_type = /datum/action/cooldown/spell/pointed/blind/eldritch
+
+/mob/living/basic/heretic_summon/raw_prophet/Initialize(mapload)
+ . = ..()
+ AddElement(/datum/element/wheel)
+ var/static/list/body_parts = list(/obj/effect/gibspawner/human, /obj/item/bodypart/arm/left, /obj/item/organ/internal/eyes)
+ AddElement(/datum/element/death_drops, body_parts)
+ AddComponent(/datum/component/focused_attacker)
+ var/on_link_message = "You feel something new enter your sphere of mind... \
+ You hear whispers of people far away, screeches of horror and a huming of welcome to [src]'s Mansus Link."
+ var/on_unlink_message = "Your mind shatters as [src]'s Mansus Link leaves your mind."
+ AddComponent( \
+ /datum/component/mind_linker/active_linking, \
+ network_name = "Mansus Link", \
+ chat_color = "#568b00", \
+ post_unlink_callback = CALLBACK(src, PROC_REF(after_unlink)), \
+ speech_action_background_icon_state = "bg_heretic", \
+ speech_action_overlay_state = "bg_heretic_border", \
+ linker_action_path = /datum/action/cooldown/spell/pointed/manse_link, \
+ link_message = on_link_message, \
+ unlink_message = on_unlink_message, \
+ )
+
+ // We don't use these for AI so we can just repeat the same adding process
+ var/static/list/add_abilities = list(
+ /datum/action/cooldown/spell/jaunt/ethereal_jaunt/ash/long,
+ /datum/action/cooldown/spell/list_target/telepathy/eldritch,
+ /datum/action/innate/expand_sight,
+ )
+ for (var/ability_type in add_abilities)
+ var/datum/action/new_action = new ability_type(src)
+ new_action.Grant(src)
+
+ var/datum/action/cooldown/blind = new blind_action_type(src)
+ blind.Grant(src)
+ ai_controller?.set_blackboard_key(BB_TARGETTED_ACTION, blind)
+
+/*
+ * Callback for the mind_linker component.
+ * Stuns people who are ejected from the network.
+ */
+/mob/living/basic/heretic_summon/raw_prophet/proc/after_unlink(mob/living/unlinked_mob)
+ if(QDELETED(unlinked_mob) || unlinked_mob.stat == DEAD)
+ return
+
+ INVOKE_ASYNC(unlinked_mob, TYPE_PROC_REF(/mob, emote), "scream")
+ unlinked_mob.AdjustParalyzed(0.5 SECONDS) //micro stun
+
+/mob/living/basic/heretic_summon/raw_prophet/melee_attack(atom/target, list/modifiers, ignore_cooldown)
+ SpinAnimation(speed = 5, loops = 1)
+ if (target == src)
+ return
+ return ..()
+
+/// Variant raw prophet used by eldritch transformation with more base attack power
+/mob/living/basic/heretic_summon/raw_prophet/ascended
+ melee_damage_lower = 15
+ melee_damage_upper = 20
+
+/// NPC variant with a less bullshit ability
+/mob/living/basic/heretic_summon/raw_prophet/ruins
+ ai_controller = /datum/ai_controller/basic_controller/raw_prophet
+ blind_action_type = /datum/action/cooldown/mob_cooldown/watcher_gaze
+
+/// Walk and attack people, blind them when we can
+/datum/ai_controller/basic_controller/raw_prophet
+ blackboard = list(
+ BB_TARGETTING_DATUM = new /datum/targetting_datum/basic,
+ )
+
+ ai_movement = /datum/ai_movement/basic_avoidance
+ idle_behavior = /datum/idle_behavior/idle_random_walk
+ planning_subtrees = list(
+ /datum/ai_planning_subtree/simple_find_target,
+ /datum/ai_planning_subtree/targeted_mob_ability,
+ /datum/ai_planning_subtree/attack_obstacle_in_path,
+ /datum/ai_planning_subtree/basic_melee_attack_subtree,
+ )
diff --git a/code/modules/mob/living/basic/lavaland/watcher/watcher_gaze.dm b/code/modules/mob/living/basic/lavaland/watcher/watcher_gaze.dm
index 9426db41cca..4b322c220ed 100644
--- a/code/modules/mob/living/basic/lavaland/watcher/watcher_gaze.dm
+++ b/code/modules/mob/living/basic/lavaland/watcher/watcher_gaze.dm
@@ -12,6 +12,7 @@
check_flags = AB_CHECK_CONSCIOUS | AB_CHECK_INCAPACITATED
click_to_activate = FALSE
shared_cooldown = NONE
+ melee_cooldown_time = 0 SECONDS
/// At what range do we check for vision?
var/effect_radius = 7
/// How long does it take to play our various animation stages
diff --git a/code/modules/mob/living/basic/space_fauna/regal_rat/regal_rat_actions.dm b/code/modules/mob/living/basic/space_fauna/regal_rat/regal_rat_actions.dm
index 7a30f88b4c2..e617ae0a670 100644
--- a/code/modules/mob/living/basic/space_fauna/regal_rat/regal_rat_actions.dm
+++ b/code/modules/mob/living/basic/space_fauna/regal_rat/regal_rat_actions.dm
@@ -221,31 +221,31 @@
taste_description = "something funny"
overdose_threshold = 20
-/datum/reagent/rat_spit/on_mob_metabolize(mob/living/L)
- ..()
- if(HAS_TRAIT(L, TRAIT_AGEUSIA))
+/datum/reagent/rat_spit/on_mob_metabolize(mob/living/affected_mob)
+ . = ..()
+ if(HAS_TRAIT(affected_mob, TRAIT_AGEUSIA))
return
- to_chat(L, span_notice("This food has a funny taste!"))
+ to_chat(affected_mob, span_notice("This food has a funny taste!"))
-/datum/reagent/rat_spit/overdose_start(mob/living/M)
- ..()
- var/mob/living/carbon/victim = M
+/datum/reagent/rat_spit/overdose_start(mob/living/affected_mob)
+ . = ..()
+ var/mob/living/carbon/victim = affected_mob
if (istype(victim) && !(FACTION_RAT in victim.faction))
to_chat(victim, span_userdanger("With this last sip, you feel your body convulsing horribly from the contents you've ingested. As you contemplate your actions, you sense an awakened kinship with rat-kind and their newly risen leader!"))
victim.faction |= FACTION_RAT
victim.vomit(VOMIT_CATEGORY_DEFAULT)
metabolization_rate = 10 * REAGENTS_METABOLISM
-/datum/reagent/rat_spit/on_mob_life(mob/living/carbon/C)
+/datum/reagent/rat_spit/on_mob_life(mob/living/carbon/affected_mob)
+ . = ..()
if(prob(15))
- to_chat(C, span_notice("You feel queasy!"))
- C.adjust_disgust(3)
+ to_chat(affected_mob, span_notice("You feel queasy!"))
+ affected_mob.adjust_disgust(3)
else if(prob(10))
- to_chat(C, span_warning("That food does not sit up well!"))
- C.adjust_disgust(5)
+ to_chat(affected_mob, span_warning("That food does not sit up well!"))
+ affected_mob.adjust_disgust(5)
else if(prob(5))
- C.vomit(VOMIT_CATEGORY_DEFAULT)
- return ..()
+ affected_mob.vomit(VOMIT_CATEGORY_DEFAULT)
/datum/pet_command/protect_owner/glockroach
protect_behavior = /datum/ai_behavior/basic_ranged_attack/glockroach
diff --git a/code/modules/mob/living/brain/brain_item.dm b/code/modules/mob/living/brain/brain_item.dm
index 10cff8c19ac..9918a21b4f6 100644
--- a/code/modules/mob/living/brain/brain_item.dm
+++ b/code/modules/mob/living/brain/brain_item.dm
@@ -552,7 +552,7 @@
/obj/item/organ/internal/brain/apply_organ_damage(damage_amount, maximum = maxHealth, required_organ_flag = NONE)
. = ..()
if(!owner)
- return
+ return FALSE
if(damage >= 60)
owner.add_mood_event("brain_damage", /datum/mood_event/brain_damage)
else
diff --git a/code/modules/mob/living/carbon/alien/damage_procs.dm b/code/modules/mob/living/carbon/alien/damage_procs.dm
index 8861a55d993..5dbffda9673 100644
--- a/code/modules/mob/living/carbon/alien/damage_procs.dm
+++ b/code/modules/mob/living/carbon/alien/damage_procs.dm
@@ -11,5 +11,5 @@
return FALSE
///aliens are immune to stamina damage.
-/mob/living/carbon/alien/setStaminaLoss(amount, updating_stamina = 1)
+/mob/living/carbon/alien/setStaminaLoss(amount, updating_stamina = 1, forced = FALSE, required_biotype)
return FALSE
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index de77200f940..ebb7a70183f 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -467,17 +467,18 @@
playsound(get_turf(src), 'sound/effects/splat.ogg', 50, TRUE)
+ var/need_mob_update = FALSE
var/turf/location = get_turf(src)
if(!blood)
adjust_nutrition(-lost_nutrition)
- adjustToxLoss(-3)
+ need_mob_update += adjustToxLoss(-3, updating_health = FALSE)
for(var/i = 0 to distance)
if(blood)
if(location)
add_splatter_floor(location)
if(vomit_flags & MOB_VOMIT_HARM)
- adjustBruteLoss(3)
+ need_mob_update += adjustBruteLoss(3, updating_health = FALSE)
else
if(location)
location.add_vomit_floor(src, vomit_type, vomit_flags, purge_ratio) // call purge when doing detoxicfication to pump more chems out of the stomach.
@@ -485,6 +486,8 @@
location = get_step(location, starting_dir)
if (location?.is_blocked_turf())
break
+ if(need_mob_update) // so we only have to call updatehealth() once as opposed to n times
+ updatehealth()
return TRUE
diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm
index 789a459b492..8cb32613da8 100644
--- a/code/modules/mob/living/carbon/carbon_defense.dm
+++ b/code/modules/mob/living/carbon/carbon_defense.dm
@@ -768,7 +768,7 @@
amount = min(amount, 0) //Prevents oxy damage but not healing
. = ..()
- check_passout(.)
+ check_passout()
/mob/living/carbon/proc/get_interaction_efficiency(zone)
var/obj/item/bodypart/limb = get_bodypart(zone)
@@ -777,12 +777,12 @@
/mob/living/carbon/setOxyLoss(amount, updating_health = TRUE, forced, required_biotype, required_respiration_type)
. = ..()
- check_passout(.)
+ check_passout()
/**
* Check to see if we should be passed out from oyxloss
*/
-/mob/living/carbon/proc/check_passout(oxyloss)
+/mob/living/carbon/proc/check_passout()
if(!isnum(oxyloss))
return
if(oxyloss <= 50)
diff --git a/code/modules/mob/living/carbon/damage_procs.dm b/code/modules/mob/living/carbon/damage_procs.dm
index 6e0c7cef867..963f064286b 100644
--- a/code/modules/mob/living/carbon/damage_procs.dm
+++ b/code/modules/mob/living/carbon/damage_procs.dm
@@ -59,37 +59,41 @@
if(!forced && (status_flags & GODMODE))
return FALSE
if(amount > 0)
- take_overall_damage(brute = amount, updating_health = updating_health, required_bodytype = required_bodytype)
+ . = take_overall_damage(brute = amount, updating_health = updating_health, forced = forced, required_bodytype = required_bodytype)
else
- heal_overall_damage(brute = abs(amount), required_bodytype = required_bodytype, updating_health = updating_health)
- return amount
+ . = heal_overall_damage(brute = abs(amount), required_bodytype = required_bodytype, updating_health = updating_health, forced = forced)
/mob/living/carbon/setBruteLoss(amount, updating_health = TRUE, forced = FALSE, required_bodytype)
+ if(!forced && (status_flags & GODMODE))
+ return FALSE
var/current = getBruteLoss()
var/diff = amount - current
if(!diff)
- return
- adjustBruteLoss(diff, updating_health, forced, required_bodytype)
+ return FALSE
+ return adjustBruteLoss(diff, updating_health, forced, required_bodytype)
/mob/living/carbon/adjustFireLoss(amount, updating_health = TRUE, forced = FALSE, required_bodytype)
if(!forced && (status_flags & GODMODE))
return FALSE
if(amount > 0)
- take_overall_damage(burn = amount, updating_health = updating_health, required_bodytype = required_bodytype)
+ . = take_overall_damage(burn = amount, updating_health = updating_health, forced = forced, required_bodytype = required_bodytype)
else
- heal_overall_damage(burn = abs(amount), required_bodytype = required_bodytype, updating_health = updating_health)
- return amount
+ . = heal_overall_damage(burn = abs(amount), required_bodytype = required_bodytype, updating_health = updating_health, forced = forced)
/mob/living/carbon/setFireLoss(amount, updating_health = TRUE, forced = FALSE, required_bodytype)
+ if(!forced && (status_flags & GODMODE))
+ return FALSE
var/current = getFireLoss()
var/diff = amount - current
if(!diff)
- return
- adjustFireLoss(diff, updating_health, forced, required_bodytype)
+ return FALSE
+ return adjustFireLoss(diff, updating_health, forced, required_bodytype)
-/mob/living/carbon/adjustToxLoss(amount, updating_health = TRUE, forced = FALSE, required_biotype = MOB_ORGANIC)
+/mob/living/carbon/adjustToxLoss(amount, updating_health = TRUE, forced = FALSE, required_biotype = ALL)
+ if(!forced && (status_flags & GODMODE))
+ return FALSE
if(!forced && !(mob_biotypes & required_biotype))
- return
+ return FALSE
if(!forced && HAS_TRAIT(src, TRAIT_TOXINLOVER)) //damage becomes healing and healing becomes damage
amount = -amount
if(HAS_TRAIT(src, TRAIT_TOXIMMUNE)) //Prevents toxin damage, but not healing
@@ -98,11 +102,11 @@
blood_volume = max(blood_volume - (5*amount), 0)
else
blood_volume = max(blood_volume - amount, 0)
- else if(HAS_TRAIT(src, TRAIT_TOXIMMUNE)) //Prevents toxin damage, but not healing
+ else if(!forced && HAS_TRAIT(src, TRAIT_TOXIMMUNE)) //Prevents toxin damage, but not healing
amount = min(amount, 0)
return ..()
-/mob/living/carbon/adjustStaminaLoss(amount, updating_stamina, forced, required_biotype)
+/mob/living/carbon/adjustStaminaLoss(amount, updating_stamina, forced, required_biotype = ALL)
. = ..()
if(amount > 0)
stam_regen_start_time = world.time + STAMINA_REGEN_BLOCK_TIME
@@ -115,14 +119,16 @@
* * amount - damage to be done
* * maximum - currently an arbitrarily large number, can be set so as to limit damage
* * required_organ_flag - targets only a specific organ type if set to ORGAN_ORGANIC or ORGAN_ROBOTIC
+ *
+ * Returns: The net change in damage from apply_organ_damage()
*/
/mob/living/carbon/adjustOrganLoss(slot, amount, maximum, required_organ_flag = NONE)
var/obj/item/organ/affected_organ = get_organ_slot(slot)
if(!affected_organ || (status_flags & GODMODE))
- return
+ return FALSE
if(required_organ_flag && !(affected_organ.organ_flags & required_organ_flag))
- return
- affected_organ.apply_organ_damage(amount, maximum)
+ return FALSE
+ return affected_organ.apply_organ_damage(amount, maximum)
/**
* If an organ exists in the slot requested, and we are capable of taking damage (we don't have [GODMODE] on), call the set damage proc on that organ, which can
@@ -132,16 +138,18 @@
* * slot - organ slot, like [ORGAN_SLOT_HEART]
* * amount - damage to be set to
* * required_organ_flag - targets only a specific organ type if set to ORGAN_ORGANIC or ORGAN_ROBOTIC
+ *
+ * Returns: The net change in damage from set_organ_damage()
*/
/mob/living/carbon/setOrganLoss(slot, amount, required_organ_flag = NONE)
var/obj/item/organ/affected_organ = get_organ_slot(slot)
if(!affected_organ || (status_flags & GODMODE))
- return
+ return FALSE
if(required_organ_flag && !(affected_organ.organ_flags & required_organ_flag))
- return
+ return FALSE
if(affected_organ.damage == amount)
- return
- affected_organ.set_organ_damage(amount)
+ return FALSE
+ return affected_organ.set_organ_damage(amount)
/**
* If an organ exists in the slot requested, return the amount of damage that organ has
@@ -200,14 +208,16 @@
* It automatically updates health status
*/
/mob/living/carbon/heal_bodypart_damage(brute = 0, burn = 0, updating_health = TRUE, required_bodytype = NONE, target_zone = null)
+ . = FALSE
var/list/obj/item/bodypart/parts = get_damaged_bodyparts(brute, burn, required_bodytype, target_zone)
if(!parts.len)
return
+
var/obj/item/bodypart/picked = pick(parts)
- var/damage_calculator = picked.get_damage(TRUE) //heal_damage returns update status T/F instead of amount healed so we dance gracefully around this
- if(picked.heal_damage(brute, burn, required_bodytype))
+ var/damage_calculator = picked.get_damage() //heal_damage returns update status T/F instead of amount healed so we dance gracefully around this
+ if(picked.heal_damage(abs(brute), abs(burn), required_bodytype = required_bodytype))
update_damage_overlays()
- return max(damage_calculator - picked.get_damage(TRUE), 0)
+ return (damage_calculator - picked.get_damage())
/**
@@ -218,15 +228,25 @@
* It automatically updates health status
*/
/mob/living/carbon/take_bodypart_damage(brute = 0, burn = 0, updating_health = TRUE, required_bodytype, check_armor = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = NONE)
+ . = FALSE
+ if(status_flags & GODMODE)
+ return
var/list/obj/item/bodypart/parts = get_damageable_bodyparts(required_bodytype)
if(!parts.len)
return
+
var/obj/item/bodypart/picked = pick(parts)
- if(picked.receive_damage(brute, burn, check_armor ? run_armor_check(picked, (brute ? MELEE : burn ? FIRE : null)) : FALSE, wound_bonus = wound_bonus, bare_wound_bonus = bare_wound_bonus, sharpness = sharpness))
+ var/damage_calculator = picked.get_damage()
+ if(picked.receive_damage(abs(brute), abs(burn), check_armor ? run_armor_check(picked, (brute ? MELEE : burn ? FIRE : null)) : FALSE, wound_bonus = wound_bonus, bare_wound_bonus = bare_wound_bonus, sharpness = sharpness))
update_damage_overlays()
+ return (damage_calculator - picked.get_damage())
+
+/mob/living/carbon/heal_overall_damage(brute = 0, burn = 0, stamina = 0, required_bodytype, updating_health = TRUE, forced = FALSE)
+ . = FALSE
+ // treat negative args as positive
+ brute = abs(brute)
+ burn = abs(burn)
-///Heal MANY bodyparts, in random order
-/mob/living/carbon/heal_overall_damage(brute = 0, burn = 0, stamina = 0, required_bodytype, updating_health = TRUE)
var/list/obj/item/bodypart/parts = get_damaged_bodyparts(brute, burn, required_bodytype)
var/update = NONE
@@ -235,25 +255,35 @@
var/brute_was = picked.brute_dam
var/burn_was = picked.burn_dam
+ . += picked.get_damage()
+
+ update |= picked.heal_damage(brute, burn, updating_health = FALSE, forced = forced, required_bodytype = required_bodytype)
- update |= picked.heal_damage(brute, burn, required_bodytype, FALSE)
+ . -= picked.get_damage() // return the net amount of damage healed
brute = round(brute - (brute_was - picked.brute_dam), DAMAGE_PRECISION)
burn = round(burn - (burn_was - picked.burn_dam), DAMAGE_PRECISION)
parts -= picked
+
+ if(!.) // no change? no need to update anything
+ return
+
if(updating_health)
updatehealth()
if(update)
update_damage_overlays()
-/// damage MANY bodyparts, in random order
-/mob/living/carbon/take_overall_damage(brute = 0, burn = 0, stamina = 0, updating_health = TRUE, required_bodytype)
- if(status_flags & GODMODE)
- return //godmode
+/mob/living/carbon/take_overall_damage(brute = 0, burn = 0, stamina = 0, updating_health = TRUE, forced = FALSE, required_bodytype)
+ . = FALSE
+ if(!forced && (status_flags & GODMODE))
+ return
+ // treat negative args as positive
+ brute = abs(brute)
+ burn = abs(burn)
var/list/obj/item/bodypart/parts = get_damageable_bodyparts(required_bodytype)
- var/update = 0
+ var/update = NONE
while(parts.len && (brute > 0 || burn > 0))
var/obj/item/bodypart/picked = pick(parts)
var/brute_per_part = round(brute/parts.len, DAMAGE_PRECISION)
@@ -261,14 +291,21 @@
var/brute_was = picked.brute_dam
var/burn_was = picked.burn_dam
+ . += picked.get_damage()
+ // disabling wounds from these for now cuz your entire body snapping cause your heart stopped would suck
+ update |= picked.receive_damage(brute_per_part, burn_per_part, blocked = FALSE, updating_health = FALSE, forced = forced, required_bodytype = required_bodytype, wound_bonus = CANT_WOUND)
- update |= picked.receive_damage(brute_per_part, burn_per_part, FALSE, updating_health, required_bodytype, wound_bonus = CANT_WOUND) // disabling wounds from these for now cuz your entire body snapping cause your heart stopped would suck
+ . -= picked.get_damage() // return the net amount of damage healed
brute = round(brute - (picked.brute_dam - brute_was), DAMAGE_PRECISION)
burn = round(burn - (picked.burn_dam - burn_was), DAMAGE_PRECISION)
parts -= picked
+
+ if(!.) // no change? no need to update anything
+ return
+
if(updating_health)
updatehealth()
if(update)
diff --git a/code/modules/mob/living/carbon/human/_species.dm b/code/modules/mob/living/carbon/human/_species.dm
index 6a8fc967cb5..4fbd3062351 100644
--- a/code/modules/mob/living/carbon/human/_species.dm
+++ b/code/modules/mob/living/carbon/human/_species.dm
@@ -1456,7 +1456,7 @@ GLOBAL_LIST_EMPTY(features_by_species)
var/damage_amount = forced ? damage : damage * hit_percent * H.physiology.brain_mod
H.adjustOrganLoss(ORGAN_SLOT_BRAIN, damage_amount)
SEND_SIGNAL(H, COMSIG_MOB_AFTER_APPLY_DAMAGE, damage, damagetype, def_zone, blocked, wound_bonus, bare_wound_bonus, sharpness, attack_direction, attacking_item)
- return 1
+ return TRUE
/datum/species/proc/on_hit(obj/projectile/P, mob/living/carbon/human/H)
// called when hit by a projectile
diff --git a/code/modules/mob/living/carbon/human/human_update_icons.dm b/code/modules/mob/living/carbon/human/human_update_icons.dm
index bb112144447..d1ecdfaa7aa 100644
--- a/code/modules/mob/living/carbon/human/human_update_icons.dm
+++ b/code/modules/mob/living/carbon/human/human_update_icons.dm
@@ -87,7 +87,6 @@ There are several things that need to be remembered:
if(check_obscured_slots(transparent_protection = TRUE) & ITEM_SLOT_ICLOTHING)
return
-
var/target_overlay = uniform.icon_state
if(uniform.adjusted == ALT_STYLE)
target_overlay = "[target_overlay]_d"
@@ -102,19 +101,29 @@ There are several things that need to be remembered:
var/handled_by_bodytype = TRUE
var/icon_file
var/woman
+ var/digi // SKYRAT EDIT ADDITION - Digi female gender shaping
+ var/female_sprite_flags = uniform.female_sprite_flags // SKYRAT EDIT ADDITION - Digi female gender shaping
var/mutant_styles = NONE // SKYRAT EDIT ADDITON - mutant styles to pass down to build_worn_icon.
//BEGIN SPECIES HANDLING
if((bodytype & BODYTYPE_MONKEY) && (uniform.supports_variations_flags & CLOTHING_MONKEY_VARIATION))
- icon_file = dna.species.generate_custom_worn_icon(LOADOUT_ITEM_UNIFORM, w_uniform, src) // SKYRAT EDIT CHANGE
+ icon_file = dna.species.generate_custom_worn_icon(LOADOUT_ITEM_UNIFORM, w_uniform, src) // SKYRAT EDIT CHANGE - ORIGINAL: icon_file = MONKEY_UNIFORM_FILE
else if((bodytype & BODYTYPE_DIGITIGRADE) && (uniform.supports_variations_flags & CLOTHING_DIGITIGRADE_VARIATION))
- icon_file = uniform.worn_icon_digi || DIGITIGRADE_UNIFORM_FILE // SKYRAT EDIT CHANGE
+ icon_file = uniform.worn_icon_digi || DIGITIGRADE_UNIFORM_FILE // SKYRAT EDIT CHANGE - ORIGINAL: icon_file = DIGITIGRADE_UNIFORM_FILE
+ digi = TRUE // SKYRAT EDIT ADDITION - Digi female gender shaping
// SKYRAT EDIT ADDITION - birbs
else if(bodytype & BODYTYPE_CUSTOM)
icon_file = dna.species.generate_custom_worn_icon(LOADOUT_ITEM_UNIFORM, w_uniform, src) // Might have to refactor how this works eventually, maybe.
// SKYRAT EDIT END
//Female sprites have lower priority than digitigrade sprites
- else if(dna.species.sexes && (bodytype & BODYTYPE_HUMANOID) && physique == FEMALE && !(uniform.female_sprite_flags & NO_FEMALE_UNIFORM)) //Agggggggghhhhh
+ if(dna.species.sexes && (bodytype & BODYTYPE_HUMANOID) && physique == FEMALE && !(female_sprite_flags & NO_FEMALE_UNIFORM)) //Agggggggghhhhh // SKYRAT EDIT CHANGE - ORIGINAL: else if(dna.species.sexes && (bodytype & BODYTYPE_HUMANOID) && physique == FEMALE && !(uniform.female_sprite_flags & NO_FEMALE_UNIFORM))
woman = TRUE
+ // SKYRAT EDIT ADDITION START - Digi female gender shaping
+ if(digi)
+ mutant_styles |= STYLE_DIGI // for passing to wear_female_version
+ if(!(female_sprite_flags & FEMALE_UNIFORM_DIGI_FULL))
+ female_sprite_flags &= ~FEMALE_UNIFORM_FULL // clear the FEMALE_UNIFORM_DIGI_FULL bit if it was set, we don't want that.
+ female_sprite_flags |= FEMALE_UNIFORM_TOP_ONLY // And set the FEMALE_UNIFORM_TOP bit if it is unset.
+ // SKYRAT EDIT ADDITION END
if(!icon_exists(icon_file, RESOLVE_ICON_STATE(uniform)))
icon_file = DEFAULT_UNIFORM_FILE
@@ -131,7 +140,7 @@ There are several things that need to be remembered:
default_layer = UNIFORM_LAYER,
default_icon_file = icon_file,
isinhands = FALSE,
- female_uniform = woman ? uniform.female_sprite_flags : null,
+ female_uniform = woman ? female_sprite_flags : null, // SKYRAT EDIT CHANGE - Digi female gender shaping - ORIGINAL: female_uniform = woman ? uniform.female_sprite_flags : null,
override_state = target_overlay,
override_file = handled_by_bodytype ? icon_file : null,
mutant_styles = mutant_styles, // SKYRAT EDIT ADDITION - Taur-friendly uniforms!
@@ -157,7 +166,9 @@ There are several things that need to be remembered:
var/obj/item/worn_item = wear_id
update_hud_id(worn_item)
var/icon_file = 'icons/mob/clothing/id.dmi'
+
id_overlay = wear_id.build_worn_icon(default_layer = ID_LAYER, default_icon_file = icon_file)
+
if(!id_overlay)
return
@@ -167,6 +178,7 @@ There are several things that need to be remembered:
apply_overlay(ID_LAYER)
+
/mob/living/carbon/human/update_worn_gloves()
remove_overlay(GLOVES_LAYER)
@@ -681,8 +693,8 @@ There are several things that need to be remembered:
overlays_standing[HANDS_LAYER] = hands
apply_overlay(HANDS_LAYER)
-/proc/wear_female_version(t_color, icon, layer, type, greyscale_colors)
- var/index = "[t_color]-[greyscale_colors]"
+/proc/wear_female_version(t_color, icon, layer, type, greyscale_colors, mutant_styles) // SKYRAT EDIT CHANGE - Digi female gender shaping - ORIGINAL: /proc/wear_female_version(t_color, icon, layer, type, greyscale_colors)
+ var/index = "[t_color]-[greyscale_colors][(mutant_styles & STYLE_DIGI) ? "-d" : ""]" // SKYRAT EDIT CHANGE - Digi female gender shaping - Original: var/index = "[t_color]-[greyscale_colors]]"
var/icon/female_clothing_icon = GLOB.female_clothing_icons[index]
if(!female_clothing_icon) //Create standing/laying icons if they don't exist
generate_female_clothing(index, t_color, icon, type)
@@ -834,7 +846,7 @@ mutant_styles: The mutant style - taur bodytype, STYLE_TESHARI, etc. // SKYRAT E
var/mutable_appearance/standing
if(female_uniform)
- standing = wear_female_version(t_state, file2use, layer2use, female_uniform, greyscale_colors) //should layer2use be in sync with the adjusted value below? needs testing - shiz
+ standing = wear_female_version(t_state, file2use, layer2use, female_uniform, greyscale_colors, mutant_styles) //should layer2use be in sync with the adjusted value below? needs testing - shiz // SKYRAT EDIT CHANGE - ORIGINAL: standing = wear_female_version(t_state, file2use, layer2use, female_uniform, greyscale_colors)
if(!standing)
standing = mutable_appearance(file2use, t_state, -layer2use)
// SKYRAT EDIT ADDITION START - Taur-friendly uniforms and suits
@@ -879,7 +891,6 @@ mutant_styles: The mutant style - taur bodytype, STYLE_TESHARI, etc. // SKYRAT E
return standing
-
/// Returns offsets used for equipped item overlays in list(px_offset,py_offset) form.
/obj/item/proc/get_worn_offsets(isinhands)
. = list(0,0) //(px,py)
diff --git a/code/modules/mob/living/carbon/human/species_types/mothmen.dm b/code/modules/mob/living/carbon/human/species_types/mothmen.dm
index 9f576e03f07..050e79b70bf 100644
--- a/code/modules/mob/living/carbon/human/species_types/mothmen.dm
+++ b/code/modules/mob/living/carbon/human/species_types/mothmen.dm
@@ -16,6 +16,7 @@
mutanteyes = /obj/item/organ/internal/eyes/moth
changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_MAGIC | MIRROR_PRIDE | ERT_SPAWN | RACE_SWAP | SLIME_EXTRACT
species_language_holder = /datum/language_holder/moth
+ death_sound = 'sound/voice/moth/moth_death.ogg'
wing_types = list(/obj/item/organ/external/wings/functional/moth/megamoth, /obj/item/organ/external/wings/functional/moth/mothra)
payday_modifier = 1.0
family_heirlooms = list(/obj/item/flashlight/lantern/heirloom_moth)
diff --git a/code/modules/mob/living/carbon/human/species_types/podpeople.dm b/code/modules/mob/living/carbon/human/species_types/podpeople.dm
index 3703f2527ac..bab1bae6e36 100644
--- a/code/modules/mob/living/carbon/human/species_types/podpeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/podpeople.dm
@@ -43,26 +43,29 @@
)
return ..()
-/datum/species/pod/spec_life(mob/living/carbon/human/H, seconds_per_tick, times_fired)
+/datum/species/pod/spec_life(mob/living/carbon/human/podperson, seconds_per_tick, times_fired)
. = ..()
- if(H.stat == DEAD)
+ if(podperson.stat == DEAD)
return
var/light_amount = 0 //how much light there is in the place, affects receiving nutrition and healing
- if(isturf(H.loc)) //else, there's considered to be no light
- var/turf/T = H.loc
- light_amount = min(1, T.get_lumcount()) - 0.5
- H.adjust_nutrition(5 * light_amount * seconds_per_tick)
+ if(isturf(podperson.loc)) //else, there's considered to be no light
+ var/turf/turf_loc = podperson.loc
+ light_amount = min(1, turf_loc.get_lumcount()) - 0.5
+ podperson.adjust_nutrition(5 * light_amount * seconds_per_tick)
if(light_amount > 0.2) //if there's enough light, heal
- H.heal_overall_damage(brute = 0.5 * seconds_per_tick, burn = 0.5 * seconds_per_tick, required_bodytype = BODYTYPE_ORGANIC)
- H.adjustToxLoss(-0.5 * seconds_per_tick)
- H.adjustOxyLoss(-0.5 * seconds_per_tick)
-
- if(H.nutrition > NUTRITION_LEVEL_ALMOST_FULL) //don't make podpeople fat because they stood in the sun for too long
- H.set_nutrition(NUTRITION_LEVEL_ALMOST_FULL)
-
- if(H.nutrition < NUTRITION_LEVEL_STARVING + 50)
- H.take_overall_damage(brute = 1 * seconds_per_tick, required_bodytype = BODYTYPE_ORGANIC)
+ var/need_mob_update = FALSE
+ need_mob_update += podperson.heal_overall_damage(brute = 0.5 * seconds_per_tick, burn = 0.5 * seconds_per_tick, updating_health = FALSE, required_bodytype = BODYTYPE_ORGANIC)
+ need_mob_update += podperson.adjustToxLoss(-0.5 * seconds_per_tick, updating_health = FALSE)
+ need_mob_update += podperson.adjustOxyLoss(-0.5 * seconds_per_tick, updating_health = FALSE)
+ if(need_mob_update)
+ podperson.updatehealth()
+
+ if(podperson.nutrition > NUTRITION_LEVEL_ALMOST_FULL) //don't make podpeople fat because they stood in the sun for too long
+ podperson.set_nutrition(NUTRITION_LEVEL_ALMOST_FULL)
+
+ if(podperson.nutrition < NUTRITION_LEVEL_STARVING + 50)
+ podperson.take_overall_damage(brute = 1 * seconds_per_tick, required_bodytype = BODYTYPE_ORGANIC)
/datum/species/pod/handle_chemical(datum/reagent/chem, mob/living/carbon/human/affected, seconds_per_tick, times_fired)
. = ..()
diff --git a/code/modules/mob/living/carbon/human/species_types/vampire.dm b/code/modules/mob/living/carbon/human/species_types/vampire.dm
index d24e5f3d272..46d507e4999 100644
--- a/code/modules/mob/living/carbon/human/species_types/vampire.dm
+++ b/code/modules/mob/living/carbon/human/species_types/vampire.dm
@@ -44,10 +44,13 @@
/datum/species/vampire/spec_life(mob/living/carbon/human/vampire, seconds_per_tick, times_fired)
. = ..()
if(istype(vampire.loc, /obj/structure/closet/crate/coffin))
- vampire.heal_overall_damage(brute = 2 * seconds_per_tick, burn = 2 * seconds_per_tick, required_bodytype = BODYTYPE_ORGANIC)
- vampire.adjustToxLoss(-2 * seconds_per_tick)
- vampire.adjustOxyLoss(-2 * seconds_per_tick)
- vampire.adjustCloneLoss(-2 * seconds_per_tick)
+ var/need_mob_update = FALSE
+ need_mob_update += vampire.heal_overall_damage(brute = 2 * seconds_per_tick, burn = 2 * seconds_per_tick, updating_health = FALSE, required_bodytype = BODYTYPE_ORGANIC)
+ need_mob_update += vampire.adjustToxLoss(-2 * seconds_per_tick, updating_health = FALSE,)
+ need_mob_update += vampire.adjustOxyLoss(-2 * seconds_per_tick, updating_health = FALSE,)
+ need_mob_update += vampire.adjustCloneLoss(-2 * seconds_per_tick, updating_health = FALSE,)
+ if(need_mob_update)
+ vampire.updatehealth()
return
vampire.blood_volume -= 0.125 * seconds_per_tick
if(vampire.blood_volume <= BLOOD_VOLUME_SURVIVE)
diff --git a/code/modules/mob/living/carbon/human/species_types/zombies.dm b/code/modules/mob/living/carbon/human/species_types/zombies.dm
index d8b2125aa64..273d7c83422 100644
--- a/code/modules/mob/living/carbon/human/species_types/zombies.dm
+++ b/code/modules/mob/living/carbon/human/species_types/zombies.dm
@@ -151,24 +151,27 @@
if(.)
COOLDOWN_START(src, regen_cooldown, REGENERATION_DELAY)
-/datum/species/zombie/infectious/spec_life(mob/living/carbon/C, seconds_per_tick, times_fired)
+/datum/species/zombie/infectious/spec_life(mob/living/carbon/carbon_mob, seconds_per_tick, times_fired)
. = ..()
- C.set_combat_mode(TRUE) // THE SUFFERING MUST FLOW
+ carbon_mob.set_combat_mode(TRUE) // THE SUFFERING MUST FLOW
//Zombies never actually die, they just fall down until they regenerate enough to rise back up.
//They must be restrained, beheaded or gibbed to stop being a threat.
if(COOLDOWN_FINISHED(src, regen_cooldown))
var/heal_amt = heal_rate
- if(HAS_TRAIT(C, TRAIT_CRITICAL_CONDITION))
+ if(HAS_TRAIT(carbon_mob, TRAIT_CRITICAL_CONDITION))
heal_amt *= 2
- C.heal_overall_damage(heal_amt * seconds_per_tick, heal_amt * seconds_per_tick)
- C.adjustToxLoss(-heal_amt * seconds_per_tick)
- for(var/i in C.all_wounds)
+ var/need_mob_update = FALSE
+ need_mob_update += carbon_mob.heal_overall_damage(heal_amt * seconds_per_tick, heal_amt * seconds_per_tick, updating_health = FALSE)
+ need_mob_update += carbon_mob.adjustToxLoss(-heal_amt * seconds_per_tick, updating_health = FALSE)
+ if(need_mob_update)
+ carbon_mob.updatehealth()
+ for(var/i in carbon_mob.all_wounds)
var/datum/wound/iter_wound = i
if(SPT_PROB(2-(iter_wound.severity/2), seconds_per_tick))
iter_wound.remove_wound()
- if(!HAS_TRAIT(C, TRAIT_CRITICAL_CONDITION) && SPT_PROB(2, seconds_per_tick))
- playsound(C, pick(spooks), 50, TRUE, 10)
+ if(!HAS_TRAIT(carbon_mob, TRAIT_CRITICAL_CONDITION) && SPT_PROB(2, seconds_per_tick))
+ playsound(carbon_mob, pick(spooks), 50, TRUE, 10)
//Congrats you somehow died so hard you stopped being a zombie
/datum/species/zombie/infectious/spec_death(gibbed, mob/living/carbon/C)
diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm
index 990f27f0707..44ffab1196e 100644
--- a/code/modules/mob/living/carbon/life.dm
+++ b/code/modules/mob/living/carbon/life.dm
@@ -37,9 +37,8 @@
if(getStaminaLoss() > 0 && stam_regen_start_time <= world.time)
adjustStaminaLoss(-INFINITY)
- var/bprv = handle_bodyparts(seconds_per_tick, times_fired)
- if(bprv & BODYPART_LIFE_UPDATE_HEALTH)
- updatehealth()
+
+ handle_bodyparts(seconds_per_tick, times_fired)
if(. && mind) //. == not dead
for(var/key in mind.addiction_points)
@@ -410,10 +409,13 @@
//-- NITRIUM --//
if(nitrium_pp)
+ var/need_mob_update = FALSE
if(nitrium_pp > 0.5)
- adjustFireLoss(nitrium_pp * 0.15)
+ need_mob_update += adjustFireLoss(nitrium_pp * 0.15, updating_health = FALSE)
if(nitrium_pp > 5)
- adjustToxLoss(nitrium_pp * 0.05)
+ need_mob_update += adjustToxLoss(nitrium_pp * 0.05, updating_health = FALSE)
+ if(need_mob_update)
+ updatehealth()
// Handle chemical euphoria mood event, caused by N2O.
if (n2o_euphoria == EUPHORIA_ACTIVE)
@@ -757,7 +759,7 @@
if(HAS_TRAIT(src, TRAIT_STABLELIVER) || HAS_TRAIT(src, TRAIT_LIVERLESS_METABOLISM))
return
- adjustToxLoss(0.6 * seconds_per_tick, TRUE, TRUE)
+ adjustToxLoss(0.6 * seconds_per_tick, forced = TRUE)
adjustOrganLoss(pick(ORGAN_SLOT_HEART, ORGAN_SLOT_LUNGS, ORGAN_SLOT_STOMACH, ORGAN_SLOT_EYES, ORGAN_SLOT_EARS), 0.5* seconds_per_tick)
/mob/living/carbon/proc/undergoing_liver_failure()
@@ -814,6 +816,7 @@
var/obj/item/organ/internal/heart/heart = get_organ_slot(ORGAN_SLOT_HEART)
if(!istype(heart))
- return
+ return FALSE
heart.beating = !status
+ return TRUE
diff --git a/code/modules/mob/living/damage_procs.dm b/code/modules/mob/living/damage_procs.dm
index dfae5d2baf1..9daab06a5a6 100644
--- a/code/modules/mob/living/damage_procs.dm
+++ b/code/modules/mob/living/damage_procs.dm
@@ -53,7 +53,7 @@
return adjustStaminaLoss(damage)
/// return the damage amount for the type given
-/mob/living/proc/get_damage_amount(damagetype = BRUTE)
+/mob/living/proc/get_current_damage_of_type(damagetype = BRUTE)
switch(damagetype)
if(BRUTE)
return getBruteLoss()
@@ -163,132 +163,157 @@
/mob/living/proc/getBruteLoss()
return bruteloss
-/mob/living/proc/adjustBruteLoss(amount, updating_health = TRUE, forced = FALSE, required_bodytype)
- SEND_SIGNAL(src, COMSIG_MOB_LOSS_BRUTE, amount) //SKYRAT EDIT ADDITION
+/mob/living/proc/adjustBruteLoss(amount, updating_health = TRUE, forced = FALSE, required_bodytype = ALL)
if(!forced && (status_flags & GODMODE))
return FALSE
+ . = bruteloss
bruteloss = clamp((bruteloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2)
+ . -= bruteloss
+ if(!.) // no change, no need to update
+ return FALSE
if(updating_health)
updatehealth()
- return amount
-/mob/living/proc/setBruteLoss(amount, updating_health = TRUE, forced = FALSE, required_bodytype)
+
+/mob/living/proc/setBruteLoss(amount, updating_health = TRUE, forced = FALSE, required_bodytype = ALL)
if(!forced && (status_flags & GODMODE))
- return
+ return FALSE
. = bruteloss
bruteloss = amount
+
+ if(!.) // no change, no need to update
+ return FALSE
if(updating_health)
updatehealth()
+ . -= bruteloss
/mob/living/proc/getOxyLoss()
return oxyloss
-/mob/living/proc/adjustOxyLoss(amount, updating_health = TRUE, forced = FALSE, required_biotype, required_respiration_type = ALL)
-
- SEND_SIGNAL(src, COMSIG_MOB_LOSS_OXY, amount) //SKYRAT EDIT ADDITION
+/mob/living/proc/adjustOxyLoss(amount, updating_health = TRUE, forced = FALSE, required_biotype = ALL, required_respiration_type = ALL)
if(!forced)
if(status_flags & GODMODE)
- return
+ return FALSE
var/obj/item/organ/internal/lungs/affected_lungs = get_organ_slot(ORGAN_SLOT_LUNGS)
if(isnull(affected_lungs))
if(!(mob_respiration_type & required_respiration_type)) // if the mob has no lungs, use mob_respiration_type
- return
+ return FALSE
else
if(!(affected_lungs.respiration_type & required_respiration_type)) // otherwise use the lungs' respiration_type
- return
-
+ return FALSE
. = oxyloss
oxyloss = clamp((oxyloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2)
+ . -= oxyloss
+ if(!.) // no change, no need to update
+ return FALSE
if(updating_health)
updatehealth()
-
-/mob/living/proc/setOxyLoss(amount, updating_health = TRUE, forced = FALSE, required_biotype, required_respiration_type = ALL)
+/mob/living/proc/setOxyLoss(amount, updating_health = TRUE, forced = FALSE, required_biotype = ALL, required_respiration_type = ALL)
if(!forced)
if(status_flags & GODMODE)
- return
+ return FALSE
var/obj/item/organ/internal/lungs/affected_lungs = get_organ_slot(ORGAN_SLOT_LUNGS)
if(isnull(affected_lungs))
if(!(mob_respiration_type & required_respiration_type))
- return
+ return FALSE
else
if(!(affected_lungs.respiration_type & required_respiration_type))
- return
-
+ return FALSE
. = oxyloss
oxyloss = amount
+ . -= oxyloss
+ if(!.) // no change, no need to update
+ return FALSE
if(updating_health)
updatehealth()
-
/mob/living/proc/getToxLoss()
return toxloss
-/mob/living/proc/adjustToxLoss(amount, updating_health = TRUE, forced = FALSE, required_biotype)
- SEND_SIGNAL(src, COMSIG_MOB_LOSS_TOX, amount) //SKYRAT EDIT ADDITION
+/mob/living/proc/adjustToxLoss(amount, updating_health = TRUE, forced = FALSE, required_biotype = ALL)
if(!forced && (status_flags & GODMODE))
return FALSE
if(!forced && !(mob_biotypes & required_biotype))
- return
+ return FALSE
+ . = toxloss
toxloss = clamp((toxloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2)
+ . -= toxloss
+ if(!.) // no change, no need to update
+ return FALSE
if(updating_health)
updatehealth()
- return amount
-/mob/living/proc/setToxLoss(amount, updating_health = TRUE, forced = FALSE, required_biotype)
+/mob/living/proc/setToxLoss(amount, updating_health = TRUE, forced = FALSE, required_biotype = ALL)
if(!forced && (status_flags & GODMODE))
return FALSE
if(!forced && !(mob_biotypes & required_biotype))
- return
+ return FALSE
+ . = toxloss
toxloss = amount
+ . -= toxloss
+ if(!.) // no change, no need to update
+ return FALSE
if(updating_health)
updatehealth()
- return amount
/mob/living/proc/getFireLoss()
return fireloss
-/mob/living/proc/adjustFireLoss(amount, updating_health = TRUE, forced = FALSE, required_bodytype)
- SEND_SIGNAL(src, COMSIG_MOB_LOSS_FIRE, amount) //SKYRAT EDIT ADDITION
+/mob/living/proc/adjustFireLoss(amount, updating_health = TRUE, forced = FALSE, required_bodytype = ALL)
if(!forced && (status_flags & GODMODE))
return FALSE
+ . = fireloss
fireloss = clamp((fireloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2)
+ . -= fireloss
+ if(!.) // no change, no need to update
+ return FALSE
if(updating_health)
updatehealth()
- return amount
-/mob/living/proc/setFireLoss(amount, updating_health = TRUE, forced = FALSE, required_bodytype)
+/mob/living/proc/setFireLoss(amount, updating_health = TRUE, forced = FALSE, required_bodytype = ALL)
if(!forced && (status_flags & GODMODE))
- return
+ return FALSE
. = fireloss
fireloss = amount
+ . -= fireloss
+ if(!.) // no change, no need to update
+ return FALSE
if(updating_health)
updatehealth()
/mob/living/proc/getCloneLoss()
return cloneloss
-/mob/living/proc/adjustCloneLoss(amount, updating_health = TRUE, forced = FALSE, required_biotype)
- SEND_SIGNAL(src, COMSIG_MOB_LOSS_CLONE, amount) //SKYRAT EDIT ADDITION
+/mob/living/proc/adjustCloneLoss(amount, updating_health = TRUE, forced = FALSE, required_biotype = ALL)
if(!forced && ( (status_flags & GODMODE) || HAS_TRAIT(src, TRAIT_NOCLONELOSS)) )
return FALSE
+ if(!forced && !(mob_biotypes & required_biotype))
+ return FALSE
+ . = cloneloss
cloneloss = clamp((cloneloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2)
+ . -= cloneloss
+ if(!.) // no change, no need to update
+ return FALSE
if(updating_health)
updatehealth()
- return amount
-/mob/living/proc/setCloneLoss(amount, updating_health = TRUE, forced = FALSE, required_biotype)
+/mob/living/proc/setCloneLoss(amount, updating_health = TRUE, forced = FALSE, required_biotype = ALL)
if(!forced && ( (status_flags & GODMODE) || HAS_TRAIT(src, TRAIT_NOCLONELOSS)) )
return FALSE
+ if(!forced && !(mob_biotypes & required_biotype))
+ return FALSE
+ . = cloneloss
cloneloss = amount
+ . -= cloneloss
+ if(!.) // no change, no need to update
+ return FALSE
if(updating_health)
updatehealth()
- return amount
/mob/living/proc/adjustOrganLoss(slot, amount, maximum, required_organ_flag)
- SEND_SIGNAL(src, COMSIG_MOB_LOSS_ORGAN, slot, amount) //SKYRAT EDIT ADDITION
return
/mob/living/proc/setOrganLoss(slot, amount, maximum, required_organ_flag)
@@ -300,65 +325,79 @@
/mob/living/proc/getStaminaLoss()
return staminaloss
-/mob/living/proc/adjustStaminaLoss(amount, updating_stamina = TRUE, forced = FALSE, required_biotype)
+/mob/living/proc/adjustStaminaLoss(amount, updating_stamina = TRUE, forced = FALSE, required_biotype = ALL)
if(!forced && (status_flags & GODMODE))
return FALSE
- if(required_biotype && !(mob_biotypes & required_biotype))
- return
+ if(!forced && !(mob_biotypes & required_biotype))
+ return FALSE
+ . = staminaloss
staminaloss = clamp((staminaloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, max_stamina)
+ . -= staminaloss
+ if(!.) // no change, no need to update
+ return FALSE
if(updating_stamina)
updatehealth()
- SEND_SIGNAL(src, COMSIG_MOB_LOSS_STAMINA, amount) //SKYRAT EDIT ADDITION
- return
-/mob/living/proc/setStaminaLoss(amount, updating_stamina = TRUE, forced = FALSE, required_biotype)
- if(!forced && ( (status_flags & GODMODE) || HAS_TRAIT(src, TRAIT_NOCLONELOSS)) )
+/mob/living/proc/setStaminaLoss(amount, updating_stamina = TRUE, forced = FALSE, required_biotype = ALL)
+ if(!forced && (status_flags & GODMODE))
+ return FALSE
+ if(!forced && !(mob_biotypes & required_biotype))
return FALSE
+ . = staminaloss
staminaloss = amount
+ . -= staminaloss
+ if(!.) // no change, no need to update
+ return FALSE
if(updating_stamina)
updatehealth()
/**
* heal ONE external organ, organ gets randomly selected from damaged ones.
*
- * needs to return amount healed in order to calculate things like tend wounds xp gain
+ * returns the net change in damage
*/
/mob/living/proc/heal_bodypart_damage(brute = 0, burn = 0, updating_health = TRUE, required_bodytype = NONE, target_zone = null)
- . = (adjustBruteLoss(-brute, FALSE) + adjustFireLoss(-burn, FALSE)) //zero as argument for no instant health update
+ . = (adjustBruteLoss(-abs(brute), updating_health = FALSE) + adjustFireLoss(-abs(burn), updating_health = FALSE))
+ if(!.) // no change, no need to update
+ return FALSE
if(updating_health)
updatehealth()
/// damage ONE external organ, organ gets randomly selected from damaged ones.
/mob/living/proc/take_bodypart_damage(brute = 0, burn = 0, updating_health = TRUE, required_bodytype, check_armor = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = NONE)
- adjustBruteLoss(brute, FALSE) //zero as argument for no instant health update
- adjustFireLoss(burn, FALSE)
+ . = (adjustBruteLoss(abs(brute), updating_health = FALSE) + adjustFireLoss(abs(burn), updating_health = FALSE))
+ if(!.) // no change, no need to update
+ return FALSE
if(updating_health)
updatehealth()
-/// heal MANY bodyparts, in random order
-/mob/living/proc/heal_overall_damage(brute = 0, burn = 0, stamina = 0, required_bodytype, updating_health = TRUE)
- adjustBruteLoss(-brute, FALSE) //zero as argument for no instant health update
- adjustFireLoss(-burn, FALSE)
- adjustStaminaLoss(-stamina, FALSE)
+/// heal MANY bodyparts, in random order. note: stamina arg nonfunctional for carbon mobs
+/mob/living/proc/heal_overall_damage(brute = 0, burn = 0, stamina = 0, required_bodytype, updating_health = TRUE, forced = FALSE)
+ . = (adjustBruteLoss(-abs(brute), updating_health = FALSE, forced = forced) + \
+ adjustFireLoss(-abs(burn), updating_health = FALSE, forced = forced) + \
+ adjustStaminaLoss(-abs(stamina), updating_stamina = FALSE, forced = forced))
+ if(!.) // no change, no need to update
+ return FALSE
if(updating_health)
updatehealth()
-/// damage MANY bodyparts, in random order
-/mob/living/proc/take_overall_damage(brute = 0, burn = 0, stamina = 0, updating_health = TRUE, required_bodytype)
- adjustBruteLoss(brute, FALSE) //zero as argument for no instant health update
- adjustFireLoss(burn, FALSE)
- adjustStaminaLoss(stamina, FALSE)
+/// damage MANY bodyparts, in random order. note: stamina arg nonfunctional for carbon mobs
+/mob/living/proc/take_overall_damage(brute = 0, burn = 0, stamina = 0, updating_health = TRUE, forced = FALSE, required_bodytype)
+ . = (adjustBruteLoss(abs(brute), updating_health = FALSE, forced = forced) + \
+ adjustFireLoss(abs(burn), updating_health = FALSE, forced = forced) + \
+ adjustStaminaLoss(abs(stamina), updating_stamina = FALSE, forced = forced))
+ if(!.) // no change, no need to update
+ return FALSE
if(updating_health)
updatehealth()
///heal up to amount damage, in a given order
/mob/living/proc/heal_ordered_damage(amount, list/damage_types)
- . = amount //we'll return the amount of damage healed
- for(var/i in damage_types)
- var/amount_to_heal = min(amount, get_damage_amount(i)) //heal only up to the amount of damage we have
+ . = FALSE //we'll return the amount of damage healed
+ for(var/damagetype in damage_types)
+ var/amount_to_heal = min(abs(amount), get_current_damage_of_type(damagetype)) //heal only up to the amount of damage we have
if(amount_to_heal)
- apply_damage_type(-amount_to_heal, i)
+ . += apply_damage_type(-amount_to_heal, damagetype)
amount -= amount_to_heal //remove what we healed from our current amount
if(!amount)
break
- . -= amount //if there's leftover healing, remove it from what we return
diff --git a/code/modules/mob/living/death.dm b/code/modules/mob/living/death.dm
index 217bc5bacba..9eddc41b127 100644
--- a/code/modules/mob/living/death.dm
+++ b/code/modules/mob/living/death.dm
@@ -14,6 +14,7 @@
if(!prev_lying)
gib_animation()
+ ghostize()
spill_organs(no_brain, no_organs, no_bodyparts, TRUE) //SKYRAT EDIT CHANGE - ORIGINAL: spill_organs(no_brain, no_organs, no_bodyparts)
if(!no_bodyparts)
diff --git a/code/modules/mob/living/emote.dm b/code/modules/mob/living/emote.dm
index 532d37ed1b2..dbb602aa2be 100644
--- a/code/modules/mob/living/emote.dm
+++ b/code/modules/mob/living/emote.dm
@@ -143,6 +143,8 @@
var/mob/living/carbon/human/H = user
var/open = FALSE
var/obj/item/organ/external/wings/functional/wings = H.get_organ_slot(ORGAN_SLOT_EXTERNAL_WINGS)
+
+ // open/close functional wings
if(istype(wings))
if(wings.wings_open)
open = TRUE
@@ -150,6 +152,10 @@
else
H.OpenWings()
addtimer(CALLBACK(wings, open ? TYPE_PROC_REF(/obj/item/organ/external/wings/functional, open_wings) : TYPE_PROC_REF(/obj/item/organ/external/wings/functional, close_wings)), wing_time)
+
+ // play moth flutter noise if moth wing
+ if(istype(wings, /obj/item/organ/external/wings/moth))
+ playsound(H, 'sound/voice/moth/moth_flutter.ogg', 50, TRUE)
*/
//SKYRAT EDIT REMOVAL END
@@ -487,7 +493,7 @@
/datum/emote/living/tremble
key = "tremble"
key_third_person = "trembles"
- message = "trembles in fear!"
+ message = "trembles!"
#define TREMBLE_LOOP_DURATION (4.4 SECONDS)
/datum/emote/living/tremble/run_emote(mob/living/user, params, type_override, intentional)
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index fa96e7c2181..8e51a6a8149 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -807,8 +807,8 @@
*/
/mob/living/proc/revive(full_heal_flags = NONE, excess_healing = 0, force_grab_ghost = FALSE)
if(excess_healing)
- adjustOxyLoss(-excess_healing, FALSE)
- adjustToxLoss(-excess_healing, FALSE, TRUE) //slime friendly
+ adjustOxyLoss(-excess_healing, updating_health = FALSE)
+ adjustToxLoss(-excess_healing, updating_health = FALSE, forced = TRUE) //slime friendly
updatehealth()
grab_ghost(force_grab_ghost)
@@ -857,13 +857,13 @@
var/oxy_to_heal = heal_to - getOxyLoss()
var/tox_to_heal = heal_to - getToxLoss()
if(brute_to_heal < 0)
- adjustBruteLoss(brute_to_heal, FALSE)
+ adjustBruteLoss(brute_to_heal, updating_health = FALSE)
if(burn_to_heal < 0)
- adjustFireLoss(burn_to_heal, FALSE)
+ adjustFireLoss(burn_to_heal, updating_health = FALSE)
if(oxy_to_heal < 0)
- adjustOxyLoss(oxy_to_heal, FALSE)
+ adjustOxyLoss(oxy_to_heal, updating_health = FALSE)
if(tox_to_heal < 0)
- adjustToxLoss(tox_to_heal, FALSE, TRUE)
+ adjustToxLoss(tox_to_heal, updating_health = FALSE, forced = TRUE)
// Run updatehealth once to set health for the revival check
updatehealth()
@@ -894,17 +894,17 @@
SHOULD_CALL_PARENT(TRUE)
if(heal_flags & HEAL_TOX)
- setToxLoss(0, FALSE, TRUE)
+ setToxLoss(0, updating_health = FALSE, forced = TRUE)
if(heal_flags & HEAL_OXY)
- setOxyLoss(0, FALSE, TRUE)
+ setOxyLoss(0, updating_health = FALSE, forced = TRUE)
if(heal_flags & HEAL_CLONE)
- setCloneLoss(0, FALSE, TRUE)
+ setCloneLoss(0, updating_health = FALSE, forced = TRUE)
if(heal_flags & HEAL_BRUTE)
- setBruteLoss(0, FALSE, TRUE)
+ setBruteLoss(0, updating_health = FALSE, forced = TRUE)
if(heal_flags & HEAL_BURN)
- setFireLoss(0, FALSE, TRUE)
+ setFireLoss(0, updating_health = FALSE, forced = TRUE)
if(heal_flags & HEAL_STAM)
- setStaminaLoss(0, FALSE, TRUE)
+ setStaminaLoss(0, updating_stamina = FALSE, forced = TRUE)
// I don't really care to keep this under a flag
set_nutrition(NUTRITION_LEVEL_FED + 50)
diff --git a/code/modules/mob/living/silicon/damage_procs.dm b/code/modules/mob/living/silicon/damage_procs.dm
index 8ee146508a4..4fe6e688632 100644
--- a/code/modules/mob/living/silicon/damage_procs.dm
+++ b/code/modules/mob/living/silicon/damage_procs.dm
@@ -18,19 +18,19 @@
/mob/living/silicon/adjustToxLoss(amount, updating_health = TRUE, forced = FALSE, required_biotype) //immune to tox damage
return FALSE
-/mob/living/silicon/setToxLoss(amount, updating_health = TRUE, forced = FALSE)
+/mob/living/silicon/setToxLoss(amount, updating_health = TRUE, forced = FALSE, required_biotype)
return FALSE
-/mob/living/silicon/adjustCloneLoss(amount, updating_health = TRUE, forced = FALSE) //immune to clone damage
+/mob/living/silicon/adjustCloneLoss(amount, updating_health = TRUE, forced = FALSE, required_biotype) //immune to clone damage
return FALSE
-/mob/living/silicon/setCloneLoss(amount, updating_health = TRUE, forced = FALSE)
+/mob/living/silicon/setCloneLoss(amount, updating_health = TRUE, forced = FALSE, required_biotype)
return FALSE
/mob/living/silicon/adjustStaminaLoss(amount, updating_stamina = TRUE, forced = FALSE, required_biotype) //immune to stamina damage.
return FALSE
-/mob/living/silicon/setStaminaLoss(amount, updating_health = TRUE)
+/mob/living/silicon/setStaminaLoss(amount, updating_stamina = TRUE, forced = FALSE, required_biotype)
return FALSE
/mob/living/silicon/adjustOrganLoss(slot, amount, maximum = 500, required_organ_flag) //immune to organ damage (no organs, duh)
@@ -45,7 +45,7 @@
return FALSE
-/mob/living/silicon/setOxyLoss(amount, updating_health = TRUE, forced = FALSE, required_biotype)
+/mob/living/silicon/setOxyLoss(amount, updating_health = TRUE, forced = FALSE, forced = FALSE, required_biotype)
if(isAI(src)) //ditto
return ..()
diff --git a/code/modules/mob/living/simple_animal/damage_procs.dm b/code/modules/mob/living/simple_animal/damage_procs.dm
index 6345320d9d9..1f7638325ce 100644
--- a/code/modules/mob/living/simple_animal/damage_procs.dm
+++ b/code/modules/mob/living/simple_animal/damage_procs.dm
@@ -42,7 +42,7 @@
else if(damage_coeff[TOX])
. = adjustHealth(amount * damage_coeff[TOX] * CONFIG_GET(number/damage_multiplier), updating_health, forced)
-/mob/living/simple_animal/adjustCloneLoss(amount, updating_health = TRUE, forced = FALSE)
+/mob/living/simple_animal/adjustCloneLoss(amount, updating_health = TRUE, forced = FALSE, required_biotype)
if(forced)
. = adjustHealth(amount * CONFIG_GET(number/damage_multiplier), updating_health, forced)
else if(damage_coeff[CLONE])
diff --git a/code/modules/mob/living/simple_animal/guardian/types/support.dm b/code/modules/mob/living/simple_animal/guardian/types/support.dm
index 5347f049e13..9afdf231ce7 100644
--- a/code/modules/mob/living/simple_animal/guardian/types/support.dm
+++ b/code/modules/mob/living/simple_animal/guardian/types/support.dm
@@ -47,10 +47,13 @@
span_userdanger("[src] heals you!"), null, COMBAT_MESSAGE_RANGE, src)
to_chat(src, span_notice("You heal [target]!"))
playsound(target, attack_sound, 50, TRUE, TRUE, frequency = -1) //play punch in REVERSE
- target.adjustBruteLoss(-healing_amount)
- target.adjustFireLoss(-healing_amount)
- target.adjustOxyLoss(-healing_amount)
- target.adjustToxLoss(-healing_amount, forced = TRUE)
+ var/need_mob_update
+ need_mob_update = target.adjustBruteLoss(-healing_amount, updating_health = FALSE)
+ need_mob_update += target.adjustFireLoss(-healing_amount, updating_health = FALSE)
+ need_mob_update += target.adjustOxyLoss(-healing_amount, updating_health = FALSE)
+ need_mob_update += target.adjustToxLoss(-healing_amount, updating_health = FALSE, forced = TRUE)
+ if(need_mob_update)
+ target.updatehealth()
var/obj/effect/temp_visual/heal/heal_effect = new /obj/effect/temp_visual/heal(get_turf(target))
heal_effect.color = guardian_color
diff --git a/code/modules/mob/living/simple_animal/hostile/heretic_monsters.dm b/code/modules/mob/living/simple_animal/hostile/heretic_monsters.dm
index 1b8cfe9de68..741e698a568 100644
--- a/code/modules/mob/living/simple_animal/hostile/heretic_monsters.dm
+++ b/code/modules/mob/living/simple_animal/hostile/heretic_monsters.dm
@@ -43,89 +43,6 @@
var/datum/action/cooldown/spell/new_spell = new spell(src)
new_spell.Grant(src)
-/mob/living/simple_animal/hostile/heretic_summon/raw_prophet
- name = "Raw Prophet"
- real_name = "Raw Prophet"
- desc = "An abomination stitched together from a few severed arms and one lost eye."
- icon_state = "raw_prophet"
- icon_living = "raw_prophet"
- status_flags = CANPUSH
- melee_damage_lower = 5
- melee_damage_upper = 10
- maxHealth = 65
- health = 65
- sight = SEE_MOBS|SEE_OBJS|SEE_TURFS
- loot = list(/obj/effect/gibspawner/human, /obj/item/bodypart/arm/left, /obj/item/organ/internal/eyes)
- actions_to_add = list(
- /datum/action/cooldown/spell/jaunt/ethereal_jaunt/ash/long,
- /datum/action/cooldown/spell/list_target/telepathy/eldritch,
- /datum/action/cooldown/spell/pointed/blind/eldritch,
- /datum/action/innate/expand_sight,
- )
- /// A weakref to the last target we smacked. Hitting targets consecutively does more damage.
- var/datum/weakref/last_target
-
-/mob/living/simple_animal/hostile/heretic_summon/raw_prophet/Initialize(mapload)
- . = ..()
- var/on_link_message = "You feel something new enter your sphere of mind... \
- You hear whispers of people far away, screeches of horror and a huming of welcome to [src]'s Mansus Link."
-
- var/on_unlink_message = "Your mind shatters as [src]'s Mansus Link leaves your mind."
-
- AddComponent( \
- /datum/component/mind_linker/active_linking, \
- network_name = "Mansus Link", \
- chat_color = "#568b00", \
- post_unlink_callback = CALLBACK(src, PROC_REF(after_unlink)), \
- speech_action_background_icon_state = "bg_heretic", \
- speech_action_overlay_state = "bg_heretic_border", \
- linker_action_path = /datum/action/cooldown/spell/pointed/manse_link, \
- link_message = on_link_message, \
- unlink_message = on_unlink_message, \
- )
-
-/mob/living/simple_animal/hostile/heretic_summon/raw_prophet/attack_animal(mob/living/simple_animal/user, list/modifiers)
- if(user == src) // Easy to hit yourself + very fragile = accidental suicide, prevent that
- return
-
- return ..()
-
-/mob/living/simple_animal/hostile/heretic_summon/raw_prophet/AttackingTarget(atom/attacked_target)
- if(WEAKREF(attacked_target) == last_target)
- melee_damage_lower = min(melee_damage_lower + 5, 30)
- melee_damage_upper = min(melee_damage_upper + 5, 35)
- else
- melee_damage_lower = initial(melee_damage_lower)
- melee_damage_upper = initial(melee_damage_upper)
-
- . = ..()
- if(!.)
- return
-
- SpinAnimation(5, 1)
- last_target = WEAKREF(attacked_target)
-
-/mob/living/simple_animal/hostile/heretic_summon/raw_prophet/Moved(atom/old_loc, movement_dir, forced, list/old_locs, momentum_change = TRUE)
- . = ..()
- var/rotation_degree = (360 / 3)
- if(movement_dir & WEST || movement_dir & SOUTH)
- rotation_degree *= -1
-
- var/matrix/to_turn = matrix(transform)
- to_turn = turn(transform, rotation_degree)
- animate(src, transform = to_turn, time = 0.1 SECONDS)
-
-/*
- * Callback for the mind_linker component.
- * Stuns people who are ejected from the network.
- */
-/mob/living/simple_animal/hostile/heretic_summon/raw_prophet/proc/after_unlink(mob/living/unlinked_mob)
- if(QDELETED(unlinked_mob) || unlinked_mob.stat == DEAD)
- return
-
- INVOKE_ASYNC(unlinked_mob, TYPE_PROC_REF(/mob, emote), "scream")
- unlinked_mob.AdjustParalyzed(0.5 SECONDS) //micro stun
-
// What if we took a linked list... But made it a mob?
/// The "Terror of the Night" / Armsy, a large worm made of multiple bodyparts that occupies multiple tiles
/mob/living/simple_animal/hostile/heretic_summon/armsy
diff --git a/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm b/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm
index 5ef5987942e..04bb2f94cc9 100644
--- a/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm
+++ b/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm
@@ -132,9 +132,10 @@
taste_mult = 1.3
/datum/reagent/toxin/leaper_venom/on_mob_life(mob/living/carbon/M, seconds_per_tick, times_fired)
+ . = ..()
if(volume >= 10)
- M.adjustToxLoss(5 * REM * seconds_per_tick, 0)
- ..()
+ if(M.adjustToxLoss(5 * REM * seconds_per_tick, updating_health = FALSE))
+ . = UPDATE_MOB_HEALTH
/obj/effect/temp_visual/leaper_crush
name = "grim tidings"
diff --git a/code/modules/mob/living/simple_animal/slime/life.dm b/code/modules/mob/living/simple_animal/slime/life.dm
index a103a55b996..3c34a68d6a2 100644
--- a/code/modules/mob/living/simple_animal/slime/life.dm
+++ b/code/modules/mob/living/simple_animal/slime/life.dm
@@ -199,8 +199,11 @@
var/mob/living/animal_victim = prey
var/totaldamage = 0 //total damage done to this unfortunate animal
- totaldamage += animal_victim.adjustBruteLoss(rand(2, 4) * 0.5 * seconds_per_tick)
- totaldamage += animal_victim.adjustToxLoss(rand(1, 2) * 0.5 * seconds_per_tick)
+ var/need_mob_update
+ need_mob_update = totaldamage += animal_victim.adjustBruteLoss(rand(2, 4) * 0.5 * seconds_per_tick, updating_health = FALSE)
+ need_mob_update += totaldamage += animal_victim.adjustToxLoss(rand(1, 2) * 0.5 * seconds_per_tick, updating_health = FALSE)
+ if(need_mob_update)
+ animal_victim.updatehealth()
if(totaldamage <= 0) //if we did no(or negative!) damage to it, stop
Feedstop(0, 0)
diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm
index 7df256d1873..8b8a8cff943 100644
--- a/code/modules/mob/mob_helpers.dm
+++ b/code/modules/mob/mob_helpers.dm
@@ -323,7 +323,7 @@
return FALSE
var/brute_damage = brute_heal > burn_heal //changes repair text based on how much brute/burn was supplied
if((brute_heal > 0 && affecting.brute_dam > 0) || (burn_heal > 0 && affecting.burn_dam > 0))
- if(affecting.heal_damage(brute_heal, burn_heal, BODYTYPE_ROBOTIC))
+ if(affecting.heal_damage(brute_heal, burn_heal, required_bodytype = BODYTYPE_ROBOTIC))
human.update_damage_overlays()
user.visible_message(span_notice("[user] fixes some of the [brute_damage ? "dents on" : "burnt wires in"] [human]'s [affecting.name]."), \
span_notice("You fix some of the [brute_damage ? "dents on" : "burnt wires in"] [human == user ? "your" : "[human]'s"] [affecting.name]."))
diff --git a/code/modules/mob/status_procs.dm b/code/modules/mob/status_procs.dm
index 1dde25c7802..fccd64ab705 100644
--- a/code/modules/mob/status_procs.dm
+++ b/code/modules/mob/status_procs.dm
@@ -12,6 +12,7 @@
/mob/proc/adjust_bodytemperature(amount,min_temp=0,max_temp=INFINITY)
if(bodytemperature >= min_temp && bodytemperature <= max_temp)
bodytemperature = clamp(bodytemperature + amount,min_temp,max_temp)
+ return TRUE
/// Sight here is the mob.sight var, which tells byond what to actually show to our client
/// See [code\__DEFINES\sight.dm] for more details
diff --git a/code/modules/mob_spawn/ghost_roles/mining_roles.dm b/code/modules/mob_spawn/ghost_roles/mining_roles.dm
index 62861c6f303..98c6dbc6d45 100644
--- a/code/modules/mob_spawn/ghost_roles/mining_roles.dm
+++ b/code/modules/mob_spawn/ghost_roles/mining_roles.dm
@@ -236,7 +236,7 @@
return ..()
/obj/effect/mob_spawn/ghost_role/human/ash_walker/allow_spawn(mob/user, silent = FALSE)
- if(!(user.ckey in team.players_spawned))//one per person unless you get a bonus spawn SKYRAT EDIT: Original: if(!(user.key in team.players_spawned))
+ if(!(user.ckey in team.players_spawned))//one per person unless you get a bonus spawn
return TRUE
if(!silent)
to_chat(user, span_warning("You have exhausted your usefulness to the Necropolis."))
@@ -254,7 +254,7 @@
spawned_human.mind.add_antag_datum(/datum/antagonist/ashwalker, team)
spawned_human.remove_language(/datum/language/common)
- team.players_spawned += (spawned_human.ckey) //SKYRAT EDIT: Original: team.players_spawned += (spawned_human.key)
+ team.players_spawned += (spawned_human.ckey)
eggshell.egg = null
QDEL_NULL(eggshell)
@@ -316,7 +316,7 @@
ears = /obj/item/radio/headset/syndicate/alt
shoes = /obj/item/clothing/shoes/combat
r_pocket = /obj/item/gun/ballistic/automatic/pistol
- r_hand = /obj/item/gun/ballistic/rifle/sniper_rifle
+ r_hand = /obj/item/storage/toolbox/guncase/skyrat/carwo_large_case/sindano/evil // SKYRAT EDIT - Original: /obj/item/gun/ballistic/rifle/sniper_rifle
implants = list(/obj/item/implant/weapons_auth)
id_trim = /datum/id_trim/syndicom/skyrat/interdyne //SKYRAT EDIT
diff --git a/code/modules/mod/modules/modules_security.dm b/code/modules/mod/modules/modules_security.dm
index 2c7ae6821fe..7e331433b4f 100644
--- a/code/modules/mod/modules/modules_security.dm
+++ b/code/modules/mod/modules/modules_security.dm
@@ -361,13 +361,95 @@
/obj/item/mod/module/active_sonar
name = "MOD active sonar"
desc = "Ancient tech from the 20th century, this module uses sonic waves to detect living creatures within the user's radius. \
+ Its basic function slowly scans around the user for any bio-signatures, however it can be overclocked to scan everywhere at once.\
Its loud ping is much harder to hide in an indoor station than in the outdoor operations it was designed for."
icon_state = "active_sonar"
module_type = MODULE_USABLE
- use_power_cost = DEFAULT_CHARGE_DRAIN * 4
+ idle_power_cost = DEFAULT_CHARGE_DRAIN * 0.5
+ use_power_cost = DEFAULT_CHARGE_DRAIN * 3
complexity = 2
incompatible_modules = list(/obj/item/mod/module/active_sonar)
cooldown_time = 15 SECONDS
+ /// Time between us displaying radial scans
+ var/scan_cooldown_time = 0.5 SECONDS
+ /// The current slice we're going to scan
+ var/scanned_slice = 1
+ /// How many slices we make 360
+ var/radar_slices = 8 // 45 degrees each
+
+ /// A list of all creatures in range sorted by angle.
+ var/list/sorted_creatures = list()
+ /// A keyed list of all creatures
+ var/list/keyed_creatures = list()
+
+ /// Time between us displaying radial scans
+ COOLDOWN_DECLARE(scan_cooldown)
+
+/obj/item/mod/module/active_sonar/Initialize(mapload)
+ . = ..()
+ for(var/i in 1 to radar_slices)
+ sorted_creatures += list(list())
+
+/obj/item/mod/module/active_sonar/on_suit_activation()
+ RegisterSignal(mod.wearer, COMSIG_MOVABLE_MOVED, PROC_REF(sort_all_creatures))
+
+/obj/item/mod/module/active_sonar/on_suit_deactivation(deleting = FALSE)
+ UnregisterSignal(mod.wearer, COMSIG_MOVABLE_MOVED)
+
+/// Detects all living creatures within world.view, and returns the amount.
+/obj/item/mod/module/active_sonar/proc/detect_living_creatures()
+ var/creatures_detected = 0
+ for(var/mob/living/creature in range(world.view, mod.wearer))
+ if(creature == mod.wearer || creature.stat == DEAD)
+ continue
+ if(keyed_creatures[creature])
+ creatures_detected++
+ continue
+ sort_creature_angle(creature)
+ RegisterSignal(creature, COMSIG_MOVABLE_MOVED, PROC_REF(sort_creature_angle))
+ creatures_detected++
+ return creatures_detected
+
+/// Swaps around where a creature is, when they move or when they're first detected
+/obj/item/mod/module/active_sonar/proc/sort_creature_angle(mob/living/creature, atom/old_loc, movement_dir, forced)
+ SIGNAL_HANDLER
+ var/oldgroup = keyed_creatures[creature]
+ var/newgroup = round(get_angle(mod.wearer, creature) / (360 / radar_slices)) + 1
+ if(oldgroup)
+ if(creature.stat == DEAD || get_dist(get_turf(mod.wearer), get_turf(creature)) > world.view)
+ sorted_creatures[oldgroup] -= creature
+ keyed_creatures -= creature
+ UnregisterSignal(creature, COMSIG_MOVABLE_MOVED)
+ return
+
+ if(oldgroup != newgroup)
+ sorted_creatures[oldgroup] -= creature
+
+ sorted_creatures[newgroup] += creature
+ keyed_creatures[creature] = newgroup
+
+/// Swaps all creatures when mod.wearer moves
+/obj/item/mod/module/active_sonar/proc/sort_all_creatures(mob/living/wearer, atom/old_loc, movement_dir, forced)
+ SIGNAL_HANDLER
+
+ for(var/mob/living/creature as anything in keyed_creatures)
+ sort_creature_angle(creature) // Kinda spaghetti but it honestly seems like the shortest path to the same result
+
+/obj/item/mod/module/active_sonar/on_process(seconds_per_tick)
+ . = ..()
+ if(!.)
+ return
+ if(!COOLDOWN_FINISHED(src, cooldown_timer) || !COOLDOWN_FINISHED(src, scan_cooldown))
+ return
+ detect_living_creatures()
+ for(var/mob/living/creature as anything in sorted_creatures[scanned_slice])
+ new /obj/effect/temp_visual/sonar_ping(mod.wearer.loc, mod.wearer, creature, "sonar_ping_small", FALSE)
+ // Next slice!
+ scanned_slice++
+ // IT'S ENOUGH SLICES
+ if(scanned_slice > radar_slices)
+ scanned_slice = 1
+ COOLDOWN_START(src, scan_cooldown, scan_cooldown_time)
/obj/item/mod/module/active_sonar/on_use()
. = ..()
@@ -377,14 +459,10 @@
playsound(mod.wearer, 'sound/mecha/skyfall_power_up.ogg', vol = 20, vary = TRUE, extrarange = SHORT_RANGE_SOUND_EXTRARANGE)
if(!do_after(mod.wearer, 1.1 SECONDS, target = mod))
return
- var/creatures_detected = 0
- for(var/mob/living/creature in range(9, mod.wearer))
- if(creature == mod.wearer || creature.stat == DEAD)
- continue
+ playsound(mod.wearer, 'sound/effects/ping_hit.ogg', vol = 75, vary = TRUE) // Should be audible for the radius of the sonar
+ to_chat(mod.wearer, span_notice("You slam your fist into the ground, sending out a sonic wave that detects [detect_living_creatures()] living beings nearby!"))
+ for(var/mob/living/creature as anything in keyed_creatures)
new /obj/effect/temp_visual/sonar_ping(mod.wearer.loc, mod.wearer, creature)
- creatures_detected++
- playsound(mod.wearer, 'sound/effects/ping_hit.ogg', vol = 75, vary = TRUE, extrarange = MEDIUM_RANGE_SOUND_EXTRARANGE) // Should be audible for the radius of the sonar
- to_chat(mod.wearer, span_notice("You slam your fist into the ground, sending out a sonic wave that detects [creatures_detected] living beings nearby!"))
#define SHOOTING_ASSISTANT_OFF "Currently Off"
#define STORMTROOPER_MODE "Quick Fire Stormtrooper"
diff --git a/code/modules/movespeed/modifiers/status_effects.dm b/code/modules/movespeed/modifiers/status_effects.dm
index e8aad88c50d..65245880ef4 100644
--- a/code/modules/movespeed/modifiers/status_effects.dm
+++ b/code/modules/movespeed/modifiers/status_effects.dm
@@ -37,3 +37,19 @@
/datum/movespeed_modifier/status_effect/tired_post_charge
multiplicative_slowdown = 3
+
+/// Get slower the more gold is in your system.
+/datum/movespeed_modifier/status_effect/midas_blight
+ id = MOVESPEED_ID_MIDAS_BLIGHT
+
+/datum/movespeed_modifier/status_effect/midas_blight/soft
+ multiplicative_slowdown = 0.25
+
+/datum/movespeed_modifier/status_effect/midas_blight/medium
+ multiplicative_slowdown = 0.75
+
+/datum/movespeed_modifier/status_effect/midas_blight/hard
+ multiplicative_slowdown = 1.5
+
+/datum/movespeed_modifier/status_effect/midas_blight/gold
+ multiplicative_slowdown = 2
diff --git a/code/modules/paperwork/paperbin.dm b/code/modules/paperwork/paperbin.dm
index 318fca21f57..9971c0da7f7 100644
--- a/code/modules/paperwork/paperbin.dm
+++ b/code/modules/paperwork/paperbin.dm
@@ -54,12 +54,26 @@
droppoint = drop_location()
if(collapse)
visible_message(span_warning("The stack of paper collapses!"))
- for(var/atom/movable/movable_atom in contents)
- movable_atom.forceMove(droppoint)
- if(!movable_atom.pixel_y)
- movable_atom.pixel_y = rand(-3,3)
- if(!movable_atom.pixel_x)
- movable_atom.pixel_x = rand(-3,3)
+ for(var/obj/item/paper/stacked_paper in paper_stack) //first, dump all of the paper that already exists
+ stacked_paper.forceMove(droppoint)
+ if(!stacked_paper.pixel_y)
+ stacked_paper.pixel_y = rand(-3,3)
+ if(!stacked_paper.pixel_x)
+ stacked_paper.pixel_x = rand(-3,3)
+ paper_stack -= stacked_paper
+ total_paper -= 1
+ for(var/i in 1 to total_paper) //second, generate new paper for the remainder
+ var/obj/item/paper/new_paper = generate_paper()
+ new_paper.forceMove(droppoint)
+ if(!new_paper.pixel_y)
+ new_paper.pixel_y = rand(-3,3)
+ if(!new_paper.pixel_x)
+ new_paper.pixel_x = rand(-3,3)
+ if(bin_pen)
+ var/obj/item/pen/pen = bin_pen
+ pen.forceMove(droppoint)
+ bin_pen = null
+ total_paper = 0
update_appearance()
/obj/item/paper_bin/fire_act(exposed_temperature, exposed_volume)
@@ -212,6 +226,8 @@
/obj/item/paper_bin/bundlenatural/dump_contents(atom/droppoint)
. = ..()
+ binding_cable.forceMove(droppoint)
+ binding_cable = null
qdel(src)
/obj/item/paper_bin/bundlenatural/update_overlays()
@@ -225,7 +241,7 @@
deconstruct(FALSE)
/obj/item/paper_bin/bundlenatural/deconstruct(disassembled)
- dump_contents()
+ dump_contents(drop_location())
return ..()
/obj/item/paper_bin/bundlenatural/fire_act(exposed_temperature, exposed_volume)
diff --git a/code/modules/plumbing/plumbers/pill_press.dm b/code/modules/plumbing/plumbers/pill_press.dm
index 3a9afca5e02..e04215e94e2 100644
--- a/code/modules/plumbing/plumbers/pill_press.dm
+++ b/code/modules/plumbing/plumbers/pill_press.dm
@@ -3,7 +3,6 @@
name = "chemical press"
desc = "A press that makes pills, patches and bottles."
icon_state = "pill_press"
- buffer = 60 //SKYRAT EDIT HYPOVIALS. This is needed so it can completely fill the vials up.
active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION * 2
///maximum size of a pill
@@ -12,8 +11,6 @@
var/max_patch_volume = 40
///maximum size of a bottle
var/max_bottle_volume = 50
- //SKYRAT EDIT HYPOVIALS maximum size of a vial
- var/max_vial_volume = 60
///current operating product (pills or patches)
var/product = "pill"
///the minimum size a pill or patch can be
@@ -72,13 +69,13 @@
reagents.trans_to(P, current_volume)
P.name = trim("[product_name] bottle")
stored_products += P
- //SKYRAT EDIT HYPOVIALS
+ //SKYRAT EDIT ADDITION BEGIN - HYPOVIALS
else if (product == "vial")
var/obj/item/reagent_containers/cup/vial/small/P = new(src)
reagents.trans_to(P, current_volume)
P.name = trim("[product_name] vial")
stored_products += P
- //SKYRAT EDIT HYPOVIALS END
+ //SKYRAT EDIT ADDITION END - HYPOVIALS
if(stored_products.len)
var/pill_amount = 0
for(var/thing in loc)
@@ -159,10 +156,10 @@
max_volume = max_patch_volume
else if (product == "bottle")
max_volume = max_bottle_volume
- //SKYRAT EDIT HYPOVIALS
+ //SKYRAT EDIT ADDITION BEGIN - HYPOVIALS
else if (product == "vial")
- max_volume = max_vial_volume
- //SKYRAT EDIT HPYOVIALS END
+ max_volume = max_bottle_volume
+ //SKYRAT EDIT ADDITION END - HYPOVIALS
current_volume = clamp(current_volume, min_volume, max_volume)
if("change_patch_style")
patch_style = params["patch_style"]
diff --git a/code/modules/plumbing/plumbers/reaction_chamber.dm b/code/modules/plumbing/plumbers/reaction_chamber.dm
index 689d043418b..36320f18184 100644
--- a/code/modules/plumbing/plumbers/reaction_chamber.dm
+++ b/code/modules/plumbing/plumbers/reaction_chamber.dm
@@ -1,5 +1,8 @@
///a reaction chamber for plumbing. pretty much everything can react, but this one keeps the reagents separated and only reacts under your given terms
+/// coefficient to convert temperature to joules. same lvl as acclimator
+#define HEATER_COEFFICIENT 0.05
+
/obj/machinery/plumbing/reaction_chamber
name = "mixing chamber"
desc = "Keeps chemicals separated until given conditions are met."
@@ -19,9 +22,6 @@
///towards which temperature do we build (except during draining)?
var/target_temperature = 300
- ///cool/heat power
- var/heater_coefficient = 0.05 //same lvl as acclimator
-
/obj/machinery/plumbing/reaction_chamber/Initialize(mapload, bolt, layer)
. = ..()
@@ -35,30 +35,48 @@
/// Handles properly detaching signal hooks.
/obj/machinery/plumbing/reaction_chamber/proc/on_reagents_del(datum/reagents/reagents)
SIGNAL_HANDLER
+
UnregisterSignal(reagents, list(COMSIG_REAGENTS_REM_REAGENT, COMSIG_REAGENTS_DEL_REAGENT, COMSIG_REAGENTS_CLEAR_REAGENTS, COMSIG_REAGENTS_REACTED, COMSIG_QDELETING))
return NONE
/// Handles stopping the emptying process when the chamber empties.
/obj/machinery/plumbing/reaction_chamber/proc/on_reagent_change(datum/reagents/holder, ...)
SIGNAL_HANDLER
- if(holder.total_volume == 0 && emptying) //we were emptying, but now we aren't
+
+ if(!holder.total_volume && emptying) //we were emptying, but now we aren't
emptying = FALSE
holder.flags |= NO_REACT
return NONE
/obj/machinery/plumbing/reaction_chamber/process(seconds_per_tick)
- if(!emptying || reagents.is_reacting) //suspend heating/cooling during emptying phase
- reagents.adjust_thermal_energy((target_temperature - reagents.chem_temp) * heater_coefficient * seconds_per_tick * SPECIFIC_HEAT_DEFAULT * reagents.total_volume) //keep constant with chem heater
+ //half the power for getting reagents in
+ var/power_usage = active_power_usage * 0.5
+
+ if(!emptying || reagents.is_reacting)
+ //do reactions and stuff
reagents.handle_reactions()
- use_power(active_power_usage * seconds_per_tick)
+ //adjust temperature of final solution
+ var/temp_diff = target_temperature - reagents.chem_temp
+ if(abs(temp_diff) > 0.01) //if we are not close enough keep going
+ reagents.adjust_thermal_energy(temp_diff * HEATER_COEFFICIENT * seconds_per_tick * SPECIFIC_HEAT_DEFAULT * reagents.total_volume) //keep constant with chem heater
+
+ //do other stuff with final solution
+ handle_reagents(seconds_per_tick)
+
+ //full power for doing reactions
+ power_usage *= 2
+
+ use_power(power_usage * seconds_per_tick)
+
+///For subtypes that want to do additional reagent handling
+/obj/machinery/plumbing/reaction_chamber/proc/handle_reagents(seconds_per_tick)
+ return
/obj/machinery/plumbing/reaction_chamber/power_change()
. = ..()
- if(use_power != NO_POWER_USE)
- icon_state = initial(icon_state) + "_on"
- else
- icon_state = initial(icon_state)
+
+ icon_state = initial(icon_state) + "[use_power != NO_POWER_USE ? "_on" : ""]"
/obj/machinery/plumbing/reaction_chamber/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
@@ -67,31 +85,29 @@
ui.open()
/obj/machinery/plumbing/reaction_chamber/ui_data(mob/user)
- var/list/data = list()
+ . = list()
var/list/reagents_data = list()
for(var/datum/reagent/required_reagent as anything in required_reagents) //make a list where the key is text, because that looks alot better in the ui than a typepath
var/list/reagent_data = list()
reagent_data["name"] = initial(required_reagent.name)
- reagent_data["required_reagent"] = required_reagents[required_reagent]
+ reagent_data["volume"] = required_reagents[required_reagent]
reagents_data += list(reagent_data)
- data["reagents"] = reagents_data
- data["emptying"] = emptying
- data["temperature"] = round(reagents.chem_temp, 0.1)
- data["targetTemp"] = target_temperature
- data["isReacting"] = reagents.is_reacting
- return data
+ .["reagents"] = reagents_data
+ .["emptying"] = emptying
+ .["temperature"] = round(reagents.chem_temp, 0.1)
+ .["targetTemp"] = target_temperature
+ .["isReacting"] = reagents.is_reacting
-/obj/machinery/plumbing/reaction_chamber/ui_act(action, params)
+/obj/machinery/plumbing/reaction_chamber/ui_act(action, params, datum/tgui/ui, datum/ui_state/state)
. = ..()
if(.)
return TRUE
- . = FALSE
switch(action)
if("add")
- var/selected_reagent = tgui_input_list(usr, "Select reagent", "Reagent", GLOB.chemical_name_list)
+ var/selected_reagent = tgui_input_list(ui.user, "Select reagent", "Reagent", GLOB.chemical_name_list)
if(!selected_reagent)
return TRUE
@@ -104,32 +120,41 @@
if(input_amount)
required_reagents[input_reagent] = input_amount
- . = TRUE
+ return TRUE
if("remove")
var/reagent = get_chem_id(params["chem"])
if(reagent)
required_reagents.Remove(reagent)
- . = TRUE
+ return TRUE
if("temperature")
var/target = text2num(params["target"])
if(target != null)
- target_temperature=clamp(target, 0, 1000)
- .=TRUE
+ target_temperature = clamp(target, 0, 1000)
+ return TRUE
+
+ var/result = handle_ui_act(action, params, ui, state)
+ if(isnull(result))
+ result = FALSE
+ return result
+
+/// For custom handling of ui actions from inside a subtype
+/obj/machinery/plumbing/reaction_chamber/proc/handle_ui_act(action, params, datum/tgui/ui, datum/ui_state/state)
+ return null
///Chemistry version of reaction chamber that allows for acid and base buffers to be used while reacting
/obj/machinery/plumbing/reaction_chamber/chem
name = "reaction chamber"
- ///If above this pH, we start dumping buffer into it
- var/acidic_limit = 9
///If below this pH, we start dumping buffer into it
- var/alkaline_limit = 5
+ var/acidic_limit = 5
+ ///If above this pH, we start dumping acid into it
+ var/alkaline_limit = 9
- ///Beaker that holds the acidic buffer. I don't want to deal with snowflaking so it's just a separate thing. It's a small (50u) beaker
+ ///beaker that holds the acidic buffer(50u)
var/obj/item/reagent_containers/cup/beaker/acidic_beaker
- ///beaker that holds the alkaline buffer.
+ ///beaker that holds the alkaline buffer(50u).
var/obj/item/reagent_containers/cup/beaker/alkaline_beaker
/obj/machinery/plumbing/reaction_chamber/chem/Initialize(mapload, bolt, layer)
@@ -147,13 +172,27 @@
QDEL_NULL(alkaline_beaker)
return ..()
-/obj/machinery/plumbing/reaction_chamber/chem/process(seconds_per_tick)
- //add acidic/alkaine buffer if over/under limit
- if(reagents.is_reacting && reagents.ph < alkaline_limit)
- alkaline_beaker.reagents.trans_to(reagents, 1 * seconds_per_tick)
- if(reagents.is_reacting && reagents.ph > acidic_limit)
- acidic_beaker.reagents.trans_to(reagents, 1 * seconds_per_tick)
- ..()
+/obj/machinery/plumbing/reaction_chamber/chem/handle_reagents(seconds_per_tick)
+ while(reagents.ph < acidic_limit || reagents.ph > alkaline_limit)
+ if(machine_stat & NOPOWER)
+ return
+
+ /**
+ * figure out which buffer to transfer to restore balance
+ * if solution is getting too basic(high ph) add some acid to lower it's value
+ * else if solution is getting too acidic(low ph) add some base to increase it's value
+ */
+ var/datum/reagents/buffer = reagents.ph > alkaline_limit ? acidic_beaker.reagents : alkaline_beaker.reagents
+ if(!buffer.total_volume)
+ return
+
+ //transfer buffer and handle reactions, not a proven math but looks logical
+ var/transfer_amount = FLOOR((reagents.ph > alkaline_limit ? (reagents.ph - alkaline_limit) : (acidic_limit - reagents.ph)) * seconds_per_tick, CHEMICAL_QUANTISATION_LEVEL)
+ if(transfer_amount <= CHEMICAL_QUANTISATION_LEVEL || !buffer.trans_to(reagents, transfer_amount))
+ return
+
+ //some power for accurate ph balancing
+ use_power(active_power_usage * 0.2 * seconds_per_tick)
/obj/machinery/plumbing/reaction_chamber/chem/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
@@ -167,16 +206,16 @@
.["reagentAcidic"] = acidic_limit
.["reagentAlkaline"] = alkaline_limit
-/obj/machinery/plumbing/reaction_chamber/chem/ui_act(action, params)
- . = ..()
- if (.)
- return
+/obj/machinery/plumbing/reaction_chamber/chem/handle_ui_act(action, params, datum/tgui/ui, datum/ui_state/state)
+ . = TRUE
switch(action)
if("acidic")
- acidic_limit = round(text2num(params["target"]))
+ acidic_limit = clamp(round(text2num(params["target"])), 0, alkaline_limit)
if("alkaline")
- alkaline_limit = round(text2num(params["target"]))
+ alkaline_limit = clamp(round(text2num(params["target"])), acidic_limit + 0.01, 14)
+ else
+ return FALSE
- return TRUE
+#undef HEATER_COEFFICIENT
diff --git a/code/modules/projectiles/guns/ballistic.dm b/code/modules/projectiles/guns/ballistic.dm
index 576ba6395be..efff8c2fc61 100644
--- a/code/modules/projectiles/guns/ballistic.dm
+++ b/code/modules/projectiles/guns/ballistic.dm
@@ -723,7 +723,7 @@ GLOBAL_LIST_INIT(gun_saw_types, typecacheof(list(
/obj/item/suppressor
name = "suppressor"
- desc = "A Scarborough Arms small-arms suppressor for maximum espionage." //SKYRAT EDIT - ORIGINAL: desc = "A syndicate small-arms suppressor for maximum espionage."
+ desc = "A small-arms suppressor for maximum espionage." //SKYRAT EDIT - ORIGINAL: desc = "A syndicate small-arms suppressor for maximum espionage."
icon = 'icons/obj/weapons/guns/ballistic.dmi'
icon_state = "suppressor"
w_class = WEIGHT_CLASS_TINY
diff --git a/code/modules/projectiles/guns/special/hand_of_midas.dm b/code/modules/projectiles/guns/special/hand_of_midas.dm
new file mode 100644
index 00000000000..9907352e3f5
--- /dev/null
+++ b/code/modules/projectiles/guns/special/hand_of_midas.dm
@@ -0,0 +1,138 @@
+// Hand of Midas
+
+/obj/item/gun/magic/midas_hand
+ name = "The Hand of Midas"
+ desc = "An ancient Egyptian matchlock pistol imbued with the powers of the Greek King Midas. Don't question the cultural or religious implications of this."
+ ammo_type = /obj/item/ammo_casing/magic/midas_round
+ icon_state = "midas_hand"
+ inhand_icon_state = "gun"
+ worn_icon_state = "gun"
+ lefthand_file = 'icons/mob/inhands/weapons/guns_lefthand.dmi'
+ righthand_file = 'icons/mob/inhands/weapons/guns_righthand.dmi'
+ fire_sound = 'sound/weapons/gun/rifle/shot.ogg'
+ pinless = TRUE
+ max_charges = 1
+ can_charge = FALSE
+ item_flags = NEEDS_PERMIT
+ w_class = WEIGHT_CLASS_BULKY // Should fit on a belt.
+ force = 3
+ trigger_guard = TRIGGER_GUARD_NORMAL
+ antimagic_flags = NONE
+ can_hold_up = FALSE
+
+ /// The length of the Midas Blight debuff, dependant on the amount of gold reagent we've sucked up.
+ var/gold_timer = 3 SECONDS
+ /// The range that we can suck gold out of people's bodies
+ var/gold_suck_range = 2
+
+/obj/item/gun/magic/midas_hand/examine(mob/user)
+ . = ..()
+ var/gold_time_converted = gold_time_convert()
+ . += span_notice("Your next shot will inflict [gold_time_converted] second[gold_time_converted == 1 ? "" : "s"] of Midas Blight.")
+ . += span_notice("Right-Click on enemies to drain gold from their bloodstreams to reload [src].")
+ . += span_notice("[src] can be reloaded using gold coins in a pinch.")
+
+/obj/item/gun/magic/midas_hand/shoot_with_empty_chamber(mob/living/user)
+ . = ..()
+ balloon_alert(user, "not enough gold")
+
+// Siphon gold from a victim, recharging our gun & removing their Midas Blight debuff in the process.
+/obj/item/gun/magic/midas_hand/afterattack_secondary(mob/living/victim, mob/living/user, proximity_flag, click_parameters)
+ if(!isliving(victim) || !IN_GIVEN_RANGE(user, victim, gold_suck_range))
+ return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
+ if(victim == user)
+ balloon_alert(user, "can't siphon from self")
+ return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
+ if(!victim.reagents)
+ return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
+ if(!victim.reagents.has_reagent(/datum/reagent/gold, check_subtypes = TRUE))
+ balloon_alert(user, "no gold in bloodstream")
+ return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
+ var/gold_beam = user.Beam(victim, icon_state="drain_gold")
+ if(!do_after(user = user, delay = 1 SECONDS, target = victim, timed_action_flags = (IGNORE_USER_LOC_CHANGE | IGNORE_TARGET_LOC_CHANGE), extra_checks = CALLBACK(src, PROC_REF(check_gold_range), user, victim)))
+ qdel(gold_beam)
+ balloon_alert(user, "link broken")
+ return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
+ handle_gold_charges(user, victim.reagents.get_reagent_amount(/datum/reagent/gold, include_subtypes = TRUE))
+ victim.reagents.remove_all_type(/datum/reagent/gold, victim.reagents.get_reagent_amount(/datum/reagent/gold, include_subtypes = TRUE))
+ victim.remove_status_effect(/datum/status_effect/midas_blight)
+ qdel(gold_beam)
+ return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
+
+// If we botch a shot, we have to start over again by inserting gold coins into the gun. Can only be done if it has no charges or gold.
+/obj/item/gun/magic/midas_hand/attackby(obj/item/I, mob/living/user, params)
+ . = ..()
+ if(charges || gold_timer)
+ balloon_alert(user, "already loaded")
+ return
+ if(istype(I, /obj/item/coin/gold))
+ handle_gold_charges(user, 1.5 SECONDS)
+ qdel(I)
+
+/// Handles recharging & inserting gold amount
+/obj/item/gun/magic/midas_hand/proc/handle_gold_charges(user, gold_amount)
+ gold_timer += gold_amount
+ var/gold_time_converted = gold_time_convert()
+ balloon_alert(user, "[gold_time_converted] second[gold_time_converted == 1 ? "" : "s"]")
+ if(!charges)
+ instant_recharge()
+
+/// Converts our gold_timer to time in seconds, for various ballons/examines
+/obj/item/gun/magic/midas_hand/proc/gold_time_convert()
+ return min(30 SECONDS, round(gold_timer, 0.2)) / 10
+
+/// Checks our range to the person we're sucking gold out of. Double the initial range, so you need to get in close to start.
+/obj/item/gun/magic/midas_hand/proc/check_gold_range(mob/living/user, mob/living/victim)
+ return IN_GIVEN_RANGE(user, victim, gold_suck_range*2)
+
+/obj/item/ammo_casing/magic/midas_round
+ projectile_type = /obj/projectile/magic/midas_round
+
+
+/obj/projectile/magic/midas_round
+ name = "gold pellet"
+ desc = "A typical flintlock ball, save for the fact it's made of cursed Egyptian gold."
+ damage_type = BRUTE
+ damage = 10
+ stamina = 20
+ armour_penetration = 50
+ hitsound = 'sound/effects/coin2.ogg'
+ icon_state = "pellet"
+ color = "#FFD700"
+ /// The gold charge in this pellet
+ var/gold_charge = 0
+
+
+/obj/projectile/magic/midas_round/fire(setAngle)
+ /// Transfer the gold energy to our bullet
+ var/obj/item/gun/magic/midas_hand/my_gun = fired_from
+ gold_charge = my_gun.gold_timer
+ my_gun.gold_timer = 0
+ ..()
+
+// Gives human targets Midas Blight.
+/obj/projectile/magic/midas_round/on_hit(atom/target)
+ . = ..()
+ if(ishuman(target))
+ var/mob/living/carbon/human/my_guy = target
+ if(isskeleton(my_guy)) // No cheap farming
+ return
+ my_guy.apply_status_effect(/datum/status_effect/midas_blight, min(30 SECONDS, round(gold_charge, 0.2))) // 100u gives 10 seconds
+ return
+
+/obj/item/gun/magic/midas_hand/suicide_act(mob/living/user)
+ if(!ishuman(user))
+ return
+
+ var/mob/living/carbon/human/victim = user
+ victim.visible_message(span_suicide("[victim] holds the barrel of [src] to [victim.p_their()] head, lighting the fuse. It looks like [user.p_theyre()] trying to commit suicide!"))
+ if(!do_after(victim, 1.5 SECONDS))
+ return
+ playsound(src, 'sound/weapons/gun/rifle/shot.ogg', 75, TRUE)
+ to_chat(victim, span_danger("You don't even have the time to register the gunshot by the time your body has completely converted into a golden statue."))
+ var/newcolors = list(rgb(206, 164, 50), rgb(146, 146, 139), rgb(28,28,28), rgb(0,0,0))
+ victim.petrify(statue_timer = INFINITY, save_brain = FALSE, colorlist = newcolors)
+ playsound(victim, 'sound/effects/coin2.ogg', 75, TRUE)
+ charges = 0
+ gold_timer = 0
+ return OXYLOSS
diff --git a/code/modules/projectiles/guns/special/medbeam.dm b/code/modules/projectiles/guns/special/medbeam.dm
index d3ee77ef3b3..267470f1701 100644
--- a/code/modules/projectiles/guns/special/medbeam.dm
+++ b/code/modules/projectiles/guns/special/medbeam.dm
@@ -144,10 +144,13 @@
/obj/item/gun/medbeam/proc/on_beam_tick(mob/living/target)
if(target.health != target.maxHealth)
new /obj/effect/temp_visual/heal(get_turf(target), COLOR_HEALING_CYAN)
- target.adjustBruteLoss(-4)
- target.adjustFireLoss(-4)
- target.adjustToxLoss(-1, forced = TRUE)
- target.adjustOxyLoss(-1, forced = TRUE)
+ var/need_mob_update
+ need_mob_update = target.adjustBruteLoss(-4, updating_health = FALSE, forced = TRUE)
+ need_mob_update += target.adjustFireLoss(-4, updating_health = FALSE, forced = TRUE)
+ need_mob_update += target.adjustToxLoss(-1, updating_health = FALSE, forced = TRUE)
+ need_mob_update += target.adjustOxyLoss(-1, updating_health = FALSE, forced = TRUE)
+ if(need_mob_update)
+ target.updatehealth()
return
/obj/item/gun/medbeam/proc/on_beam_release(mob/living/target)
diff --git a/code/modules/projectiles/guns/special/syringe_gun.dm b/code/modules/projectiles/guns/special/syringe_gun.dm
index 270bb8744cc..805378c1ffc 100644
--- a/code/modules/projectiles/guns/special/syringe_gun.dm
+++ b/code/modules/projectiles/guns/special/syringe_gun.dm
@@ -206,6 +206,6 @@
/obj/item/gun/syringe/blowgun/process_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0)
visible_message(span_danger("[user] shoots the blowgun!"))
- user.adjustStaminaLoss(20)
+ user.adjustStaminaLoss(20, updating_stamina = FALSE)
user.adjustOxyLoss(20)
return ..()
diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm
index 503560aa224..b03a736e3f8 100644
--- a/code/modules/reagents/chemistry/holder.dm
+++ b/code/modules/reagents/chemistry/holder.dm
@@ -470,7 +470,7 @@
* Check if this holder contains this reagent.
* Reagent takes a PATH to a reagent.
* Amount checks for having a specific amount of that chemical.
- * Needs matabolizing takes into consideration if the chemical is matabolizing when it's checked.
+ * Needs matabolizing takes into consideration if the chemical is metabolizing when it's checked.
* Check subtypes controls whether it should it should also include subtypes: ispath(type, reagent) versus type == reagent.
*/
/datum/reagents/proc/has_reagent(reagent, amount = -1, needs_metabolizing = FALSE, check_subtypes = FALSE)
diff --git a/code/modules/reagents/chemistry/machinery/chem_master.dm b/code/modules/reagents/chemistry/machinery/chem_master.dm
index 0a49fd1beb1..9d33cccd56c 100644
--- a/code/modules/reagents/chemistry/machinery/chem_master.dm
+++ b/code/modules/reagents/chemistry/machinery/chem_master.dm
@@ -46,9 +46,10 @@ GLOBAL_LIST_INIT(chem_master_containers, list(
/obj/item/reagent_containers/pill/patch/style
)),
// SKYRAT EDIT ADDITION START
- CAT_HYPOS = typecacheof(list(
- /obj/item/reagent_containers/cup/vial
- )),
+ CAT_HYPOS = list(
+ /obj/item/reagent_containers/cup/vial/small,
+ /obj/item/reagent_containers/cup/vial/large,
+ ),
CAT_DARTS = typecacheof(list(
/obj/item/reagent_containers/syringe/smartdart
))
diff --git a/code/modules/reagents/chemistry/reagents.dm b/code/modules/reagents/chemistry/reagents.dm
index 110107d103f..46ac1eda360 100644
--- a/code/modules/reagents/chemistry/reagents.dm
+++ b/code/modules/reagents/chemistry/reagents.dm
@@ -50,8 +50,6 @@ GLOBAL_LIST_INIT(blacklisted_metalgen_types, typecacheof(list(
var/color = "#000000" // rgb: 0, 0, 0
///how fast the reagent is metabolized by the mob
var/metabolization_rate = REAGENTS_METABOLISM
- /// appears unused
- var/overrides_metab = 0
/// above this overdoses happen
var/overdose_threshold = 0
/// You fucked up and this is now triggering its overdose effects, purge that shit quick.
@@ -159,12 +157,27 @@ GLOBAL_LIST_INIT(blacklisted_metalgen_types, typecacheof(list(
/datum/reagent/proc/burn(datum/reagents/holder)
return
-/// Called from [/datum/reagents/proc/metabolize]
-/datum/reagent/proc/on_mob_life(mob/living/carbon/M, seconds_per_tick, times_fired)
+/**
+ * Ticks on mob Life() for as long as the reagent remains in the mob's reagents.
+ *
+ * Usage: Parent should be called first using . = ..()
+ *
+ * Exceptions: If the holder var needs to be accessed, call the parent afterward that as it can become null if the reagent is fully removed.
+ *
+ * Returns: UPDATE_MOB_HEALTH only if you need to update the health of a mob (this is only needed when damage is dealt to the mob)
+ *
+ * Arguments
+ * * mob/living/carbon/affected_mob - the mob which the reagent currently is inside of
+ * * seconds_per_tick - the time in server seconds between proc calls (when performing normally it will be 2)
+ * * times_fired - the number of times the owner's Life() tick has been called aka The number of times SSmobs has fired
+ *
+ */
+/datum/reagent/proc/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
current_cycle++
if(length(reagent_removal_skip_list))
return
- holder.remove_reagent(type, metabolization_rate * M.metabolism_efficiency * seconds_per_tick) //By default it slowly disappears.
+ if(holder)
+ holder.remove_reagent(type, metabolization_rate * affected_mob.metabolism_efficiency * seconds_per_tick) //By default it slowly disappears.
/// Called in burns.dm *if* the reagent has the REAGENT_AFFECTS_WOUNDS process flag
/datum/reagent/proc/on_burn_wound_processing(datum/wound/burn/flesh/burn_wound)
@@ -182,34 +195,35 @@ Primarily used in reagents/reaction_agents
return
/// Called when this reagent is first added to a mob
-/datum/reagent/proc/on_mob_add(mob/living/L, amount)
+/datum/reagent/proc/on_mob_add(mob/living/affected_mob, amount)
overdose_threshold /= max(normalise_creation_purity(), 1) //Maybe??? Seems like it would help pure chems be even better but, if I normalised this to 1, then everything would take a 25% reduction
return
/// Called when this reagent is removed while inside a mob
-/datum/reagent/proc/on_mob_delete(mob/living/L)
- L.clear_mood_event("[type]_overdose")
+/datum/reagent/proc/on_mob_delete(mob/living/affected_mob)
+ affected_mob.clear_mood_event("[type]_overdose")
return
/// Called when this reagent first starts being metabolized by a liver
-/datum/reagent/proc/on_mob_metabolize(mob/living/L)
+/datum/reagent/proc/on_mob_metabolize(mob/living/affected_mob)
return
/// Called when this reagent stops being metabolized by a liver
-/datum/reagent/proc/on_mob_end_metabolize(mob/living/L)
+/datum/reagent/proc/on_mob_end_metabolize(mob/living/affected_mob)
return
-/// Called when a reagent is inside of a mob when they are dead
-/datum/reagent/proc/on_mob_dead(mob/living/carbon/C, seconds_per_tick)
+/// Called when a reagent is inside of a mob when they are dead. Returning UPDATE_MOB_HEALTH will cause updatehealth() to be called on the holder mob by /datum/reagents/proc/metabolize.
+/datum/reagent/proc/on_mob_dead(mob/living/carbon/affected_mob, seconds_per_tick)
if(!(chemical_flags & REAGENT_DEAD_PROCESS))
return
current_cycle++
if(length(reagent_removal_skip_list))
return
- holder.remove_reagent(type, metabolization_rate * C.metabolism_efficiency * seconds_per_tick)
+ if(holder)
+ holder.remove_reagent(type, metabolization_rate * affected_mob.metabolism_efficiency * seconds_per_tick)
/// Called by [/datum/reagents/proc/conditional_update_move]
-/datum/reagent/proc/on_move(mob/M)
+/datum/reagent/proc/on_move(mob/affected_mob)
return
/// Called after add_reagents creates a new reagent.
@@ -225,14 +239,14 @@ Primarily used in reagents/reaction_agents
/datum/reagent/proc/on_update(atom/A)
return
-/// Called if the reagent has passed the overdose threshold and is set to be triggering overdose effects
-/datum/reagent/proc/overdose_process(mob/living/M, seconds_per_tick, times_fired)
+/// Called if the reagent has passed the overdose threshold and is set to be triggering overdose effects. Returning UPDATE_MOB_HEALTH will cause updatehealth() to be called on the holder mob by /datum/reagents/proc/metabolize.
+/datum/reagent/proc/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired)
return
-/// Called when an overdose starts
-/datum/reagent/proc/overdose_start(mob/living/M)
- to_chat(M, span_userdanger("You feel like you took too much of [name]!"))
- M.add_mood_event("[type]_overdose", /datum/mood_event/overdose, name)
+/// Called when an overdose starts. Returning UPDATE_MOB_HEALTH will cause updatehealth() to be called on the holder mob by /datum/reagents/proc/metabolize.
+/datum/reagent/proc/overdose_start(mob/living/affected_mob)
+ to_chat(affected_mob, span_userdanger("You feel like you took too much of [name]!"))
+ affected_mob.add_mood_event("[type]_overdose", /datum/mood_event/overdose, name)
return
/**
diff --git a/code/modules/reagents/chemistry/reagents/atmos_gas_reagents.dm b/code/modules/reagents/chemistry/reagents/atmos_gas_reagents.dm
index 817e5ed98bf..4550edbdfdf 100644
--- a/code/modules/reagents/chemistry/reagents/atmos_gas_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/atmos_gas_reagents.dm
@@ -12,8 +12,8 @@
breather.add_movespeed_modifier(/datum/movespeed_modifier/reagent/freon)
/datum/reagent/freon/on_mob_end_metabolize(mob/living/breather)
+ . = ..()
breather.remove_movespeed_modifier(/datum/movespeed_modifier/reagent/freon)
- return ..()
/datum/reagent/halon
name = "Halon"
@@ -30,9 +30,9 @@
ADD_TRAIT(breather, TRAIT_RESISTHEAT, type)
/datum/reagent/halon/on_mob_end_metabolize(mob/living/breather)
+ . = ..()
breather.remove_movespeed_modifier(/datum/movespeed_modifier/reagent/halon)
REMOVE_TRAIT(breather, TRAIT_RESISTHEAT, type)
- return ..()
/datum/reagent/healium
name = "Healium"
@@ -44,16 +44,18 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_NO_RANDOM_RECIPE
/datum/reagent/healium/on_mob_end_metabolize(mob/living/breather)
+ . = ..()
breather.SetSleeping(1 SECONDS)
- return ..()
/datum/reagent/healium/on_mob_life(mob/living/breather, seconds_per_tick, times_fired)
- breather.SetSleeping(30 SECONDS)
- breather.adjustFireLoss(-2 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype)
- breather.adjustToxLoss(-5 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
- breather.adjustBruteLoss(-2 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype)
. = ..()
- return TRUE
+ breather.SetSleeping(30 SECONDS)
+ var/need_mob_update
+ need_mob_update = breather.adjustFireLoss(-2 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
+ need_mob_update += breather.adjustToxLoss(-5 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)
+ need_mob_update += breather.adjustBruteLoss(-2 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/hypernoblium
name = "Hyper-Noblium"
@@ -65,9 +67,9 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_NO_RANDOM_RECIPE
/datum/reagent/hypernoblium/on_mob_life(mob/living/carbon/breather, seconds_per_tick, times_fired)
+ . = ..()
if(isplasmaman(breather))
breather.set_timed_status_effect(10 SECONDS * REM * seconds_per_tick, /datum/status_effect/hypernob_protection)
- ..()
/datum/reagent/nitrium_high_metabolization
name = "Nitrosyl plasmide"
@@ -85,14 +87,16 @@
ADD_TRAIT(breather, TRAIT_SLEEPIMMUNE, type)
/datum/reagent/nitrium_high_metabolization/on_mob_end_metabolize(mob/living/breather)
+ . = ..()
REMOVE_TRAIT(breather, TRAIT_SLEEPIMMUNE, type)
- return ..()
/datum/reagent/nitrium_high_metabolization/on_mob_life(mob/living/carbon/breather, seconds_per_tick, times_fired)
- breather.adjustStaminaLoss(-2 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
- breather.adjustToxLoss(0.1 * current_cycle * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) // 1 toxin damage per cycle at cycle 10
. = ..()
- return TRUE
+ var/need_mob_update
+ need_mob_update = breather.adjustStaminaLoss(-2 * REM * seconds_per_tick, updating_stamina = FALSE, required_biotype = affected_biotype)
+ need_mob_update += breather.adjustToxLoss(0.1 * (current_cycle-1) * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype) // 1 toxin damage per cycle at cycle 10
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/nitrium_low_metabolization
name = "Nitrium"
@@ -109,8 +113,8 @@
breather.add_movespeed_modifier(/datum/movespeed_modifier/reagent/nitrium)
/datum/reagent/nitrium_low_metabolization/on_mob_end_metabolize(mob/living/breather)
+ . = ..()
breather.remove_movespeed_modifier(/datum/movespeed_modifier/reagent/nitrium)
- return ..()
/datum/reagent/pluoxium
name = "Pluoxium"
@@ -122,18 +126,17 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_NO_RANDOM_RECIPE
/datum/reagent/pluoxium/on_mob_life(mob/living/carbon/breather, seconds_per_tick, times_fired)
+ . = ..()
if(!HAS_TRAIT(breather, TRAIT_KNOCKEDOUT))
- return ..()
+ return
. = ..()
for(var/obj/item/organ/organ_being_healed as anything in breather.organs)
if(!organ_being_healed.damage)
continue
- organ_being_healed.apply_organ_damage(-0.5 * REM * seconds_per_tick, required_organ_flag = ORGAN_ORGANIC)
- . = TRUE
-
- return .
+ if(organ_being_healed.apply_organ_damage(-0.5 * REM * seconds_per_tick, required_organ_flag = ORGAN_ORGANIC))
+ return UPDATE_MOB_HEALTH
/datum/reagent/zauker
name = "Zauker"
@@ -147,9 +150,11 @@
affected_respiration_type = ALL
/datum/reagent/zauker/on_mob_life(mob/living/breather, seconds_per_tick, times_fired)
- breather.adjustBruteLoss(6 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype)
- breather.adjustOxyLoss(1 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
- breather.adjustFireLoss(2 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype)
- breather.adjustToxLoss(2 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
- ..()
- return TRUE
+ . = ..()
+ var/need_mob_update
+ need_mob_update = breather.adjustBruteLoss(6 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
+ need_mob_update += breather.adjustOxyLoss(1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
+ need_mob_update += breather.adjustFireLoss(2 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
+ need_mob_update += breather.adjustToxLoss(2 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
diff --git a/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm
index 693404431fa..53558cbd820 100644
--- a/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm
@@ -27,21 +27,23 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/medicine/c2/helbital/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
- . = TRUE
var/death_is_coming = (affected_mob.getToxLoss() + affected_mob.getOxyLoss() + affected_mob.getFireLoss() + affected_mob.getBruteLoss())*normalise_creation_purity()
var/thou_shall_heal = 0
var/good_kind_of_healing = FALSE
+ var/need_mob_update = FALSE
switch(affected_mob.stat)
if(CONSCIOUS) //bad
thou_shall_heal = death_is_coming/50
- affected_mob.adjustOxyLoss(2 * REM * seconds_per_tick, TRUE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
+ need_mob_update += affected_mob.adjustOxyLoss(2 * REM * seconds_per_tick, TRUE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
if(SOFT_CRIT) //meh convert
thou_shall_heal = round(death_is_coming/47,0.1)
- affected_mob.adjustOxyLoss(1 * REM * seconds_per_tick, TRUE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
+ need_mob_update += affected_mob.adjustOxyLoss(1 * REM * seconds_per_tick, TRUE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
else //no convert
thou_shall_heal = round(death_is_coming/45, 0.1)
good_kind_of_healing = TRUE
- affected_mob.adjustBruteLoss(-thou_shall_heal * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype)
+ need_mob_update += affected_mob.adjustBruteLoss(-thou_shall_heal * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype)
+ if(need_mob_update)
+ . = UPDATE_MOB_HEALTH
if(good_kind_of_healing && !reaping && SPT_PROB(0.00005, seconds_per_tick)) //janken with the grim reaper!
notify_ghosts("[affected_mob] has entered a game of rock-paper-scissors with death!", source = affected_mob, action = NOTIFY_ORBIT, header = "Who Will Win?")
@@ -73,21 +75,18 @@
affected_mob.revive(HEAL_ALL)
holder.del_reagent(type)
return
-
- ..()
- return
+ return ..() || .
/datum/reagent/medicine/c2/helbital/overdose_process(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
if(!helbent)
affected_mob.apply_necropolis_curse(CURSE_WASTING | CURSE_BLINDING)
helbent = TRUE
- ..()
- return TRUE
-/datum/reagent/medicine/c2/helbital/on_mob_delete(mob/living/L)
+/datum/reagent/medicine/c2/helbital/on_mob_delete(mob/living/affected_mob)
+ . = ..()
if(helbent)
- L.remove_status_effect(/datum/status_effect/necropolis_curse)
- ..()
+ affected_mob.remove_status_effect(/datum/status_effect/necropolis_curse)
/datum/reagent/medicine/c2/libital //messes with your liber
name = "Libital"
@@ -99,10 +98,12 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/medicine/c2/libital/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
- affected_mob.adjustOrganLoss(ORGAN_SLOT_LIVER, 0.3 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)
- affected_mob.adjustBruteLoss(-3 * REM * normalise_creation_purity() * seconds_per_tick, required_bodytype = affected_bodytype)
- ..()
- return TRUE
+ . = ..()
+ var/need_mob_update
+ need_mob_update = affected_mob.adjustOrganLoss(ORGAN_SLOT_LIVER, 0.3 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)
+ need_mob_update += affected_mob.adjustBruteLoss(-3 * REM * normalise_creation_purity() * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/medicine/c2/probital
name = "Probital"
@@ -116,7 +117,9 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/medicine/c2/probital/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
- affected_mob.adjustBruteLoss(-2.25 * REM * normalise_creation_purity() * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
+ . = ..()
+ var/need_mob_update
+ need_mob_update = affected_mob.adjustBruteLoss(-2.25 * REM * normalise_creation_purity() * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
var/ooo_youaregettingsleepy = 3.5
switch(round(affected_mob.getStaminaLoss()))
if(10 to 40)
@@ -125,20 +128,22 @@
ooo_youaregettingsleepy = 2.5
if(61 to 200) //you really can only go to 120
ooo_youaregettingsleepy = 2
- affected_mob.adjustStaminaLoss(ooo_youaregettingsleepy * REM * seconds_per_tick)
- ..()
- . = TRUE
+ need_mob_update += affected_mob.adjustStaminaLoss(ooo_youaregettingsleepy * REM * seconds_per_tick, updating_stamina = FALSE)
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/medicine/c2/probital/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired)
- affected_mob.adjustStaminaLoss(3 * REM * seconds_per_tick, updating_stamina = FALSE)
+ . = ..()
+ var/need_mob_update
+ need_mob_update = affected_mob.adjustStaminaLoss(3 * REM * seconds_per_tick, updating_stamina = FALSE)
if(affected_mob.getStaminaLoss() >= 80)
affected_mob.adjust_drowsiness(2 SECONDS * REM * seconds_per_tick)
if(affected_mob.getStaminaLoss() >= 100)
to_chat(affected_mob,span_warning("You feel more tired than you usually do, perhaps if you rest your eyes for a bit..."))
- affected_mob.adjustStaminaLoss(-100, updating_stamina = TRUE) // Don't add the biotype parameter here as it results in infinite sleep and chat spam.
+ need_mob_update += affected_mob.adjustStaminaLoss(-100, updating_stamina = FALSE) // Don't add the biotype parameter here as it results in infinite sleep and chat spam.
affected_mob.Sleeping(10 SECONDS)
- ..()
- . = TRUE
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/medicine/c2/probital/on_transfer(atom/A, methods=INGEST, trans_volume)
if(!(methods & INGEST) || (!iscarbon(A) && !istype(A, /obj/item/organ/internal/stomach)) )
@@ -162,10 +167,12 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/medicine/c2/lenturi/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
- affected_mob.adjustFireLoss(-3 * REM * normalise_creation_purity() * seconds_per_tick, required_bodytype = affected_bodytype)
- affected_mob.adjustOrganLoss(ORGAN_SLOT_STOMACH, 0.4 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)
- ..()
- return TRUE
+ . = ..()
+ var/need_mob_update
+ need_mob_update = affected_mob.adjustFireLoss(-3 * REM * normalise_creation_purity() * seconds_per_tick, required_bodytype = affected_bodytype)
+ need_mob_update += affected_mob.adjustOrganLoss(ORGAN_SLOT_STOMACH, 0.4 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/medicine/c2/aiuri
name = "Aiuri"
@@ -178,10 +185,12 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/medicine/c2/aiuri/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
- affected_mob.adjustFireLoss(-2 * REM * normalise_creation_purity() * seconds_per_tick, required_bodytype = affected_bodytype)
- affected_mob.adjustOrganLoss(ORGAN_SLOT_EYES, 0.25 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)
- ..()
- return TRUE
+ . = ..()
+ var/need_mob_update
+ need_mob_update = affected_mob.adjustFireLoss(-2 * REM * normalise_creation_purity() * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
+ need_mob_update += affected_mob.adjustOrganLoss(ORGAN_SLOT_EYES, 0.25 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/medicine/c2/hercuri
name = "Hercuri"
@@ -196,18 +205,20 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/medicine/c2/hercuri/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
+ var/need_mob_update
if(affected_mob.getFireLoss() > 50)
- affected_mob.adjustFireLoss(-2 * REM * seconds_per_tick * normalise_creation_purity(), FALSE, required_bodytype = affected_bodytype)
+ need_mob_update = affected_mob.adjustFireLoss(-2 * REM * seconds_per_tick * normalise_creation_purity(), updating_health = FALSE, required_bodytype = affected_bodytype)
else
- affected_mob.adjustFireLoss(-1.25 * REM * seconds_per_tick * normalise_creation_purity(), FALSE, required_bodytype = affected_bodytype)
+ need_mob_update = affected_mob.adjustFireLoss(-1.25 * REM * seconds_per_tick * normalise_creation_purity(), updating_health = FALSE, required_bodytype = affected_bodytype)
affected_mob.adjust_bodytemperature(rand(-25,-5) * TEMPERATURE_DAMAGE_COEFFICIENT * REM * seconds_per_tick, 50)
if(ishuman(affected_mob))
var/mob/living/carbon/human/humi = affected_mob
humi.adjust_coretemperature(rand(-25,-5) * TEMPERATURE_DAMAGE_COEFFICIENT * REM * seconds_per_tick, 50)
affected_mob.reagents?.chem_temp += (-10 * REM * seconds_per_tick)
affected_mob.adjust_fire_stacks(-1 * REM * seconds_per_tick)
- ..()
- . = TRUE
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/medicine/c2/hercuri/expose_mob(mob/living/carbon/exposed_mob, methods=VAPOR, reac_volume)
. = ..()
@@ -220,11 +231,11 @@
exposed_mob.extinguish_mob()
/datum/reagent/medicine/c2/hercuri/overdose_process(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
affected_mob.adjust_bodytemperature(-10 * TEMPERATURE_DAMAGE_COEFFICIENT * REM * seconds_per_tick, 50) //chilly chilly
if(ishuman(affected_mob))
var/mob/living/carbon/human/humi = affected_mob
humi.adjust_coretemperature(-10 * TEMPERATURE_DAMAGE_COEFFICIENT * REM * seconds_per_tick, 50)
- ..()
/******OXY******/
@@ -243,20 +254,22 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/medicine/c2/convermol/on_mob_life(mob/living/carbon/human/affected_mob, seconds_per_tick, times_fired)
- var/oxycalc = 2.5 * REM * current_cycle
+ . = ..()
+ var/oxycalc = 2.5 * REM * (current_cycle-1)
if(!overdosed)
oxycalc = min(oxycalc, affected_mob.getOxyLoss() + 0.5) //if NOT overdosing, we lower our toxdamage to only the damage we actually healed with a minimum of 0.1*current_cycle. IE if we only heal 10 oxygen damage but we COULD have healed 20, we will only take toxdamage for the 10. We would take the toxdamage for the extra 10 if we were overdosing.
- affected_mob.adjustOxyLoss(-oxycalc * seconds_per_tick * normalise_creation_purity(), FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
- affected_mob.adjustToxLoss(oxycalc * seconds_per_tick / CONVERMOL_RATIO, FALSE, required_biotype = affected_biotype)
- if(SPT_PROB(current_cycle / 2, seconds_per_tick) && affected_mob.losebreath)
+ var/need_mob_update
+ need_mob_update = affected_mob.adjustOxyLoss(-oxycalc * seconds_per_tick * normalise_creation_purity(), FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
+ need_mob_update += affected_mob.adjustToxLoss(oxycalc * seconds_per_tick / CONVERMOL_RATIO, updating_health = FALSE, required_biotype = affected_biotype)
+ if(SPT_PROB((current_cycle-1) / 2, seconds_per_tick) && affected_mob.losebreath)
affected_mob.losebreath--
- ..()
- return TRUE
+ need_mob_update = TRUE
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/medicine/c2/convermol/overdose_process(mob/living/carbon/human/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
metabolization_rate += 2.5 * REAGENTS_METABOLISM
- ..()
- return TRUE
#undef CONVERMOL_RATIO
@@ -273,20 +286,22 @@
COOLDOWN_DECLARE(drowsycd)
/datum/reagent/medicine/c2/tirimol/on_mob_life(mob/living/carbon/human/affected_mob, seconds_per_tick, times_fired)
- affected_mob.adjustOxyLoss(-3 * REM * seconds_per_tick * normalise_creation_purity(), required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
- affected_mob.adjustStaminaLoss(2 * REM * seconds_per_tick, required_biotype = affected_biotype)
+ . = ..()
+ var/need_mob_update
+ need_mob_update = affected_mob.adjustOxyLoss(-3 * REM * seconds_per_tick * normalise_creation_purity(), updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
+ need_mob_update += affected_mob.adjustStaminaLoss(2 * REM * seconds_per_tick, updating_stamina = FALSE, required_biotype = affected_biotype)
if(drowsycd && COOLDOWN_FINISHED(src, drowsycd))
affected_mob.adjust_drowsiness(20 SECONDS)
COOLDOWN_START(src, drowsycd, 45 SECONDS)
else if(!drowsycd)
COOLDOWN_START(src, drowsycd, 15 SECONDS)
- ..()
- return TRUE
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
-/datum/reagent/medicine/c2/tirimol/on_mob_end_metabolize(mob/living/L)
- if(current_cycle > 20)
- L.Sleeping(10 SECONDS)
- ..()
+/datum/reagent/medicine/c2/tirimol/on_mob_end_metabolize(mob/living/affected_mob)
+ . = ..()
+ if(current_cycle > 21)
+ affected_mob.Sleeping(10 SECONDS)
/******TOXIN******/
/*Suffix: -iver*/
@@ -307,14 +322,16 @@
rads_heal_threshold = rand(rads_heal_threshold - 50, rads_heal_threshold + 50) // Basically this means 50K and below will always give the radiation heal, and upto 150K could. Calculated once.
/datum/reagent/medicine/c2/seiver/on_mob_life(mob/living/carbon/human/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
var/chemtemp = min(holder.chem_temp, 1000)
chemtemp = chemtemp ? chemtemp : T0C //why do you have null sweaty
var/healypoints = 0 //5 healypoints = 1 heart damage; 5 rads = 1 tox damage healed for the purpose of healypoints
//you're hot
var/toxcalc = min(round(5 + ((chemtemp-1000)/175), 0.1), 5) * REM * seconds_per_tick * normalise_creation_purity() //max 2.5 tox healing per second
+ var/need_mob_update
if(toxcalc > 0)
- affected_mob.adjustToxLoss(-toxcalc, required_biotype = affected_biotype)
+ need_mob_update = affected_mob.adjustToxLoss(-toxcalc, updating_health = FALSE, required_biotype = affected_biotype)
healypoints += toxcalc
//and you're cold
@@ -323,16 +340,16 @@
radcalc *= normalise_creation_purity()
// extra rad healing if you are SUPER cold
if(chemtemp < rads_heal_threshold*0.1)
- affected_mob.adjustToxLoss(-radcalc * 0.9, required_biotype = affected_biotype)
+ need_mob_update += affected_mob.adjustToxLoss(-radcalc * 0.9, updating_health = FALSE, required_biotype = affected_biotype)
else if(chemtemp < rads_heal_threshold)
- affected_mob.adjustToxLoss(-radcalc * 0.75, required_biotype = affected_biotype)
+ need_mob_update += affected_mob.adjustToxLoss(-radcalc * 0.75, updating_health = FALSE, required_biotype = affected_biotype)
healypoints += (radcalc / 5)
//you're yes and... oh no!
healypoints = round(healypoints, 0.1)
affected_mob.adjustOrganLoss(ORGAN_SLOT_HEART, healypoints / 5, required_organ_flag = affected_organ_flags)
- ..()
- return TRUE
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/medicine/c2/multiver //enhanced with MULTIple medicines
name = "Multiver"
@@ -343,6 +360,7 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/medicine/c2/multiver/on_mob_life(mob/living/carbon/human/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
var/medibonus = 0 //it will always have itself which makes it REALLY start @ 1
for(var/r in affected_mob.reagents.reagent_list)
var/datum/reagent/the_reagent = r
@@ -350,8 +368,9 @@
medibonus += 1
if(creation_purity >= 1) //Perfectly pure multivers gives a bonus of 2!
medibonus += 1
- affected_mob.adjustToxLoss(-0.5 * min(medibonus, 3 * normalise_creation_purity()) * REM * seconds_per_tick, required_biotype = affected_biotype) //not great at healing but if you have nothing else it will work
- affected_mob.adjustOrganLoss(ORGAN_SLOT_LUNGS, 0.5 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) //kills at 40u
+ var/need_mob_update
+ need_mob_update = affected_mob.adjustToxLoss(-0.5 * min(medibonus, 3 * normalise_creation_purity()) * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype) //not great at healing but if you have nothing else it will work
+ need_mob_update += affected_mob.adjustOrganLoss(ORGAN_SLOT_LUNGS, 0.5 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) //kills at 40u
for(var/r2 in affected_mob.reagents.reagent_list)
var/datum/reagent/the_reagent2 = r2
if(the_reagent2 == src)
@@ -360,8 +379,8 @@
if(medibonus >= 3 && istype(the_reagent2, /datum/reagent/medicine)) //3 unique meds (2+multiver) | (1 + pure multiver) will make it not purge medicines
continue
affected_mob.reagents.remove_reagent(the_reagent2.type, amount2purge * REM * seconds_per_tick)
- ..()
- return TRUE
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
// Antitoxin binds plants pretty well. So the tox goes significantly down
/datum/reagent/medicine/c2/multiver/on_hydroponics_apply(obj/machinery/hydroponics/mytray, mob/user)
@@ -385,7 +404,7 @@
return
var/mob/living/carbon/C = A
if(trans_volume >= 0.6) //prevents cheesing with ultralow doses.
- C.adjustToxLoss((-1.5 * min(2, trans_volume) * REM) * normalise_creation_purity(), FALSE, required_biotype = affected_biotype) //This is to promote iv pole use for that chemotherapy feel.
+ C.adjustToxLoss((-1.5 * min(2, trans_volume) * REM) * normalise_creation_purity(), required_biotype = affected_biotype) //This is to promote iv pole use for that chemotherapy feel.
var/obj/item/organ/internal/liver/L = C.organs_slot[ORGAN_SLOT_LIVER]
if(!L || L.organ_flags & ORGAN_FAILING)
return
@@ -395,22 +414,24 @@
..()
/datum/reagent/medicine/c2/syriniver/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
- affected_mob.adjustOrganLoss(ORGAN_SLOT_LIVER, 0.8 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)
- affected_mob.adjustToxLoss(-1 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
+ . = ..()
+ var/need_mob_update
+ need_mob_update = affected_mob.adjustOrganLoss(ORGAN_SLOT_LIVER, 0.8 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)
+ need_mob_update += affected_mob.adjustToxLoss(-1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)
for(var/datum/reagent/R in affected_mob.reagents.reagent_list)
if(issyrinormusc(R))
continue
affected_mob.reagents.remove_reagent(R.type, 0.4 * REM * seconds_per_tick)
- ..()
- . = TRUE
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/medicine/c2/syriniver/overdose_process(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
- affected_mob.adjustOrganLoss(ORGAN_SLOT_LIVER, 1.5 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)
+ . = ..()
+ if(affected_mob.adjustOrganLoss(ORGAN_SLOT_LIVER, 1.5 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags))
+ . = UPDATE_MOB_HEALTH
affected_mob.adjust_disgust(3 * REM * seconds_per_tick)
affected_mob.reagents.add_reagent(/datum/reagent/medicine/c2/musiver, 0.225 * REM * seconds_per_tick)
- ..()
- . = TRUE
/datum/reagent/medicine/c2/musiver //MUScles
name = "Musiver"
@@ -424,30 +445,32 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/medicine/c2/musiver/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
- affected_mob.adjustOrganLoss(ORGAN_SLOT_LIVER, 0.1 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)
- affected_mob.adjustToxLoss(-1 * REM * seconds_per_tick * normalise_creation_purity(), FALSE, required_biotype = affected_biotype)
+ . = ..()
+ var/need_mob_update
+ need_mob_update = affected_mob.adjustOrganLoss(ORGAN_SLOT_LIVER, 0.1 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)
+ need_mob_update += affected_mob.adjustToxLoss(-1 * REM * seconds_per_tick * normalise_creation_purity(), updating_health = FALSE, required_biotype = affected_biotype)
for(var/datum/reagent/R in affected_mob.reagents.reagent_list)
if(issyrinormusc(R))
continue
affected_mob.reagents.remove_reagent(R.type, 0.2 * REM * seconds_per_tick)
- ..()
- . = TRUE
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/medicine/c2/musiver/overdose_start(mob/living/carbon/affected_mob)
+ . = ..()
trauma = new()
affected_mob.gain_trauma(trauma, TRAUMA_RESILIENCE_ABSOLUTE)
- ..()
-/datum/reagent/medicine/c2/musiver/on_mob_delete(mob/living/carbon/affected_mob)
+/datum/reagent/medicine/c2/musiver/on_mob_delete(mob/living/affected_mob)
+ . = ..()
if(trauma)
QDEL_NULL(trauma)
- return ..()
/datum/reagent/medicine/c2/musiver/overdose_process(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
- affected_mob.adjustOrganLoss(ORGAN_SLOT_LIVER, 1.5 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)
+ . = ..()
+ if(affected_mob.adjustOrganLoss(ORGAN_SLOT_LIVER, 1.5 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags))
+ . = UPDATE_MOB_HEALTH
affected_mob.adjust_disgust(3 * REM * seconds_per_tick)
- ..()
- . = TRUE
#undef issyrinormusc
/******COMBOS******/
@@ -469,14 +492,19 @@
show_message = 0
if(!(methods & (PATCH|TOUCH|VAPOR)))
return
- var/harmies = min(carbies.getBruteLoss(), carbies.adjustBruteLoss(-1.25 * reac_volume, required_bodytype = affected_bodytype)*-1)
- var/burnies = min(carbies.getFireLoss(), carbies.adjustFireLoss(-1.25 * reac_volume, required_bodytype = affected_bodytype)*-1)
+ var/harmies = min(carbies.getBruteLoss(), carbies.adjustBruteLoss(-1.25 * reac_volume, updating_health = FALSE, required_bodytype = affected_bodytype)*-1)
+ var/burnies = min(carbies.getFireLoss(), carbies.adjustFireLoss(-1.25 * reac_volume, updating_health = FALSE, required_bodytype = affected_bodytype)*-1)
for(var/i in carbies.all_wounds)
var/datum/wound/iter_wound = i
iter_wound.on_synthflesh(reac_volume)
- carbies.adjustToxLoss((harmies+burnies)*(0.5 + (0.25*(1-creation_purity))), required_biotype = affected_biotype) //0.5 - 0.75
+ var/need_mob_update = harmies + burnies
+ need_mob_update += carbies.adjustToxLoss((harmies+burnies)*(0.5 + (0.25*(1-creation_purity))), updating_health = FALSE, required_biotype = affected_biotype) //0.5 - 0.75
+
+ if(need_mob_update)
+ carbies.updatehealth()
if(show_message)
to_chat(carbies, span_danger("You feel your burns and bruises healing! It stings like hell!"))
+
carbies.add_mood_event("painful_medicine", /datum/mood_event/painful_medicine)
if(HAS_TRAIT_FROM(exposed_mob, TRAIT_HUSK, BURN) && carbies.getFireLoss() < UNHUSK_DAMAGE_THRESHOLD && (carbies.reagents.get_reagent_amount(/datum/reagent/medicine/c2/synthflesh) + reac_volume >= SYNTHFLESH_UNHUSK_AMOUNT))
carbies.cure_husk(BURN)
@@ -526,45 +554,51 @@
user.throw_alert("penthrite", /atom/movable/screen/alert/penthrite)
user.add_traits(subject_traits, type)
-/datum/reagent/medicine/c2/penthrite/on_mob_life(mob/living/carbon/human/H, seconds_per_tick, times_fired)
- H.adjustStaminaLoss(-25 * REM) //SKYRAT EDIT ADDITION - COMBAT - makes your heart beat faster, fills you with energy. For miners
- H.adjustOrganLoss(ORGAN_SLOT_STOMACH, 0.25 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)
- if(H.health <= HEALTH_THRESHOLD_CRIT && H.health > (H.crit_threshold + HEALTH_THRESHOLD_FULLCRIT * (2 * normalise_creation_purity()))) //we cannot save someone below our lowered crit threshold.
+/datum/reagent/medicine/c2/penthrite/on_mob_life(mob/living/carbon/human/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
+ var/need_mob_update
+ need_mob_update = affected_mob.adjustStaminaLoss(-12.5 * REM * seconds_per_tick, updating_stamina = FALSE) //SKYRAT EDIT ADDITION - COMBAT - makes your heart beat faster, fills you with energy. For miners
+ need_mob_update = affected_mob.adjustOrganLoss(ORGAN_SLOT_STOMACH, 0.25 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)
+ if(affected_mob.health <= HEALTH_THRESHOLD_CRIT && affected_mob.health > (affected_mob.crit_threshold + HEALTH_THRESHOLD_FULLCRIT * (2 * normalise_creation_purity()))) //we cannot save someone below our lowered crit threshold.
- H.adjustToxLoss(-2 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
- H.adjustBruteLoss(-2 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype)
- H.adjustFireLoss(-2 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype)
- H.adjustOxyLoss(-6 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
+ need_mob_update += affected_mob.adjustToxLoss(-2 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)
+ need_mob_update += affected_mob.adjustBruteLoss(-2 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
+ need_mob_update += affected_mob.adjustFireLoss(-2 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
+ need_mob_update += affected_mob.adjustOxyLoss(-6 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
- H.losebreath = 0
+ affected_mob.losebreath = 0
- H.adjustOrganLoss(ORGAN_SLOT_HEART, max(volume/10, 1) * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) // your heart is barely keeping up!
+ need_mob_update += affected_mob.adjustOrganLoss(ORGAN_SLOT_HEART, max(volume/10, 1) * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) // your heart is barely keeping up!
- H.set_jitter_if_lower(rand(0 SECONDS, 4 SECONDS) * REM * seconds_per_tick)
- H.set_dizzy_if_lower(rand(0 SECONDS, 4 SECONDS) * REM * seconds_per_tick)
+ affected_mob.set_jitter_if_lower(rand(0 SECONDS, 4 SECONDS) * REM * seconds_per_tick)
+ affected_mob.set_dizzy_if_lower(rand(0 SECONDS, 4 SECONDS) * REM * seconds_per_tick)
if(SPT_PROB(18, seconds_per_tick))
- to_chat(H,span_danger("Your body is trying to give up, but your heart is still beating!"))
+ to_chat(affected_mob,span_danger("Your body is trying to give up, but your heart is still beating!"))
- if(H.health <= (H.crit_threshold + HEALTH_THRESHOLD_FULLCRIT*(2*normalise_creation_purity()))) //certain death below this threshold
- REMOVE_TRAIT(H, TRAIT_STABLEHEART, type) //we have to remove the stable heart trait before we give them a heart attack
- to_chat(H,span_danger("You feel something rupturing inside your chest!"))
- H.emote("scream")
- H.set_heartattack(TRUE)
+ if(affected_mob.health <= (affected_mob.crit_threshold + HEALTH_THRESHOLD_FULLCRIT*(2*normalise_creation_purity()))) //certain death below this threshold
+ REMOVE_TRAIT(affected_mob, TRAIT_STABLEHEART, type) //we have to remove the stable heart trait before we give them a heart attack
+ to_chat(affected_mob,span_danger("You feel something rupturing inside your chest!"))
+ affected_mob.emote("scream")
+ affected_mob.set_heartattack(TRUE)
volume = 0
- . = ..()
- return TRUE
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
-/datum/reagent/medicine/c2/penthrite/on_mob_end_metabolize(mob/living/user)
- user.clear_alert("penthrite")
- user.remove_traits(subject_traits, type)
+/datum/reagent/medicine/c2/penthrite/on_mob_end_metabolize(mob/living/affected_mob)
. = ..()
+ affected_mob.clear_alert("penthrite")
+ affected_mob.remove_traits(subject_traits, type)
-/datum/reagent/medicine/c2/penthrite/overdose_process(mob/living/carbon/human/H, seconds_per_tick, times_fired)
- REMOVE_TRAIT(H, TRAIT_STABLEHEART, type)
- H.adjustStaminaLoss(10 * REM * seconds_per_tick, required_biotype = affected_biotype)
- H.adjustOrganLoss(ORGAN_SLOT_HEART, 10 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)
- H.set_heartattack(TRUE)
+/datum/reagent/medicine/c2/penthrite/overdose_process(mob/living/carbon/human/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
+ REMOVE_TRAIT(affected_mob, TRAIT_STABLEHEART, type)
+ var/need_mob_update
+ need_mob_update = affected_mob.adjustStaminaLoss(10 * REM * seconds_per_tick, updating_stamina = FALSE, required_biotype = affected_biotype)
+ need_mob_update += affected_mob.adjustOrganLoss(ORGAN_SLOT_HEART, 10 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)
+ need_mob_update += affected_mob.set_heartattack(TRUE)
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/******NICHE******/
diff --git a/code/modules/reagents/chemistry/reagents/drinks/alcohol_reagents.dm b/code/modules/reagents/chemistry/reagents/drinks/alcohol_reagents.dm
index b81e1600bbf..07335fe728f 100644
--- a/code/modules/reagents/chemistry/reagents/drinks/alcohol_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/drinks/alcohol_reagents.dm
@@ -51,9 +51,10 @@
return ..()
/datum/reagent/consumable/ethanol/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
+ . = ..()
if(drinker.get_drunk_amount() < volume * boozepwr * ALCOHOL_THRESHOLD_MODIFIER || boozepwr < 0)
var/booze_power = boozepwr
- if(HAS_TRAIT(drinker, TRAIT_ALCOHOL_TOLERANCE)) //we're an accomplished drinker
+ if(HAS_TRAIT(drinker, TRAIT_ALCOHOL_TOLERANCE)) // we're an accomplished drinker
booze_power *= 0.7
if(HAS_TRAIT(drinker, TRAIT_LIGHT_DRINKER))
booze_power *= 2
@@ -77,8 +78,8 @@
var/obj/item/organ/internal/liver/liver = drinker.get_organ_slot(ORGAN_SLOT_LIVER)
var/heavy_drinker_multiplier = (HAS_TRAIT(drinker, TRAIT_HEAVY_DRINKER) ? 0.5 : 1)
if (istype(liver))
- liver.apply_organ_damage(((max(sqrt(volume) * (boozepwr ** ALCOHOL_EXPONENT) * liver.alcohol_tolerance * heavy_drinker_multiplier * seconds_per_tick, 0))/300)) // SKYRAT EDIT CHANGE - Alcohol Tolerance - Original: (((max(sqrt(volume) * (boozepwr ** ALCOHOL_EXPONENT) * liver.alcohol_tolerance * heavy_drinker_multiplier * seconds_per_tick, 0))/150))
- return ..()
+ if(liver.apply_organ_damage(((max(sqrt(volume) * (boozepwr ** ALCOHOL_EXPONENT) * liver.alcohol_tolerance * heavy_drinker_multiplier * seconds_per_tick, 0))/300))) // SKYRAT EDIT CHANGE - Alcohol Tolerance - Original: if((((max(sqrt(volume) * (boozepwr ** ALCOHOL_EXPONENT) * liver.alcohol_tolerance * heavy_drinker_multiplier * seconds_per_tick, 0))/150)))
+ return UPDATE_MOB_HEALTH
/datum/reagent/consumable/ethanol/expose_obj(obj/exposed_obj, reac_volume)
if(istype(exposed_obj, /obj/item/paper))
@@ -151,9 +152,9 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/ethanol/beer/green/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
+ . = ..()
if(drinker.color != color)
drinker.add_atom_colour(color, TEMPORARY_COLOUR_PRIORITY)
- return ..()
/datum/reagent/consumable/ethanol/beer/green/on_mob_end_metabolize(mob/living/drinker)
drinker.remove_atom_colour(TEMPORARY_COLOUR_PRIORITY, color)
@@ -167,13 +168,12 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/ethanol/kahlua/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
+ . = ..()
drinker.set_dizzy_if_lower(10 SECONDS * REM * seconds_per_tick)
drinker.adjust_drowsiness(-6 SECONDS * REM * seconds_per_tick)
drinker.AdjustSleeping(-40 * REM * seconds_per_tick)
if(!HAS_TRAIT(drinker, TRAIT_ALCOHOL_TOLERANCE))
drinker.set_jitter_if_lower(10 SECONDS)
- ..()
- . = TRUE
/datum/reagent/consumable/ethanol/whiskey
name = "Whiskey"
@@ -200,9 +200,9 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/ethanol/whiskey/candycorn/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
+ . = ..()
if(SPT_PROB(5, seconds_per_tick))
drinker.adjust_hallucinations(4 SECONDS * REM * seconds_per_tick)
- ..()
/datum/reagent/consumable/ethanol/thirteenloko
name = "Thirteen Loko"
@@ -216,20 +216,21 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/ethanol/thirteenloko/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
+ . = ..()
drinker.adjust_drowsiness(-14 SECONDS * REM * seconds_per_tick)
drinker.AdjustSleeping(-40 * REM * seconds_per_tick)
drinker.adjust_bodytemperature(-5 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, drinker.get_body_temp_normal())
if(!HAS_TRAIT(drinker, TRAIT_ALCOHOL_TOLERANCE))
drinker.set_jitter_if_lower(10 SECONDS)
- ..()
- return TRUE
/datum/reagent/consumable/ethanol/thirteenloko/overdose_start(mob/living/drinker)
+ . = ..()
to_chat(drinker, span_userdanger("Your entire body violently jitters as you start to feel queasy. You really shouldn't have drank all of that [name]!"))
drinker.set_jitter_if_lower(40 SECONDS)
drinker.Stun(1.5 SECONDS)
/datum/reagent/consumable/ethanol/thirteenloko/overdose_process(mob/living/drinker, seconds_per_tick, times_fired)
+ . = ..()
if(SPT_PROB(3.5, seconds_per_tick) && iscarbon(drinker))
var/obj/item/held_item = drinker.get_active_held_item()
if(held_item)
@@ -248,15 +249,18 @@
eyes.forceMove(get_turf(drinker))
to_chat(drinker, span_userdanger("You double over in pain as you feel your eyeballs liquify in your head!"))
drinker.emote("scream")
- drinker.adjustBruteLoss(15, required_bodytype = affected_bodytype)
+ if(drinker.adjustBruteLoss(15 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype))
+ . = UPDATE_MOB_HEALTH
else
to_chat(drinker, span_userdanger("You scream in terror as you go blind!"))
- eyes.apply_organ_damage(eyes.maxHealth)
+ if(eyes.apply_organ_damage(eyes.maxHealth))
+ . = UPDATE_MOB_HEALTH
drinker.emote("scream")
if(SPT_PROB(1.5, seconds_per_tick) && iscarbon(drinker))
drinker.visible_message(span_danger("[drinker] starts having a seizure!"), span_userdanger("You have a seizure!"))
- drinker.Unconscious(10 SECONDS)
+ if(drinker.Unconscious(10 SECONDS))
+ . = UPDATE_MOB_HEALTH
drinker.set_jitter_if_lower(700 SECONDS)
if(SPT_PROB(0.5, seconds_per_tick) && iscarbon(drinker))
@@ -285,10 +289,10 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/ethanol/bilk/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
+ . = ..()
if(drinker.getBruteLoss() && SPT_PROB(5, seconds_per_tick))
- drinker.heal_bodypart_damage(brute = 1)
- . = TRUE
- return ..() || .
+ if(drinker.heal_bodypart_damage(brute = 1 * REM * seconds_per_tick, updating_health = FALSE))
+ return UPDATE_MOB_HEALTH
/datum/reagent/consumable/ethanol/threemileisland
name = "Three Mile Island Iced Tea"
@@ -301,8 +305,8 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/ethanol/threemileisland/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
+ . = ..()
drinker.set_drugginess(100 SECONDS * REM * seconds_per_tick)
- return ..()
/datum/reagent/consumable/ethanol/gin
name = "Gin"
@@ -415,9 +419,9 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/ethanol/absinthe/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
+ . = ..()
if(SPT_PROB(5, seconds_per_tick) && !HAS_TRAIT(drinker, TRAIT_ALCOHOL_TOLERANCE))
- drinker.adjust_hallucinations(8 SECONDS)
- ..()
+ drinker.adjust_hallucinations(8 SECONDS * REM * seconds_per_tick)
/datum/reagent/consumable/ethanol/hooch
name = "Hooch"
@@ -513,13 +517,15 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/ethanol/cuba_libre/on_mob_life(mob/living/carbon/cubano, seconds_per_tick, times_fired)
+ . = ..()
+ var/need_mob_update
if(cubano.mind && cubano.mind.has_antag_datum(/datum/antagonist/rev)) //Cuba Libre, the traditional drink of revolutions! Heals revolutionaries.
- cubano.adjustBruteLoss(-1 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype)
- cubano.adjustFireLoss(-1 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype)
- cubano.adjustToxLoss(-1 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
- cubano.adjustOxyLoss(-5 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
- . = TRUE
- return ..() || .
+ need_mob_update = cubano.adjustBruteLoss(-1 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
+ need_mob_update += cubano.adjustFireLoss(-1 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
+ need_mob_update += cubano.adjustToxLoss(-1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)
+ need_mob_update += cubano.adjustOxyLoss(-5 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/consumable/ethanol/whiskey_cola
name = "Whiskey Cola"
@@ -602,17 +608,17 @@
))
/datum/reagent/consumable/ethanol/screwdrivercocktail/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
+ . = ..()
var/obj/item/organ/internal/liver/liver = drinker.get_organ_slot(ORGAN_SLOT_LIVER)
if(HAS_TRAIT(liver, TRAIT_ENGINEER_METABOLISM))
ADD_TRAIT(drinker, TRAIT_HALT_RADIATION_EFFECTS, "[type]")
if (HAS_TRAIT(drinker, TRAIT_IRRADIATED))
- drinker.adjustToxLoss(-2 * REM * seconds_per_tick, required_biotype = affected_biotype)
-
- return ..()
+ if(drinker.adjustToxLoss(-2 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype))
+ return UPDATE_MOB_HEALTH
/datum/reagent/consumable/ethanol/screwdrivercocktail/on_mob_end_metabolize(mob/living/drinker)
+ . = ..()
REMOVE_TRAIT(drinker, TRAIT_HALT_RADIATION_EFFECTS, "[type]")
- return ..()
/datum/reagent/consumable/ethanol/booger
name = "Booger"
@@ -648,6 +654,7 @@
var/tough_text
/datum/reagent/consumable/ethanol/brave_bull/on_mob_metabolize(mob/living/drinker)
+ . = ..()
tough_text = pick("brawny", "tenacious", "tough", "hardy", "sturdy") //Tuff stuff
to_chat(drinker, span_notice("You feel [tough_text]!"))
drinker.maxHealth += 10 //Brave Bull makes you sturdier, and thus capable of withstanding a tiny bit more punishment.
@@ -655,6 +662,7 @@
ADD_TRAIT(drinker, TRAIT_FEARLESS, type)
/datum/reagent/consumable/ethanol/brave_bull/on_mob_end_metabolize(mob/living/drinker)
+ . = ..()
to_chat(drinker, span_notice("You no longer feel [tough_text]."))
drinker.maxHealth -= 10
drinker.health = min(drinker.health - 10, drinker.maxHealth) //This can indeed crit you if you're alive solely based on alchol ingestion
@@ -672,6 +680,7 @@
var/obj/effect/light_holder
/datum/reagent/consumable/ethanol/tequila_sunrise/on_mob_metabolize(mob/living/drinker)
+ . = ..()
to_chat(drinker, span_notice("You feel gentle warmth spread through your body!"))
light_holder = new(drinker)
light_holder.set_light(3, 0.7, "#FFCC00") //Tequila Sunrise makes you radiate dim light, like a sunrise!
@@ -684,6 +693,7 @@
return ..()
/datum/reagent/consumable/ethanol/tequila_sunrise/on_mob_end_metabolize(mob/living/drinker)
+ . = ..()
to_chat(drinker, span_notice("The warmth in your body fades."))
QDEL_NULL(light_holder)
@@ -697,8 +707,8 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/ethanol/toxins_special/on_mob_life(mob/living/drinker, seconds_per_tick, times_fired)
+ . = ..()
drinker.adjust_bodytemperature(15 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, 0, drinker.get_body_temp_normal() + 20) //310.15 is the normal bodytemp.
- return ..()
/datum/reagent/consumable/ethanol/beepsky_smash
name = "Beepsky Smash"
@@ -714,6 +724,7 @@
var/datum/brain_trauma/special/beepsky/beepsky_hallucination
/datum/reagent/consumable/ethanol/beepsky_smash/on_mob_metabolize(mob/living/carbon/drinker)
+ . = ..()
if(HAS_TRAIT(drinker, TRAIT_ALCOHOL_TOLERANCE))
metabolization_rate = 0.8
// if you don't have a liver, or your liver isn't an officer's liver
@@ -721,28 +732,27 @@
if(!liver || !HAS_TRAIT(liver, TRAIT_LAW_ENFORCEMENT_METABOLISM))
beepsky_hallucination = new()
drinker.gain_trauma(beepsky_hallucination, TRAUMA_RESILIENCE_ABSOLUTE)
- ..()
/datum/reagent/consumable/ethanol/beepsky_smash/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
+ . = ..()
drinker.set_jitter_if_lower(4 SECONDS)
var/obj/item/organ/internal/liver/liver = drinker.get_organ_slot(ORGAN_SLOT_LIVER)
// if you have a liver and that liver is an officer's liver
if(liver && HAS_TRAIT(liver, TRAIT_LAW_ENFORCEMENT_METABOLISM))
- . = TRUE
- drinker.adjustStaminaLoss(-10 * REM * seconds_per_tick, required_biotype = affected_biotype)
+ if(drinker.adjustStaminaLoss(-10 * REM * seconds_per_tick, updating_stamina = FALSE, required_biotype = affected_biotype))
+ . = UPDATE_MOB_HEALTH
if(SPT_PROB(10, seconds_per_tick))
drinker.cause_hallucination(get_random_valid_hallucination_subtype(/datum/hallucination/nearby_fake_item), name)
if(SPT_PROB(5, seconds_per_tick))
drinker.cause_hallucination(/datum/hallucination/stray_bullet, name)
- ..()
-
/datum/reagent/consumable/ethanol/beepsky_smash/on_mob_end_metabolize(mob/living/carbon/drinker)
+ . = ..()
if(beepsky_hallucination)
QDEL_NULL(beepsky_hallucination)
- return ..()
/datum/reagent/consumable/ethanol/beepsky_smash/overdose_start(mob/living/carbon/drinker)
+ . = ..()
var/obj/item/organ/internal/liver/liver = drinker.get_organ_slot(ORGAN_SLOT_LIVER)
// if you don't have a liver, or your liver isn't an officer's liver
if(!liver || !HAS_TRAIT(liver, TRAIT_LAW_ENFORCEMENT_METABOLISM))
@@ -768,6 +778,7 @@
var/dorf_mode = FALSE
/datum/reagent/consumable/ethanol/manly_dorf/on_mob_metabolize(mob/living/drinker)
+ . = ..()
if(ishuman(drinker))
var/mob/living/carbon/human/potential_dwarf = drinker
if(HAS_TRAIT(potential_dwarf, TRAIT_DWARF))
@@ -776,10 +787,13 @@
dorf_mode = TRUE
/datum/reagent/consumable/ethanol/manly_dorf/on_mob_life(mob/living/carbon/dwarf, seconds_per_tick, times_fired)
+ . = ..()
if(dorf_mode)
- dwarf.adjustBruteLoss(-2 * REM * seconds_per_tick, required_bodytype = affected_bodytype)
- dwarf.adjustFireLoss(-2 * REM * seconds_per_tick, required_bodytype = affected_bodytype)
- return ..()
+ var/need_mob_update
+ need_mob_update = dwarf.adjustBruteLoss(-2 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
+ need_mob_update += dwarf.adjustFireLoss(-2 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/consumable/ethanol/longislandicedtea
name = "Long Island Iced Tea"
@@ -809,6 +823,7 @@
glass_price = DRINK_PRICE_EASY
/datum/reagent/consumable/ethanol/b52/on_mob_metabolize(mob/living/drinker)
+ . = ..()
playsound(drinker, 'sound/effects/explosion_distant.ogg', 100, FALSE)
/datum/reagent/consumable/ethanol/irishcoffee
@@ -859,8 +874,8 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/ethanol/manhattan_proj/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
+ . = ..()
drinker.set_drugginess(1 MINUTES * REM * seconds_per_tick)
- return ..()
/datum/reagent/consumable/ethanol/whiskeysoda
name = "Whiskey Soda"
@@ -881,8 +896,8 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/ethanol/antifreeze/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
+ . = ..()
drinker.adjust_bodytemperature(20 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, 0, drinker.get_body_temp_normal() + 20) //310.15 is the normal bodytemp.
- return ..()
/datum/reagent/consumable/ethanol/barefoot
name = "Barefoot"
@@ -894,12 +909,12 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/ethanol/barefoot/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
+ . = ..()
if(ishuman(drinker)) //Barefoot causes the imbiber to quickly regenerate brute trauma if they're not wearing shoes.
var/mob/living/carbon/human/unshoed = drinker
if(!unshoed.shoes)
- unshoed.adjustBruteLoss(-3 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype)
- . = TRUE
- return ..() || .
+ if(unshoed.adjustBruteLoss(-3 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype))
+ return UPDATE_MOB_HEALTH
/datum/reagent/consumable/ethanol/snowwhite
name = "Snow White"
@@ -1028,13 +1043,16 @@
var/static/list/ray_filter = list(type = "rays", size = 40, density = 15, color = SUPERMATTER_SINGULARITY_RAYS_COLOUR, factor = 15)
/datum/reagent/consumable/ethanol/singulo/on_mob_metabolize(mob/living/drinker)
+ . = ..()
ADD_TRAIT(drinker, TRAIT_MADNESS_IMMUNE, type)
/datum/reagent/consumable/ethanol/singulo/on_mob_end_metabolize(mob/living/drinker)
+ . = ..()
REMOVE_TRAIT(drinker, TRAIT_MADNESS_IMMUNE, type)
drinker.remove_filter("singulo_rays")
/datum/reagent/consumable/ethanol/singulo/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
+ . = ..()
if(SPT_PROB(2.5, seconds_per_tick))
// 20u = 1x1, 45u = 2x2, 80u = 3x3
var/volume_to_radius = FLOOR(sqrt(volume/5), 1) - 1
@@ -1050,7 +1068,6 @@
animate(drinker.get_filter("singulo_rays"), offset = 10, time = 1.5 SECONDS, loop = -1)
addtimer(CALLBACK(drinker, TYPE_PROC_REF(/datum, remove_filter), "singulo_rays"), 1.5 SECONDS)
drinker.emote("burp")
- return ..()
/datum/reagent/consumable/ethanol/sbiten
name = "Sbiten"
@@ -1062,8 +1079,8 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/ethanol/sbiten/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
+ . = ..()
drinker.adjust_bodytemperature(50 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, 0, BODYTEMP_HEAT_DAMAGE_LIMIT) //310.15 is the normal bodytemp.
- return ..()
/datum/reagent/consumable/ethanol/red_mead
name = "Red Mead"
@@ -1093,8 +1110,8 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/ethanol/iced_beer/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
+ . = ..()
drinker.adjust_bodytemperature(-20 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, T0C) //310.15 is the normal bodytemp.
- return ..()
/datum/reagent/consumable/ethanol/grog
name = "Grog"
@@ -1162,9 +1179,9 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/ethanol/changelingsting/on_mob_life(mob/living/carbon/target, seconds_per_tick, times_fired)
+ . = ..()
var/datum/antagonist/changeling/changeling = target.mind?.has_antag_datum(/datum/antagonist/changeling)
changeling?.adjust_chemicals(metabolization_rate * REM * seconds_per_tick)
- return ..()
/datum/reagent/consumable/ethanol/irishcarbomb
name = "Irish Car Bomb"
@@ -1185,9 +1202,9 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/ethanol/syndicatebomb/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
+ . = ..()
if(SPT_PROB(2.5, seconds_per_tick))
playsound(get_turf(drinker), 'sound/effects/explosionfar.ogg', 100, TRUE)
- return ..()
/datum/reagent/consumable/ethanol/hiveminderaser
name = "Hivemind Eraser"
@@ -1228,11 +1245,11 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/ethanol/bananahonk/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
+ . = ..()
var/obj/item/organ/internal/liver/liver = drinker.get_organ_slot(ORGAN_SLOT_LIVER)
if((liver && HAS_TRAIT(liver, TRAIT_COMEDY_METABOLISM)) || ismonkey(drinker))
- drinker.heal_bodypart_damage(1 * REM * seconds_per_tick, 1 * REM * seconds_per_tick)
- . = TRUE
- return ..() || .
+ if(drinker.heal_bodypart_damage(brute = 1 * REM * seconds_per_tick, burn = 1 * REM * seconds_per_tick, updating_health = FALSE))
+ return UPDATE_MOB_HEALTH
/datum/reagent/consumable/ethanol/silencer
name = "Silencer"
@@ -1245,11 +1262,11 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/ethanol/silencer/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
+ . = ..()
if(ishuman(drinker) && HAS_MIND_TRAIT(drinker, TRAIT_MIMING))
drinker.set_silence_if_lower(MIMEDRINK_SILENCE_DURATION)
- drinker.heal_bodypart_damage(1 * REM * seconds_per_tick, 1 * REM * seconds_per_tick)
- . = TRUE
- return ..() || .
+ if(drinker.heal_bodypart_damage(brute = 1 * REM * seconds_per_tick, burn = 1 * REM * seconds_per_tick, updating_health = FALSE))
+ return UPDATE_MOB_HEALTH
/datum/reagent/consumable/ethanol/drunkenblumpkin
name = "Drunken Blumpkin"
@@ -1289,9 +1306,9 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/ethanol/fetching_fizz/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
+ . = ..()
for(var/obj/item/stack/ore/O in orange(3, drinker))
step_towards(O, get_turf(drinker))
- return ..()
//Another reference. Heals those in critical condition extremely quickly.
/datum/reagent/consumable/ethanol/hearty_punch
@@ -1305,14 +1322,16 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/ethanol/hearty_punch/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
+ . = ..()
if(drinker.health <= 0)
- drinker.adjustBruteLoss(-3 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype)
- drinker.adjustFireLoss(-3 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype)
- drinker.adjustCloneLoss(-5 * REM * seconds_per_tick, 0)
- drinker.adjustOxyLoss(-4 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
- drinker.adjustToxLoss(-3 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
- . = TRUE
- return ..() || .
+ var/need_mob_update
+ need_mob_update = drinker.adjustBruteLoss(-3 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
+ need_mob_update += drinker.adjustFireLoss(-3 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
+ need_mob_update += drinker.adjustCloneLoss(-5 * REM * seconds_per_tick, updating_health = FALSE)
+ need_mob_update += drinker.adjustOxyLoss(-4 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
+ need_mob_update += drinker.adjustToxLoss(-3 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/consumable/ethanol/bacchus_blessing //An EXTREMELY powerful drink. Smashed in seconds, dead in minutes.
name = "Bacchus' Blessing"
@@ -1333,20 +1352,19 @@
glass_price = DRINK_PRICE_HIGH
/datum/reagent/consumable/ethanol/atomicbomb/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
+ . = ..()
drinker.set_drugginess(100 SECONDS * REM * seconds_per_tick)
if(!HAS_TRAIT(drinker, TRAIT_ALCOHOL_TOLERANCE))
drinker.adjust_confusion(2 SECONDS * REM * seconds_per_tick)
drinker.set_dizzy_if_lower(20 SECONDS * REM * seconds_per_tick)
drinker.adjust_slurring(6 SECONDS * REM * seconds_per_tick)
switch(current_cycle)
- if(51 to 200)
+ if(52 to 201)
drinker.Sleeping(100 * REM * seconds_per_tick)
- . = TRUE
- if(201 to INFINITY)
+ if(202 to INFINITY)
drinker.AdjustSleeping(40 * REM * seconds_per_tick)
- drinker.adjustToxLoss(2 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
- . = TRUE
- ..()
+ if(drinker.adjustToxLoss(2 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype))
+ return UPDATE_MOB_HEALTH
/datum/reagent/consumable/ethanol/gargle_blaster
name = "Pan-Galactic Gargle Blaster"
@@ -1358,20 +1376,19 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/ethanol/gargle_blaster/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
+ . = ..()
drinker.adjust_dizzy(3 SECONDS * REM * seconds_per_tick)
switch(current_cycle)
- if(15 to 45)
+ if(16 to 46)
drinker.adjust_slurring(3 SECONDS * REM * seconds_per_tick)
-
- if(45 to 55)
+ if(46 to 56)
if(SPT_PROB(30, seconds_per_tick))
drinker.adjust_confusion(3 SECONDS * REM * seconds_per_tick)
- if(55 to 200)
+ if(56 to 201)
drinker.set_drugginess(110 SECONDS * REM * seconds_per_tick)
- if(200 to INFINITY)
- drinker.adjustToxLoss(2 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
- . = TRUE
- ..()
+ if(201 to INFINITY)
+ if(drinker.adjustToxLoss(2 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype))
+ return UPDATE_MOB_HEALTH
/datum/reagent/consumable/ethanol/neurotoxin
name = "Neurotoxin"
@@ -1387,35 +1404,37 @@
return (pick(TRAIT_PARALYSIS_L_ARM,TRAIT_PARALYSIS_R_ARM,TRAIT_PARALYSIS_R_LEG,TRAIT_PARALYSIS_L_LEG))
/datum/reagent/consumable/ethanol/neurotoxin/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
+ . = ..()
drinker.set_drugginess(100 SECONDS * REM * seconds_per_tick)
drinker.adjust_dizzy(4 SECONDS * REM * seconds_per_tick)
- drinker.adjustOrganLoss(ORGAN_SLOT_BRAIN, 1 * REM * seconds_per_tick, 150, required_organ_flag = affected_organ_flags)
+ var/need_mob_update
+ need_mob_update = drinker.adjustOrganLoss(ORGAN_SLOT_BRAIN, 1 * REM * seconds_per_tick, 150, required_organ_flag = affected_organ_flags)
if(SPT_PROB(10, seconds_per_tick))
- drinker.adjustStaminaLoss(10, required_biotype = affected_biotype)
+ need_mob_update += drinker.adjustStaminaLoss(10 * REM * seconds_per_tick, updating_stamina = FALSE, required_biotype = affected_biotype)
drinker.drop_all_held_items()
to_chat(drinker, span_notice("You cant feel your hands!"))
- if(current_cycle > 5)
+ if(current_cycle > 6)
if(SPT_PROB(10, seconds_per_tick))
var/paralyzed_limb = pick_paralyzed_limb()
ADD_TRAIT(drinker, paralyzed_limb, type)
- drinker.adjustStaminaLoss(10, required_biotype = affected_biotype)
- if(current_cycle > 30)
- drinker.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)
- if(current_cycle > 50 && SPT_PROB(7.5, seconds_per_tick))
+ need_mob_update += drinker.adjustStaminaLoss(10 * REM * seconds_per_tick, updating_stamina = FALSE, required_biotype = affected_biotype)
+ if(current_cycle > 31)
+ need_mob_update += drinker.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)
+ if(current_cycle > 51 && SPT_PROB(7.5, seconds_per_tick))
if(!drinker.undergoing_cardiac_arrest() && drinker.can_heartattack())
drinker.set_heartattack(TRUE)
if(drinker.stat == CONSCIOUS)
drinker.visible_message(span_userdanger("[drinker] clutches at [drinker.p_their()] chest as if [drinker.p_their()] heart stopped!"))
- . = TRUE
- ..()
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/consumable/ethanol/neurotoxin/on_mob_end_metabolize(mob/living/carbon/drinker)
+ . = ..()
REMOVE_TRAIT(drinker, TRAIT_PARALYSIS_L_ARM, type)
REMOVE_TRAIT(drinker, TRAIT_PARALYSIS_R_ARM, type)
REMOVE_TRAIT(drinker, TRAIT_PARALYSIS_R_LEG, type)
REMOVE_TRAIT(drinker, TRAIT_PARALYSIS_L_LEG, type)
drinker.adjustStaminaLoss(10, required_biotype = affected_biotype)
- ..()
/datum/reagent/consumable/ethanol/hippies_delight
name = "Hippie's Delight"
@@ -1429,36 +1448,36 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/ethanol/hippies_delight/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
+ . = ..()
drinker.set_slurring_if_lower(1 SECONDS * REM * seconds_per_tick)
switch(current_cycle)
- if(1 to 5)
+ if(2 to 6)
drinker.set_dizzy_if_lower(20 SECONDS * REM * seconds_per_tick)
drinker.set_drugginess(1 MINUTES * REM * seconds_per_tick)
if(SPT_PROB(5, seconds_per_tick))
drinker.emote(pick("twitch","giggle"))
- if(5 to 10)
+ if(6 to 11)
drinker.set_jitter_if_lower(40 SECONDS * REM * seconds_per_tick)
drinker.set_dizzy_if_lower(40 SECONDS * REM * seconds_per_tick)
drinker.set_drugginess(1.5 MINUTES * REM * seconds_per_tick)
if(SPT_PROB(10, seconds_per_tick))
drinker.emote(pick("twitch","giggle"))
- if (10 to 200)
+ if (11 to 201)
drinker.set_jitter_if_lower(80 SECONDS * REM * seconds_per_tick)
drinker.set_dizzy_if_lower(80 SECONDS * REM * seconds_per_tick)
drinker.set_drugginess(2 MINUTES * REM * seconds_per_tick)
if(SPT_PROB(16, seconds_per_tick))
drinker.emote(pick("twitch","giggle"))
- if(200 to INFINITY)
+ if(201 to INFINITY)
drinker.set_jitter_if_lower(120 SECONDS * REM * seconds_per_tick)
drinker.set_dizzy_if_lower(120 SECONDS * REM * seconds_per_tick)
drinker.set_drugginess(2.5 MINUTES * REM * seconds_per_tick)
if(SPT_PROB(23, seconds_per_tick))
drinker.emote(pick("twitch","giggle"))
if(SPT_PROB(16, seconds_per_tick))
- drinker.adjustToxLoss(2, FALSE, required_biotype = affected_biotype)
- . = TRUE
- ..()
+ if(drinker.adjustToxLoss(2 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype))
+ return UPDATE_MOB_HEALTH
/datum/reagent/consumable/ethanol/eggnog
name = "Eggnog"
@@ -1490,9 +1509,9 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/ethanol/narsour/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
+ . = ..()
drinker.adjust_timed_status_effect(6 SECONDS * REM * seconds_per_tick, /datum/status_effect/speech/slurring/cult, max_duration = 6 SECONDS)
drinker.adjust_stutter_up_to(6 SECONDS * REM * seconds_per_tick, 6 SECONDS)
- return ..()
/datum/reagent/consumable/ethanol/triple_sec
name = "Triple Sec"
@@ -1536,12 +1555,12 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/ethanol/quadruple_sec/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
+ . = ..()
//Securidrink in line with the Screwdriver for engineers or Nothing for mimes
var/obj/item/organ/internal/liver/liver = drinker.get_organ_slot(ORGAN_SLOT_LIVER)
if(liver && HAS_TRAIT(liver, TRAIT_LAW_ENFORCEMENT_METABOLISM))
- drinker.heal_bodypart_damage(1 * REM * seconds_per_tick, 1 * REM * seconds_per_tick)
- . = TRUE
- return ..()
+ if(drinker.heal_bodypart_damage(brute = 1 * REM * seconds_per_tick, burn = 1 * REM * seconds_per_tick, updating_health = FALSE))
+ return UPDATE_MOB_HEALTH
/datum/reagent/consumable/ethanol/quintuple_sec
name = "Quintuple Sec"
@@ -1553,13 +1572,15 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/ethanol/quintuple_sec/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
+ . = ..()
//Securidrink in line with the Screwdriver for engineers or Nothing for mimes but STRONG..
var/obj/item/organ/internal/liver/liver = drinker.get_organ_slot(ORGAN_SLOT_LIVER)
if(liver && HAS_TRAIT(liver, TRAIT_LAW_ENFORCEMENT_METABOLISM))
- drinker.heal_bodypart_damage(2 * REM * seconds_per_tick, 2 * REM * seconds_per_tick)
- drinker.adjustStaminaLoss(-2 * REM * seconds_per_tick, required_biotype = affected_biotype)
- . = TRUE
- return ..()
+ var/need_mob_update
+ need_mob_update = drinker.heal_bodypart_damage(2 * REM * seconds_per_tick, 2 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
+ need_mob_update += drinker.adjustStaminaLoss(-2 * REM * seconds_per_tick, updating_stamina = FALSE, required_biotype = affected_biotype)
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/consumable/ethanol/grasshopper
name = "Grasshopper"
@@ -1592,28 +1613,34 @@
glass_price = DRINK_PRICE_HIGH
/datum/reagent/consumable/ethanol/bastion_bourbon/on_mob_metabolize(mob/living/drinker)
+ . = ..()
var/heal_points = 10
if(drinker.health <= 0)
heal_points = 20 //heal more if we're in softcrit
- for(var/counter in 1 to min(volume, heal_points)) //only heals 1 point of damage per unit on add, for balance reasons
- drinker.adjustBruteLoss(-1, required_bodytype = affected_bodytype)
- drinker.adjustFireLoss(-1, required_bodytype = affected_bodytype)
- drinker.adjustToxLoss(-1, required_biotype = affected_biotype)
- drinker.adjustOxyLoss(-1, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
- drinker.adjustStaminaLoss(-1, required_biotype = affected_biotype)
+ var/need_mob_update
+ var/heal_amt = min(volume, heal_points) //only heals 1 point of damage per unit on add, for balance reasons
+ need_mob_update = drinker.adjustBruteLoss(-heal_amt, updating_health = FALSE, required_bodytype = affected_bodytype)
+ need_mob_update += drinker.adjustFireLoss(-heal_amt, updating_health = FALSE, required_bodytype = affected_bodytype)
+ need_mob_update += drinker.adjustToxLoss(-heal_amt, updating_health = FALSE, required_biotype = affected_biotype)
+ need_mob_update += drinker.adjustOxyLoss(-heal_amt, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
+ need_mob_update += drinker.adjustStaminaLoss(-heal_amt, updating_stamina = FALSE, required_biotype = affected_biotype)
+ if(need_mob_update)
+ drinker.updatehealth()
drinker.visible_message(span_warning("[drinker] shivers with renewed vigor!"), span_notice("One taste of [lowertext(name)] fills you with energy!"))
if(!drinker.stat && heal_points == 20) //brought us out of softcrit
drinker.visible_message(span_danger("[drinker] lurches to [drinker.p_their()] feet!"), span_boldnotice("Up and at 'em, kid."))
/datum/reagent/consumable/ethanol/bastion_bourbon/on_mob_life(mob/living/drinker, seconds_per_tick, times_fired)
+ . = ..()
if(drinker.health > 0)
- drinker.adjustBruteLoss(-1 * REM * seconds_per_tick, required_bodytype = affected_bodytype)
- drinker.adjustFireLoss(-1 * REM * seconds_per_tick, required_bodytype = affected_bodytype)
- drinker.adjustToxLoss(-0.5 * REM * seconds_per_tick, required_biotype = affected_biotype)
- drinker.adjustOxyLoss(-3 * REM * seconds_per_tick, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
- drinker.adjustStaminaLoss(-5 * REM * seconds_per_tick, required_biotype = affected_biotype)
- . = TRUE
- ..()
+ var/need_mob_update
+ need_mob_update = drinker.adjustBruteLoss(-1 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
+ need_mob_update += drinker.adjustFireLoss(-1 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
+ need_mob_update += drinker.adjustToxLoss(-0.5 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)
+ need_mob_update += drinker.adjustOxyLoss(-3 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
+ need_mob_update += drinker.adjustStaminaLoss(-5 * REM * seconds_per_tick, updating_stamina = FALSE, required_biotype = affected_biotype)
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/consumable/ethanol/squirt_cider
name = "Squirt Cider"
@@ -1625,9 +1652,8 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/ethanol/squirt_cider/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
+ . = ..()
drinker.satiety += 5 * REM * seconds_per_tick //for context, vitamins give 15 satiety per second
- ..()
- . = TRUE
/datum/reagent/consumable/ethanol/fringe_weaver
name = "Fringe Weaver"
@@ -1649,9 +1675,8 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/ethanol/sugar_rush/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
+ . = ..()
drinker.satiety -= 10 * REM * seconds_per_tick //junky as hell! a whole glass will keep you from being able to eat junk food
- ..()
- . = TRUE
/datum/reagent/consumable/ethanol/crevice_spike
name = "Crevice Spike"
@@ -1663,6 +1688,7 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/ethanol/crevice_spike/on_mob_metabolize(mob/living/drinker) //damage only applies when drink first enters system and won't again until drink metabolizes out
+ . = ..()
drinker.adjustBruteLoss(3 * min(5,volume), required_bodytype = affected_bodytype) //minimum 3 brute damage on ingestion to limit non-drink means of injury - a full 5 unit gulp of the drink trucks you for the full 15
/datum/reagent/consumable/ethanol/sake
@@ -1684,9 +1710,9 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/ethanol/peppermint_patty/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
+ . = ..()
drinker.apply_status_effect(/datum/status_effect/throat_soothed)
drinker.adjust_bodytemperature(5 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, 0, drinker.get_body_temp_normal())
- ..()
/datum/reagent/consumable/ethanol/alexander
name = "Alexander"
@@ -1699,24 +1725,24 @@
var/obj/item/shield/mighty_shield
/datum/reagent/consumable/ethanol/alexander/on_mob_metabolize(mob/living/drinker)
+ . = ..()
if(ishuman(drinker))
var/mob/living/carbon/human/the_human = drinker
for(var/obj/item/shield/the_shield in the_human.contents)
mighty_shield = the_shield
mighty_shield.block_chance += 10
to_chat(the_human, span_notice("[the_shield] appears polished, although you don't recall polishing it."))
- return TRUE
/datum/reagent/consumable/ethanol/alexander/on_mob_life(mob/living/drinker, seconds_per_tick, times_fired)
- ..()
if(mighty_shield && !(mighty_shield in drinker.contents)) //If you had a shield and lose it, you lose the reagent as well. Otherwise this is just a normal drink.
holder.remove_reagent(type, volume)
+ return ..()
/datum/reagent/consumable/ethanol/alexander/on_mob_end_metabolize(mob/living/drinker)
+ . = ..()
if(mighty_shield)
mighty_shield.block_chance -= 10
to_chat(drinker,span_notice("You notice [mighty_shield] looks worn again. Weird."))
- ..()
/datum/reagent/consumable/ethanol/amaretto_alexander
name = "Amaretto Alexander"
@@ -1748,7 +1774,7 @@
glass_price = DRINK_PRICE_MEDIUM
/datum/reagent/consumable/ethanol/between_the_sheets/on_mob_life(mob/living/drinker, seconds_per_tick, times_fired)
- ..()
+ . = ..()
var/is_between_the_sheets = FALSE
for(var/obj/item/bedsheet/bedsheet in range(drinker.loc, 0))
if(bedsheet.loc != drinker.loc) // bedsheets in your backpack/neck don't count
@@ -1759,15 +1785,18 @@
if(!drinker.IsSleeping() || !is_between_the_sheets)
return
+ var/need_mob_update
if(drinker.getBruteLoss() && drinker.getFireLoss()) //If you are damaged by both types, slightly increased healing but it only heals one. The more the merrier wink wink.
if(prob(50))
- drinker.adjustBruteLoss(-0.25 * REM * seconds_per_tick, required_bodytype = affected_bodytype)
+ need_mob_update = drinker.adjustBruteLoss(-0.25 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
else
- drinker.adjustFireLoss(-0.25 * REM * seconds_per_tick, required_bodytype = affected_bodytype)
+ need_mob_update = drinker.adjustFireLoss(-0.25 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
else if(drinker.getBruteLoss()) //If you have only one, it still heals but not as well.
- drinker.adjustBruteLoss(-0.2 * REM * seconds_per_tick, required_bodytype = affected_bodytype)
+ need_mob_update = drinker.adjustBruteLoss(-0.2 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
else if(drinker.getFireLoss())
- drinker.adjustFireLoss(-0.2 * REM * seconds_per_tick, required_bodytype = affected_bodytype)
+ need_mob_update = drinker.adjustFireLoss(-0.2 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/consumable/ethanol/kamikaze
name = "Kamikaze"
@@ -1806,11 +1835,12 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/ethanol/fernet/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
+ . = ..()
if(drinker.nutrition <= NUTRITION_LEVEL_STARVING)
- drinker.adjustToxLoss(1 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
+ if(drinker.adjustToxLoss(1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype))
+ . = UPDATE_MOB_HEALTH
drinker.adjust_nutrition(-5 * REM * seconds_per_tick)
drinker.overeatduration = 0
- return ..()
/datum/reagent/consumable/ethanol/fernet_cola
name = "Fernet Cola"
@@ -1822,11 +1852,12 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/ethanol/fernet_cola/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
+ . = ..()
if(drinker.nutrition <= NUTRITION_LEVEL_STARVING)
- drinker.adjustToxLoss(0.5 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
+ if(drinker.adjustToxLoss(0.5 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype))
+ . = UPDATE_MOB_HEALTH
drinker.adjust_nutrition(-3 * REM * seconds_per_tick)
drinker.overeatduration = 0
- return ..()
/datum/reagent/consumable/ethanol/fanciulli
name = "Fanciulli"
@@ -1839,15 +1870,14 @@
glass_price = DRINK_PRICE_HIGH
/datum/reagent/consumable/ethanol/fanciulli/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
+ . = ..()
drinker.adjust_nutrition(-5 * REM * seconds_per_tick)
drinker.overeatduration = 0
- return ..()
/datum/reagent/consumable/ethanol/fanciulli/on_mob_metabolize(mob/living/drinker)
+ . = ..()
if(drinker.health > 0)
drinker.adjustStaminaLoss(20, required_biotype = affected_biotype)
- . = TRUE
- ..()
/datum/reagent/consumable/ethanol/branca_menta
name = "Branca Menta"
@@ -1860,14 +1890,13 @@
glass_price = DRINK_PRICE_MEDIUM
/datum/reagent/consumable/ethanol/branca_menta/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
+ . = ..()
drinker.adjust_bodytemperature(-20 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, T0C)
- return ..()
/datum/reagent/consumable/ethanol/branca_menta/on_mob_metabolize(mob/living/drinker)
+ . = ..()
if(drinker.health > 0)
drinker.adjustStaminaLoss(35, required_biotype = affected_biotype)
- . = TRUE
- ..()
/datum/reagent/consumable/ethanol/blank_paper
name = "Blank Paper"
@@ -1880,11 +1909,11 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/ethanol/blank_paper/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
+ . = ..()
if(ishuman(drinker) && HAS_MIND_TRAIT(drinker, TRAIT_MIMING))
drinker.set_silence_if_lower(MIMEDRINK_SILENCE_DURATION)
- drinker.heal_bodypart_damage(1 * REM * seconds_per_tick, 1 * REM * seconds_per_tick)
- . = TRUE
- return ..()
+ if(drinker.heal_bodypart_damage(brute = 1 * REM * seconds_per_tick, burn = 1 * REM * seconds_per_tick, updating_health = FALSE))
+ return UPDATE_MOB_HEALTH
/datum/reagent/consumable/ethanol/fruit_wine
name = "Fruit Wine"
@@ -2011,13 +2040,16 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/ethanol/wizz_fizz/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
+ . = ..()
//A healing drink similar to Quadruple Sec, Ling Stings, and Screwdrivers for the Wizznerds; the check is consistent with the changeling sting
if(drinker?.mind?.has_antag_datum(/datum/antagonist/wizard))
- drinker.heal_bodypart_damage(1 * REM * seconds_per_tick, 1 * REM * seconds_per_tick)
- drinker.adjustOxyLoss(-1 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
- drinker.adjustToxLoss(-1 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
- drinker.adjustStaminaLoss(-1 * REM * seconds_per_tick, required_biotype = affected_biotype)
- return ..()
+ var/need_mob_update
+ need_mob_update = drinker.heal_bodypart_damage(1 * REM * seconds_per_tick, 1 * REM * seconds_per_tick, updating_health = FALSE)
+ need_mob_update += drinker.adjustOxyLoss(-1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
+ need_mob_update += drinker.adjustToxLoss(-1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)
+ need_mob_update += drinker.adjustStaminaLoss(-1 * REM * seconds_per_tick, updating_stamina = FALSE, required_biotype = affected_biotype)
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/consumable/ethanol/bug_spray
name = "Bug Spray"
@@ -2027,19 +2059,20 @@
quality = DRINK_GOOD
taste_description = "the pain of ten thousand slain mosquitos"
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
+ affected_biotype = MOB_BUG
/datum/reagent/consumable/ethanol/bug_spray/on_new(data)
. = ..()
AddElement(/datum/element/bugkiller_reagent)
/datum/reagent/consumable/ethanol/bug_spray/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
+ . = ..()
// Does some damage to bug biotypes
- var/did_damage = drinker.adjustToxLoss(1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = MOB_BUG)
- // Random chance of causing a screm if we did some damage
- if(did_damage && SPT_PROB(2, seconds_per_tick))
- drinker.emote("scream")
-
- return ..() || did_damage
+ if(drinker.adjustToxLoss(1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype))
+ . = UPDATE_MOB_HEALTH
+ // Random chance of causing a screm if we did some damage
+ if(SPT_PROB(2, seconds_per_tick))
+ drinker.emote("scream")
/datum/reagent/consumable/ethanol/applejack
name = "Applejack"
@@ -2068,10 +2101,11 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/ethanol/turbo/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
+ . = ..()
if(SPT_PROB(2, seconds_per_tick))
to_chat(drinker, span_notice("[pick("You feel disregard for the rule of law.", "You feel pumped!", "Your head is pounding.", "Your thoughts are racing..")]"))
- drinker.adjustStaminaLoss(-0.25 * drinker.get_drunk_amount() * REM * seconds_per_tick, required_biotype = affected_biotype)
- return ..()
+ if(drinker.adjustStaminaLoss(-0.25 * drinker.get_drunk_amount() * REM * seconds_per_tick, updating_stamina = FALSE, required_biotype = affected_biotype))
+ return UPDATE_MOB_HEALTH
/datum/reagent/consumable/ethanol/old_timer
name = "Old Timer"
@@ -2083,6 +2117,7 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/ethanol/old_timer/on_mob_life(mob/living/carbon/human/metabolizer, seconds_per_tick, times_fired)
+ . = ..()
if(SPT_PROB(10, seconds_per_tick) && istype(metabolizer))
metabolizer.age += 1
if(metabolizer.age > 70)
@@ -2097,8 +2132,6 @@
metabolizer.visible_message(span_notice("[metabolizer] becomes older than any man should be.. and crumbles into dust!"))
metabolizer.dust(just_ash = FALSE, drop_items = TRUE, force = FALSE)
- return ..()
-
/datum/reagent/consumable/ethanol/rubberneck
name = "Rubberneck"
description = "A quality rubberneck should not contain any gross natural ingredients."
@@ -2135,11 +2168,12 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/ethanol/trappist/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
+ . = ..()
if(drinker.mind?.holy_role)
- drinker.adjustFireLoss(-2.5 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype)
+ if(drinker.adjustFireLoss(-2.5 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype))
+ . = UPDATE_MOB_HEALTH
drinker.adjust_jitter(-2 SECONDS * REM * seconds_per_tick)
drinker.adjust_stutter(-2 SECONDS * REM * seconds_per_tick)
- return ..()
/datum/reagent/consumable/ethanol/blazaam
name = "Blazaam"
@@ -2150,6 +2184,7 @@
var/stored_teleports = 0
/datum/reagent/consumable/ethanol/blazaam/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
+ . = ..()
if(drinker.get_drunk_amount() > 40)
if(stored_teleports)
do_teleport(drinker, get_turf(drinker), rand(1,3), channel = TELEPORT_CHANNEL_WORMHOLE)
@@ -2159,7 +2194,6 @@
stored_teleports += rand(2, 6)
if(prob(70))
drinker.vomit(vomit_flags = VOMIT_CATEGORY_DEFAULT, vomit_type = /obj/effect/decal/cleanable/vomit/purple)
- return ..()
/datum/reagent/consumable/ethanol/planet_cracker
name = "Planet Cracker"
@@ -2181,9 +2215,8 @@
// Heats the user up while the reagent is in the body. Occasionally makes you burst into flames.
drinker.adjust_bodytemperature(25 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick)
if (SPT_PROB(2.5, seconds_per_tick))
- drinker.adjust_fire_stacks(1)
+ drinker.adjust_fire_stacks(1 * REM * seconds_per_tick)
drinker.ignite_mob()
- ..()
/datum/reagent/consumable/ethanol/painkiller
name = "Painkiller"
@@ -2211,6 +2244,7 @@
taste_description = "a horrible emulsion of pineapple and olive oil"
/datum/reagent/consumable/ethanol/pina_olivada/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
+ . = ..()
if(SPT_PROB(8, seconds_per_tick))
drinker.manual_emote(pick("coughs up some oil", "swallows the lump in [drinker.p_their()] throat", "gags", "chokes up a bit"))
if(SPT_PROB(3, seconds_per_tick))
@@ -2222,7 +2256,6 @@
"Your throat feels horrible.",
)
to_chat(drinker, span_notice(pick(messages)))
- return ..()
/datum/reagent/consumable/ethanol/pruno // pruno mix is in drink_reagents
name = "Pruno"
@@ -2233,8 +2266,8 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/ethanol/pruno/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
+ . = ..()
drinker.adjust_disgust(5 * REM * seconds_per_tick)
- ..()
/datum/reagent/consumable/ethanol/ginger_amaretto
name = "Ginger Amaretto"
@@ -2274,9 +2307,10 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/ethanol/kortara/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
+ . = ..()
if(drinker.getBruteLoss() && SPT_PROB(10, seconds_per_tick))
- drinker.heal_bodypart_damage(1,0)
- . = TRUE
+ if(drinker.heal_bodypart_damage(brute = 1 * REM * seconds_per_tick, burn = 0, updating_health = FALSE))
+ return UPDATE_MOB_HEALTH
/datum/reagent/consumable/ethanol/sea_breeze
name = "Sea Breeze"
@@ -2288,8 +2322,8 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/ethanol/sea_breeze/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
+ . = ..()
drinker.apply_status_effect(/datum/status_effect/throat_soothed)
- ..()
/datum/reagent/consumable/ethanol/white_tiziran
name = "White Tiziran"
@@ -2310,8 +2344,8 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/ethanol/drunken_espatier/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
+ . = ..()
drinker.add_mood_event("numb", /datum/mood_event/narcotic_medium, name) //comfortably numb
- ..()
/datum/reagent/consumable/ethanol/drunken_espatier/on_mob_metabolize(mob/living/drinker)
. = ..()
@@ -2332,12 +2366,12 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/ethanol/protein_blend/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
+ . = ..()
drinker.adjust_nutrition(2 * REM * seconds_per_tick)
if(!islizard(drinker))
drinker.adjust_disgust(5 * REM * seconds_per_tick)
else
drinker.adjust_disgust(2 * REM * seconds_per_tick)
- ..()
/datum/reagent/consumable/ethanol/mushi_kombucha
name = "Mushi Kombucha"
@@ -2358,9 +2392,9 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/ethanol/triumphal_arch/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
+ . = ..()
if(islizard(drinker))
drinker.add_mood_event("triumph", /datum/mood_event/memories_of_home, name)
- ..()
/datum/reagent/consumable/ethanol/the_juice
name = "The Juice"
@@ -2378,9 +2412,9 @@
drinker.gain_trauma(prophet_trauma, TRAUMA_RESILIENCE_ABSOLUTE)
/datum/reagent/consumable/ethanol/the_juice/on_mob_end_metabolize(mob/living/carbon/drinker)
+ . = ..()
if(prophet_trauma)
QDEL_NULL(prophet_trauma)
- return ..()
//a jacked up absinthe that causes hallucinations to the game master controller basically, used in smuggling objectives
/datum/reagent/consumable/ethanol/ritual_wine
@@ -2517,11 +2551,10 @@
var/hal_cap = 24
/datum/reagent/consumable/ethanol/helianthus/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
+ . = ..()
if(SPT_PROB(5, seconds_per_tick))
drinker.adjust_hallucinations_up_to(4 SECONDS * REM * seconds_per_tick, 48 SECONDS)
- ..()
-
/datum/reagent/consumable/ethanol/plumwine
name = "Plum wine"
description = "Plums turned into wine."
@@ -2552,8 +2585,8 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/ethanol/gin_garden/on_mob_life(mob/living/carbon/doll, seconds_per_tick, times_fired)
+ . = ..()
doll.adjust_bodytemperature(-5 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, doll.get_body_temp_normal())
- ..()
/datum/reagent/consumable/ethanol/wine_voltaic
name = "Voltaic Yellow Wine"
@@ -2587,8 +2620,8 @@
ADD_TRAIT(affected_mob, TRAIT_SHOCKIMMUNE, type)
/datum/reagent/consumable/ethanol/telepole/on_mob_end_metabolize(mob/living/affected_mob)
+ . = ..()
REMOVE_TRAIT(affected_mob, TRAIT_SHOCKIMMUNE, type)
- return ..()
/datum/reagent/consumable/ethanol/telepole/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume) //can't be on life because of the way blood works.
. = ..()
@@ -2610,11 +2643,11 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/ethanol/pod_tesla/on_mob_metabolize(mob/living/affected_mob)
- ..()
+ . = ..()
affected_mob.add_traits(list(TRAIT_SHOCKIMMUNE,TRAIT_TESLA_SHOCKIMMUNE,TRAIT_FEARLESS), type)
-
/datum/reagent/consumable/ethanol/pod_tesla/on_mob_end_metabolize(mob/living/affected_mob)
+ . = ..()
affected_mob.remove_traits(list(TRAIT_SHOCKIMMUNE,TRAIT_TESLA_SHOCKIMMUNE,TRAIT_FEARLESS), type)
/datum/reagent/consumable/ethanol/pod_tesla/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume) //can't be on life because of the way blood works.
diff --git a/code/modules/reagents/chemistry/reagents/drinks/drink_reagents.dm b/code/modules/reagents/chemistry/reagents/drinks/drink_reagents.dm
index 36444d6229b..8270b42f502 100644
--- a/code/modules/reagents/chemistry/reagents/drinks/drink_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/drinks/drink_reagents.dm
@@ -8,10 +8,10 @@
default_container = /obj/item/reagent_containers/cup/glass/bottle/juice/orangejuice
/datum/reagent/consumable/orangejuice/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
if(affected_mob.getOxyLoss() && SPT_PROB(16, seconds_per_tick))
- affected_mob.adjustOxyLoss(-1, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
- . = TRUE
- ..()
+ if(affected_mob.adjustOxyLoss(-1 * REM * seconds_per_tick, FALSE, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type))
+ return UPDATE_MOB_HEALTH
/datum/reagent/consumable/tomatojuice
name = "Tomato Juice"
@@ -22,10 +22,10 @@
default_container = /obj/item/reagent_containers/cup/glass/bottle/juice/tomatojuice
/datum/reagent/consumable/tomatojuice/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
if(affected_mob.getFireLoss() && SPT_PROB(10, seconds_per_tick))
- affected_mob.heal_bodypart_damage(0, 1)
- . = TRUE
- ..()
+ if(affected_mob.heal_bodypart_damage(brute = 0, burn = 1 * REM * seconds_per_tick, updating_health = FALSE))
+ return UPDATE_MOB_HEALTH
/datum/reagent/consumable/limejuice
name = "Lime Juice"
@@ -37,10 +37,10 @@
default_container = /obj/item/reagent_containers/cup/glass/bottle/juice/limejuice
/datum/reagent/consumable/limejuice/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
if(affected_mob.getToxLoss() && SPT_PROB(10, seconds_per_tick))
- affected_mob.adjustToxLoss(-1, FALSE, required_biotype = affected_biotype)
- . = TRUE
- ..()
+ if(affected_mob.adjustToxLoss(-1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype))
+ return UPDATE_MOB_HEALTH
/datum/reagent/consumable/carrotjuice
name = "Carrot Juice"
@@ -50,17 +50,20 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/carrotjuice/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
affected_mob.adjust_eye_blur(-2 SECONDS * REM * seconds_per_tick)
affected_mob.adjust_temp_blindness(-2 SECONDS * REM * seconds_per_tick)
+ var/need_mob_update
switch(current_cycle)
if(1 to 20)
//nothing
if(21 to 110)
if(SPT_PROB(100 * (1 - (sqrt(110 - current_cycle) / 10)), seconds_per_tick))
- affected_mob.adjustOrganLoss(ORGAN_SLOT_EYES, -2)
+ need_mob_update = affected_mob.adjustOrganLoss(ORGAN_SLOT_EYES, -2 * REM * seconds_per_tick)
if(110 to INFINITY)
- affected_mob.adjustOrganLoss(ORGAN_SLOT_EYES, -2)
- return ..()
+ need_mob_update = affected_mob.adjustOrganLoss(ORGAN_SLOT_EYES, -2 * REM * seconds_per_tick)
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/consumable/berryjuice
name = "Berry Juice"
@@ -84,9 +87,9 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/poisonberryjuice/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
- affected_mob.adjustToxLoss(1 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
- . = TRUE
- ..()
+ . = ..()
+ if(affected_mob.adjustToxLoss(1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype))
+ return UPDATE_MOB_HEALTH
/datum/reagent/consumable/watermelonjuice
name = "Watermelon Juice"
@@ -111,11 +114,11 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/banana/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
var/obj/item/organ/internal/liver/liver = affected_mob.get_organ_slot(ORGAN_SLOT_LIVER)
if((liver && HAS_TRAIT(liver, TRAIT_COMEDY_METABOLISM)) || ismonkey(affected_mob))
- affected_mob.heal_bodypart_damage(1 * REM * seconds_per_tick, 1 * REM * seconds_per_tick)
- . = TRUE
- ..()
+ if(affected_mob.heal_bodypart_damage(brute = 1 * REM * seconds_per_tick, burn = 1 * REM * seconds_per_tick, updating_health = FALSE))
+ return UPDATE_MOB_HEALTH
/datum/reagent/consumable/nothing
name = "Nothing"
@@ -128,11 +131,11 @@
icon_state = "shotglass"
/datum/reagent/consumable/nothing/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
+ . = ..()
if(ishuman(drinker) && HAS_MIND_TRAIT(drinker, TRAIT_MIMING))
drinker.set_silence_if_lower(MIMEDRINK_SILENCE_DURATION)
- drinker.heal_bodypart_damage(1 * REM * seconds_per_tick, 1 * REM * seconds_per_tick)
- . = TRUE
- ..()
+ if(drinker.heal_bodypart_damage(brute = 1 * REM * seconds_per_tick, burn = 1 * REM * seconds_per_tick, updating_health = FALSE))
+ return UPDATE_MOB_HEALTH
/datum/reagent/consumable/laughter
name = "Laughter"
@@ -143,9 +146,9 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/laughter/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
affected_mob.emote("laugh")
affected_mob.add_mood_event("chemical_laughter", /datum/mood_event/chemical_laughter)
- ..()
/datum/reagent/consumable/superlaughter
name = "Super Laughter"
@@ -156,11 +159,11 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/superlaughter/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
if(SPT_PROB(16, seconds_per_tick))
affected_mob.visible_message(span_danger("[affected_mob] bursts out into a fit of uncontrollable laughter!"), span_userdanger("You burst out in a fit of uncontrollable laughter!"))
affected_mob.Stun(5)
affected_mob.add_mood_event("chemical_laughter", /datum/mood_event/chemical_superlaughter)
- ..()
/datum/reagent/consumable/potato_juice
name = "Potato Juice"
@@ -179,11 +182,11 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/pickle/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
var/obj/item/organ/internal/liver/liver = affected_mob.get_organ_slot(ORGAN_SLOT_LIVER)
if((liver && HAS_TRAIT(liver, TRAIT_CORONER_METABOLISM)))
- affected_mob.adjustToxLoss(-1, FALSE, required_biotype = affected_biotype)
- . = TRUE
- ..()
+ if(affected_mob.adjustToxLoss(-1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype))
+ return UPDATE_MOB_HEALTH
/datum/reagent/consumable/grapejuice
name = "Grape Juice"
@@ -219,11 +222,11 @@
/datum/reagent/consumable/milk/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
if(affected_mob.getBruteLoss() && SPT_PROB(10, seconds_per_tick))
- affected_mob.heal_bodypart_damage(1,0)
- . = TRUE
+ if(affected_mob.heal_bodypart_damage(brute = 1 * REM * seconds_per_tick, burn = 0, updating_health = FALSE))
+ . = UPDATE_MOB_HEALTH
if(holder.has_reagent(/datum/reagent/consumable/capsaicin))
holder.remove_reagent(/datum/reagent/consumable/capsaicin, 1 * seconds_per_tick)
- ..()
+ return ..() || .
/datum/reagent/consumable/soymilk
name = "Soy Milk"
@@ -234,10 +237,10 @@
default_container = /obj/item/reagent_containers/condiment/soymilk
/datum/reagent/consumable/soymilk/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
if(affected_mob.getBruteLoss() && SPT_PROB(10, seconds_per_tick))
- affected_mob.heal_bodypart_damage(1, 0)
- . = TRUE
- ..()
+ if(affected_mob.heal_bodypart_damage(1, 0))
+ return UPDATE_MOB_HEALTH
/datum/reagent/consumable/cream
name = "Cream"
@@ -265,8 +268,8 @@
/datum/reagent/consumable/coffee/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
affected_mob.set_jitter_if_lower(10 SECONDS * REM * seconds_per_tick)
- ..()
/datum/reagent/consumable/coffee/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
affected_mob.adjust_dizzy(-10 SECONDS * REM * seconds_per_tick)
@@ -276,8 +279,7 @@
affected_mob.adjust_bodytemperature(25 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, 0, affected_mob.get_body_temp_normal())
if(holder.has_reagent(/datum/reagent/consumable/frostoil))
holder.remove_reagent(/datum/reagent/consumable/frostoil, 5 * REM * seconds_per_tick)
- ..()
- . = TRUE
+ return ..() || .
/datum/reagent/consumable/tea
name = "Tea"
@@ -290,12 +292,16 @@
default_container = /obj/item/reagent_containers/cup/glass/mug/tea
/datum/reagent/consumable/tea/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
affected_mob.adjust_dizzy(-4 SECONDS * REM * seconds_per_tick)
affected_mob.adjust_drowsiness(-2 SECONDS * REM * seconds_per_tick)
affected_mob.adjust_jitter(-6 SECONDS * REM * seconds_per_tick)
affected_mob.AdjustSleeping(-20 * REM * seconds_per_tick)
if(affected_mob.getToxLoss() && SPT_PROB(10, seconds_per_tick))
- affected_mob.adjustToxLoss(-1, FALSE, required_biotype = affected_biotype)
+ if(affected_mob.adjustToxLoss(-1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype))
+ . = UPDATE_MOB_HEALTH
+ affected_mob.adjust_bodytemperature(20 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, 0, affected_mob.get_body_temp_normal())
+
var/to_chatted = FALSE
for(var/datum/wound/iter_wound as anything in affected_mob.all_wounds)
if(SPT_PROB(10, seconds_per_tick))
@@ -303,9 +309,6 @@
if(!to_chatted && helped)
to_chat(affected_mob, span_notice("A calm, relaxed feeling suffuses you. Your wounds feel a little healthier."))
to_chatted = TRUE
- affected_mob.adjust_bodytemperature(20 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, 0, affected_mob.get_body_temp_normal())
- ..()
- . = TRUE
// Different handling, different name.
// Returns FALSE by default so broken bones and 'loss' wounds don't give a false message
@@ -348,10 +351,9 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/tea/arnold_palmer/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
if(SPT_PROB(2.5, seconds_per_tick))
to_chat(affected_mob, span_notice("[pick("You remember to square your shoulders.","You remember to keep your head down.","You can't decide between squaring your shoulders and keeping your head down.","You remember to relax.","You think about how someday you'll get two strokes off your golf game.")]"))
- ..()
- . = TRUE
/datum/reagent/consumable/icecoffee
name = "Iced Coffee"
@@ -362,13 +364,12 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/icecoffee/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
affected_mob.adjust_dizzy(-10 SECONDS * REM * seconds_per_tick)
affected_mob.adjust_drowsiness(-6 SECONDS * REM * seconds_per_tick)
affected_mob.AdjustSleeping(-40 * REM * seconds_per_tick)
affected_mob.adjust_bodytemperature(-5 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, affected_mob.get_body_temp_normal())
affected_mob.set_jitter_if_lower(10 SECONDS * REM * seconds_per_tick)
- ..()
- . = TRUE
/datum/reagent/consumable/hot_ice_coffee
name = "Hot Ice Coffee"
@@ -379,14 +380,14 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/hot_ice_coffee/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
affected_mob.adjust_dizzy(-10 SECONDS * REM * seconds_per_tick)
affected_mob.adjust_drowsiness(-6 SECONDS * REM * seconds_per_tick)
affected_mob.AdjustSleeping(-60 * REM * seconds_per_tick)
affected_mob.adjust_bodytemperature(-7 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, affected_mob.get_body_temp_normal())
affected_mob.set_jitter_if_lower(10 SECONDS * REM * seconds_per_tick)
- affected_mob.adjustToxLoss(1 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
- ..()
- . = TRUE
+ if(affected_mob.adjustToxLoss(1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype))
+ return UPDATE_MOB_HEALTH
/datum/reagent/consumable/icetea
name = "Iced Tea"
@@ -397,14 +398,14 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/icetea/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
affected_mob.adjust_dizzy(-4 SECONDS * REM * seconds_per_tick)
affected_mob.adjust_drowsiness(-2 SECONDS * REM * seconds_per_tick)
affected_mob.AdjustSleeping(-40 * REM * seconds_per_tick)
if(affected_mob.getToxLoss() && SPT_PROB(10, seconds_per_tick))
- affected_mob.adjustToxLoss(-1, FALSE, required_biotype = affected_biotype)
+ if(affected_mob.adjustToxLoss(-1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype))
+ . = UPDATE_MOB_HEALTH
affected_mob.adjust_bodytemperature(-5 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, affected_mob.get_body_temp_normal())
- ..()
- . = TRUE
/datum/reagent/consumable/space_cola
name = "Cola"
@@ -414,9 +415,9 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/space_cola/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
affected_mob.adjust_drowsiness(-10 SECONDS * REM * seconds_per_tick)
affected_mob.adjust_bodytemperature(-5 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, affected_mob.get_body_temp_normal())
- ..()
/datum/reagent/consumable/roy_rogers
name = "Roy Rogers"
@@ -441,22 +442,21 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/nuka_cola/on_mob_metabolize(mob/living/affected_mob)
- ..()
+ . = ..()
affected_mob.add_movespeed_modifier(/datum/movespeed_modifier/reagent/nuka_cola)
/datum/reagent/consumable/nuka_cola/on_mob_end_metabolize(mob/living/affected_mob)
+ . = ..()
affected_mob.remove_movespeed_modifier(/datum/movespeed_modifier/reagent/nuka_cola)
- ..()
/datum/reagent/consumable/nuka_cola/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
affected_mob.set_jitter_if_lower(40 SECONDS * REM * seconds_per_tick)
affected_mob.set_drugginess(1 MINUTES * REM * seconds_per_tick)
affected_mob.adjust_dizzy(3 SECONDS * REM * seconds_per_tick)
affected_mob.remove_status_effect(/datum/status_effect/drowsiness)
affected_mob.AdjustSleeping(-40 * REM * seconds_per_tick)
affected_mob.adjust_bodytemperature(-5 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, affected_mob.get_body_temp_normal())
- ..()
- . = TRUE
/datum/reagent/consumable/rootbeer
name = "root beer"
@@ -471,15 +471,16 @@
var/effect_enabled = FALSE
/datum/reagent/consumable/rootbeer/on_mob_end_metabolize(mob/living/affected_mob)
+ . = ..()
REMOVE_TRAIT(affected_mob, TRAIT_DOUBLE_TAP, type)
if(current_cycle > 10)
to_chat(affected_mob, span_warning("You feel kinda tired as your sugar rush wears off..."))
affected_mob.adjustStaminaLoss(min(80, current_cycle * 3), required_biotype = affected_biotype)
- affected_mob.adjust_drowsiness(current_cycle * 2 SECONDS)
- ..()
+ affected_mob.adjust_drowsiness((current_cycle-1) * 2 SECONDS)
/datum/reagent/consumable/rootbeer/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
- if(current_cycle >= 3 && !effect_enabled) // takes a few seconds for the bonus to kick in to prevent microdosing
+ . = ..()
+ if(current_cycle > 3 && !effect_enabled) // takes a few seconds for the bonus to kick in to prevent microdosing
to_chat(affected_mob, span_notice("You feel your trigger finger getting itchy..."))
ADD_TRAIT(affected_mob, TRAIT_DOUBLE_TAP, type)
effect_enabled = TRUE
@@ -490,9 +491,6 @@
if(current_cycle > 10)
affected_mob.adjust_dizzy(3 SECONDS * REM * seconds_per_tick)
- ..()
- . = TRUE
-
/datum/reagent/consumable/grey_bull
name = "Grey Bull"
description = "Grey Bull, it gives you gloves!"
@@ -502,7 +500,7 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/grey_bull/on_mob_metabolize(mob/living/carbon/affected_atom)
- ..()
+ . = ..()
ADD_TRAIT(affected_atom, TRAIT_SHOCKIMMUNE, type)
var/obj/item/organ/internal/liver/liver = affected_atom.get_organ_slot(ORGAN_SLOT_LIVER)
if(HAS_TRAIT(liver, TRAIT_MAINTENANCE_METABOLISM))
@@ -510,16 +508,16 @@
metabolization_rate *= 0.8
/datum/reagent/consumable/grey_bull/on_mob_end_metabolize(mob/living/affected_mob)
+ . = ..()
REMOVE_TRAIT(affected_mob, TRAIT_SHOCKIMMUNE, type)
- ..()
/datum/reagent/consumable/grey_bull/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
affected_mob.set_jitter_if_lower(40 SECONDS * REM * seconds_per_tick)
affected_mob.adjust_dizzy(2 SECONDS * REM * seconds_per_tick)
affected_mob.remove_status_effect(/datum/status_effect/drowsiness)
affected_mob.AdjustSleeping(-40 * REM * seconds_per_tick)
affected_mob.adjust_bodytemperature(-5 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, affected_mob.get_body_temp_normal())
- ..()
/datum/reagent/consumable/spacemountainwind
name = "SM Wind"
@@ -529,12 +527,11 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/spacemountainwind/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
affected_mob.adjust_drowsiness(-14 SECONDS * REM * seconds_per_tick)
affected_mob.AdjustSleeping(-20 * REM * seconds_per_tick)
affected_mob.adjust_bodytemperature(-5 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, affected_mob.get_body_temp_normal())
affected_mob.set_jitter_if_lower(10 SECONDS * REM * seconds_per_tick)
- ..()
- . = TRUE
/datum/reagent/consumable/dr_gibb
name = "Dr. Gibb"
@@ -544,9 +541,9 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/dr_gibb/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
affected_mob.adjust_drowsiness(-12 SECONDS * REM * seconds_per_tick)
affected_mob.adjust_bodytemperature(-5 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, affected_mob.get_body_temp_normal())
- ..()
/datum/reagent/consumable/space_up
name = "Space-Up"
@@ -556,8 +553,8 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/space_up/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
affected_mob.adjust_bodytemperature(-8 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, affected_mob.get_body_temp_normal())
- ..()
/datum/reagent/consumable/lemon_lime
name = "Lemon Lime"
@@ -567,8 +564,8 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/lemon_lime/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
affected_mob.adjust_bodytemperature(-8 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, affected_mob.get_body_temp_normal())
- ..()
/datum/reagent/consumable/pwr_game
name = "Pwr Game"
@@ -585,10 +582,10 @@
You feel as though a great secret of the universe has been made known to you...")
/datum/reagent/consumable/pwr_game/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
affected_mob.adjust_bodytemperature(-8 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, affected_mob.get_body_temp_normal())
if(SPT_PROB(5, seconds_per_tick))
affected_mob.mind?.adjust_experience(/datum/skill/gaming, 5)
- ..()
/datum/reagent/consumable/shamblers
name = "Shambler's Juice"
@@ -598,8 +595,8 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/shamblers/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
affected_mob.adjust_bodytemperature(-8 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, affected_mob.get_body_temp_normal())
- ..()
/datum/reagent/consumable/sodawater
name = "Soda Water"
@@ -615,10 +612,10 @@
mytray.adjust_plant_health(round(volume * 0.1))
/datum/reagent/consumable/sodawater/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
affected_mob.adjust_dizzy(-10 SECONDS * REM * seconds_per_tick)
affected_mob.adjust_drowsiness(-6 SECONDS * REM * seconds_per_tick)
affected_mob.adjust_bodytemperature(-5 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, affected_mob.get_body_temp_normal())
- ..()
/datum/reagent/consumable/tonic
name = "Tonic Water"
@@ -628,12 +625,11 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/tonic/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
affected_mob.adjust_dizzy(-10 SECONDS * REM * seconds_per_tick)
affected_mob.adjust_drowsiness(-6 SECONDS * REM * seconds_per_tick)
affected_mob.AdjustSleeping(-40 * REM * seconds_per_tick)
affected_mob.adjust_bodytemperature(-5 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, affected_mob.get_body_temp_normal())
- ..()
- . = TRUE
/datum/reagent/consumable/wellcheers
name = "Wellcheers"
@@ -643,15 +639,18 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/wellcheers/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
affected_mob.adjust_drowsiness(3 SECONDS * REM * seconds_per_tick)
+ var/need_mob_update
switch(affected_mob.mob_mood.sanity_level)
if (SANITY_INSANE to SANITY_CRAZY)
- affected_mob.adjustStaminaLoss(3 * REM * seconds_per_tick, 0)
+ need_mob_update = affected_mob.adjustStaminaLoss(3 * REM * seconds_per_tick, updating_stamina = FALSE)
if (SANITY_UNSTABLE to SANITY_DISTURBED)
affected_mob.add_mood_event("wellcheers", /datum/mood_event/wellcheers)
if (SANITY_NEUTRAL to SANITY_GREAT)
- affected_mob.adjustBruteLoss(-1.5 * REM * seconds_per_tick, 0)
- return ..()
+ need_mob_update = affected_mob.adjustBruteLoss(-1.5 * REM * seconds_per_tick, updating_health = FALSE)
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/consumable/monkey_energy
name = "Monkey Energy"
@@ -662,26 +661,26 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/monkey_energy/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
affected_mob.set_jitter_if_lower(80 SECONDS * REM * seconds_per_tick)
affected_mob.adjust_dizzy(2 SECONDS * REM * seconds_per_tick)
affected_mob.remove_status_effect(/datum/status_effect/drowsiness)
affected_mob.AdjustSleeping(-40 * REM * seconds_per_tick)
affected_mob.adjust_bodytemperature(-5 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, affected_mob.get_body_temp_normal())
- ..()
/datum/reagent/consumable/monkey_energy/on_mob_metabolize(mob/living/affected_mob)
- ..()
+ . = ..()
if(ismonkey(affected_mob))
affected_mob.add_movespeed_modifier(/datum/movespeed_modifier/reagent/monkey_energy)
/datum/reagent/consumable/monkey_energy/on_mob_end_metabolize(mob/living/affected_mob)
+ . = ..()
affected_mob.remove_movespeed_modifier(/datum/movespeed_modifier/reagent/monkey_energy)
- ..()
/datum/reagent/consumable/monkey_energy/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
if(SPT_PROB(7.5, seconds_per_tick))
affected_mob.say(pick_list_replacements(BOOMER_FILE, "boomer"), forced = /datum/reagent/consumable/monkey_energy)
- ..()
/datum/reagent/consumable/ice
name = "Ice"
@@ -693,8 +692,9 @@
default_container = /obj/item/reagent_containers/cup/glass/ice
/datum/reagent/consumable/ice/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
- affected_mob.adjust_bodytemperature(-5 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, affected_mob.get_body_temp_normal())
- ..()
+ . = ..()
+ if(affected_mob.adjust_bodytemperature(-5 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, FALSE, affected_mob.get_body_temp_normal()))
+ return UPDATE_MOB_HEALTH
/datum/reagent/consumable/soy_latte
name = "Soy Latte"
@@ -706,15 +706,17 @@
glass_price = DRINK_PRICE_EASY
/datum/reagent/consumable/soy_latte/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
affected_mob.adjust_dizzy(-10 SECONDS * REM * seconds_per_tick)
affected_mob.adjust_drowsiness(-6 SECONDS * REM * seconds_per_tick)
- affected_mob.SetSleeping(0)
+ var/need_mob_update
+ need_mob_update = affected_mob.SetSleeping(0)
affected_mob.adjust_bodytemperature(5 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, 0, affected_mob.get_body_temp_normal())
affected_mob.set_jitter_if_lower(10 SECONDS * REM * seconds_per_tick)
if(affected_mob.getBruteLoss() && SPT_PROB(10, seconds_per_tick))
- affected_mob.heal_bodypart_damage(1,0)
- ..()
- . = TRUE
+ need_mob_update += affected_mob.heal_bodypart_damage(brute = 1 * REM * seconds_per_tick, burn = 0, updating_health = FALSE)
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/consumable/cafe_latte
name = "Cafe Latte"
@@ -726,15 +728,17 @@
glass_price = DRINK_PRICE_EASY
/datum/reagent/consumable/cafe_latte/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
affected_mob.adjust_dizzy(-10 SECONDS * REM * seconds_per_tick)
affected_mob.adjust_drowsiness(-12 SECONDS * REM * seconds_per_tick)
- affected_mob.SetSleeping(0)
+ var/need_mob_update
+ need_mob_update = affected_mob.SetSleeping(0)
affected_mob.adjust_bodytemperature(5 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, 0, affected_mob.get_body_temp_normal())
affected_mob.set_jitter_if_lower(10 SECONDS * REM * seconds_per_tick)
if(affected_mob.getBruteLoss() && SPT_PROB(10, seconds_per_tick))
- affected_mob.heal_bodypart_damage(1, 0)
- ..()
- . = TRUE
+ need_mob_update += affected_mob.heal_bodypart_damage(brute = 1 * REM * seconds_per_tick, burn = 0, updating_health = FALSE)
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/consumable/doctor_delight
name = "The Doctor's Delight"
@@ -745,17 +749,19 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/doctor_delight/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
- affected_mob.adjustBruteLoss(-0.5 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype)
- affected_mob.adjustFireLoss(-0.5 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype)
- affected_mob.adjustToxLoss(-0.5 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
- affected_mob.adjustOxyLoss(-0.5 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
+ . = ..()
+ var/need_mob_update
+ need_mob_update = affected_mob.adjustBruteLoss(-0.5 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
+ need_mob_update += affected_mob.adjustFireLoss(-0.5 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
+ need_mob_update += affected_mob.adjustToxLoss(-0.5 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)
+ need_mob_update += affected_mob.adjustOxyLoss(-0.5 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
if(affected_mob.nutrition && (affected_mob.nutrition - 2 > 0))
var/obj/item/organ/internal/liver/liver = affected_mob.get_organ_slot(ORGAN_SLOT_LIVER)
if(!(HAS_TRAIT(liver, TRAIT_MEDICAL_METABOLISM)))
// Drains the nutrition of the holder. Not medical doctors though, since it's the Doctor's Delight!
affected_mob.adjust_nutrition(-2 * REM * seconds_per_tick)
- ..()
- . = TRUE
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/consumable/cinderella
name = "Cinderella"
@@ -766,8 +772,8 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/cinderella/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
affected_mob.adjust_disgust(-5 * REM * seconds_per_tick)
- return ..()
/datum/reagent/consumable/cherryshake
name = "Cherry Shake"
@@ -886,8 +892,8 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/grape_soda/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
affected_mob.adjust_bodytemperature(-5 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, affected_mob.get_body_temp_normal())
- ..()
/datum/reagent/consumable/milk/chocolate_milk
name = "Chocolate Milk"
@@ -908,11 +914,11 @@
/datum/reagent/consumable/hot_coco/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
affected_mob.adjust_bodytemperature(5 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, 0, affected_mob.get_body_temp_normal())
if(affected_mob.getBruteLoss() && SPT_PROB(10, seconds_per_tick))
- affected_mob.heal_bodypart_damage(1, 0)
- . = TRUE
+ if(affected_mob.heal_bodypart_damage(brute = 1 * REM * seconds_per_tick, burn = 0, updating_health = FALSE))
+ . = UPDATE_MOB_HEALTH
if(holder.has_reagent(/datum/reagent/consumable/capsaicin))
holder.remove_reagent(/datum/reagent/consumable/capsaicin, 2 * REM * seconds_per_tick)
- ..()
+ return ..() || .
/datum/reagent/consumable/italian_coco
name = "Italian Hot Chocolate"
@@ -924,8 +930,8 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/italian_coco/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
affected_mob.adjust_bodytemperature(5 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, 0, affected_mob.get_body_temp_normal())
- return ..()
/datum/reagent/consumable/menthol
name = "Menthol"
@@ -936,8 +942,8 @@
default_container = /obj/item/reagent_containers/cup/glass/bottle/juice/menthol
/datum/reagent/consumable/menthol/on_mob_life(mob/living/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
affected_mob.apply_status_effect(/datum/status_effect/throat_soothed)
- ..()
/datum/reagent/consumable/grenadine
name = "Grenadine"
@@ -977,8 +983,8 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/cream_soda/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
affected_mob.adjust_bodytemperature(-5 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, affected_mob.get_body_temp_normal())
- ..()
/datum/reagent/consumable/sol_dry
name = "Sol Dry"
@@ -989,8 +995,8 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/sol_dry/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
affected_mob.adjust_disgust(-5 * REM * seconds_per_tick)
- ..()
/datum/reagent/consumable/shirley_temple
name = "Shirley Temple"
@@ -1014,8 +1020,9 @@
var/current_size = RESIZE_DEFAULT_SIZE
/datum/reagent/consumable/red_queen/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
if(SPT_PROB(50, seconds_per_tick))
- return ..()
+ return
var/newsize = pick(0.5, 0.75, 1, 1.50, 2)
newsize *= RESIZE_DEFAULT_SIZE
@@ -1023,12 +1030,11 @@
current_size = newsize
if(SPT_PROB(23, seconds_per_tick))
affected_mob.emote("sneeze")
- ..()
/datum/reagent/consumable/red_queen/on_mob_end_metabolize(mob/living/affected_mob)
+ . = ..()
affected_mob.update_transform(RESIZE_DEFAULT_SIZE/current_size)
current_size = RESIZE_DEFAULT_SIZE
- ..()
/datum/reagent/consumable/bungojuice
name = "Bungo Juice"
@@ -1052,10 +1058,10 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/aloejuice/on_mob_life(mob/living/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
if(affected_mob.getToxLoss() && SPT_PROB(16, seconds_per_tick))
- affected_mob.adjustToxLoss(-1, FALSE, required_biotype = affected_biotype)
- ..()
- . = TRUE
+ if(affected_mob.adjustToxLoss(-1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype))
+ return UPDATE_MOB_HEALTH
/datum/reagent/consumable/agua_fresca
name = "Agua Fresca"
@@ -1066,10 +1072,11 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/agua_fresca/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
affected_mob.adjust_bodytemperature(-8 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, affected_mob.get_body_temp_normal())
if(affected_mob.getToxLoss() && SPT_PROB(10, seconds_per_tick))
- affected_mob.adjustToxLoss(-0.5, FALSE, required_biotype = affected_biotype)
- return ..()
+ if(affected_mob.adjustToxLoss(-0.5, updating_health = FALSE, required_biotype = affected_biotype))
+ return UPDATE_MOB_HEALTH
/datum/reagent/consumable/mushroom_tea
name = "Mushroom Tea"
@@ -1080,10 +1087,10 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/mushroom_tea/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
if(islizard(affected_mob))
- affected_mob.adjustOxyLoss(-0.5 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
- ..()
- . = TRUE
+ if(affected_mob.adjustOxyLoss(-0.5 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type))
+ return UPDATE_MOB_HEALTH
//Moth Stuff
/datum/reagent/consumable/toechtauese_juice
@@ -1166,10 +1173,11 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/cucumberlemonade/on_mob_life(mob/living/carbon/doll, seconds_per_tick, times_fired)
+ . = ..()
doll.adjust_bodytemperature(-8 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, doll.get_body_temp_normal())
if(doll.getToxLoss() && SPT_PROB(10, seconds_per_tick))
- doll.adjustToxLoss(-0.5, FALSE, required_biotype = affected_biotype)
- return ..()
+ if(doll.adjustToxLoss(-0.5, updating_health = FALSE, required_biotype = affected_biotype))
+ return UPDATE_MOB_HEALTH
/datum/reagent/consumable/mississippi_queen
name = "Mississippi Queen"
@@ -1179,17 +1187,16 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/mississippi_queen/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
+ . = ..()
switch(current_cycle)
- if(10 to 20)
+ if(11 to 21)
drinker.adjust_dizzy(4 SECONDS * REM * seconds_per_tick)
- if(20 to 30)
+ if(21 to 31)
if(SPT_PROB(15, seconds_per_tick))
drinker.adjust_confusion(4 SECONDS * REM * seconds_per_tick)
- if(30 to 200)
+ if(31 to 201)
drinker.adjust_hallucinations(60 SECONDS * REM * seconds_per_tick)
- return ..()
-
/datum/reagent/consumable/t_letter
name = "T"
description = "You expected to find this in a soup, but this is fine too."
@@ -1198,14 +1205,15 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/t_letter/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
if(!HAS_MIND_TRAIT(affected_mob, TRAIT_MIMING))
- return ..()
+ return
affected_mob.set_silence_if_lower(MIMEDRINK_SILENCE_DURATION)
affected_mob.adjust_drowsiness(-6 SECONDS * REM * seconds_per_tick)
affected_mob.AdjustSleeping(-40 * REM * seconds_per_tick)
if(affected_mob.getToxLoss() && SPT_PROB(25, seconds_per_tick))
- affected_mob.adjustToxLoss(-2, FALSE, required_biotype = affected_biotype)
- return ..()
+ if(affected_mob.adjustToxLoss(-2 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype))
+ return UPDATE_MOB_HEALTH
/datum/reagent/consumable/hakka_mate
name = "Hakka-Mate"
diff --git a/code/modules/reagents/chemistry/reagents/drug_reagents.dm b/code/modules/reagents/chemistry/reagents/drug_reagents.dm
index 23d6010f1a9..56552fccf63 100644
--- a/code/modules/reagents/chemistry/reagents/drug_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/drug_reagents.dm
@@ -18,22 +18,23 @@
addiction_types = list(/datum/addiction/hallucinogens = 10) //4 per 2 seconds
/datum/reagent/drug/space_drugs/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
affected_mob.set_drugginess(30 SECONDS * REM * seconds_per_tick)
if(isturf(affected_mob.loc) && !isspaceturf(affected_mob.loc) && !HAS_TRAIT(affected_mob, TRAIT_IMMOBILIZED) && SPT_PROB(5, seconds_per_tick))
step(affected_mob, pick(GLOB.cardinals))
if(SPT_PROB(3.5, seconds_per_tick))
affected_mob.emote(pick("twitch","drool","moan","giggle"))
- ..()
/datum/reagent/drug/space_drugs/overdose_start(mob/living/affected_mob)
+ . = ..()
to_chat(affected_mob, span_userdanger("You start tripping hard!"))
affected_mob.add_mood_event("[type]_overdose", /datum/mood_event/overdose, name)
/datum/reagent/drug/space_drugs/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
var/hallucination_duration_in_seconds = (affected_mob.get_timed_status_effect_duration(/datum/status_effect/hallucination) / 10)
if(hallucination_duration_in_seconds < volume && SPT_PROB(10, seconds_per_tick))
affected_mob.adjust_hallucinations(10 SECONDS)
- ..()
/datum/reagent/drug/cannabis
name = "Cannabis"
@@ -45,6 +46,7 @@
metabolization_rate = 0.125 * REAGENTS_METABOLISM
/datum/reagent/drug/cannabis/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
affected_mob.apply_status_effect(/datum/status_effect/stoned)
if(SPT_PROB(1, seconds_per_tick))
var/smoke_message = pick("You feel relaxed.","You feel calmed.","Your mouth feels dry.","You could use some water.","Your heart beats quickly.","You feel clumsy.","You crave junk food.","You notice you've been moving more slowly.")
@@ -58,7 +60,6 @@
if(SPT_PROB(4, seconds_per_tick) && affected_mob.buckled && affected_mob.body_position != LYING_DOWN && !affected_mob.IsParalyzed()) //chance to be couchlocked if sitting
to_chat(affected_mob, "It's too comfy to move...")
affected_mob.Paralyze(10 SECONDS)
- return ..()
/datum/reagent/drug/nicotine
name = "Nicotine"
@@ -79,6 +80,7 @@
mytray.adjust_pestlevel(-rand(1, 2))
/datum/reagent/drug/nicotine/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
if(SPT_PROB(0.5, seconds_per_tick))
var/smoke_message = pick("You feel relaxed.", "You feel calmed.","You feel alert.","You feel rugged.")
to_chat(affected_mob, span_notice("[smoke_message]"))
@@ -89,14 +91,15 @@
affected_mob.AdjustUnconscious(-50 * REM * seconds_per_tick)
affected_mob.AdjustParalyzed(-50 * REM * seconds_per_tick)
affected_mob.AdjustImmobilized(-50 * REM * seconds_per_tick)
- ..()
- . = TRUE
+ return UPDATE_MOB_HEALTH
/datum/reagent/drug/nicotine/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired)
- affected_mob.adjustToxLoss(0.1 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
- affected_mob.adjustOxyLoss(1.1 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
- ..()
- . = TRUE
+ . = ..()
+ var/need_mob_update
+ need_mob_update = affected_mob.adjustToxLoss(0.1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)
+ need_mob_update += affected_mob.adjustOxyLoss(1.1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/drug/krokodil
name = "Krokodil"
@@ -110,28 +113,28 @@
/datum/reagent/drug/krokodil/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
var/high_message = pick("You feel calm.", "You feel collected.", "You feel like you need to relax.")
if(SPT_PROB(2.5, seconds_per_tick))
to_chat(affected_mob, span_notice("[high_message]"))
affected_mob.add_mood_event("smacked out", /datum/mood_event/narcotic_heavy, name)
- if(current_cycle == 35 && creation_purity <= 0.6)
+ if(current_cycle == 36 && creation_purity <= 0.6)
if(!istype(affected_mob.dna.species, /datum/species/human/krokodil_addict))
to_chat(affected_mob, span_userdanger("Your skin falls off easily!"))
var/mob/living/carbon/human/affected_human = affected_mob
affected_human.set_facial_hairstyle("Shaved", update = FALSE)
affected_human.set_hairstyle("Bald", update = FALSE)
affected_mob.set_species(/datum/species/human/krokodil_addict)
- affected_mob.adjustBruteLoss(50 * REM, FALSE, required_bodytype = affected_bodytype) // holy shit your skin just FELL THE FUCK OFF
- . = TRUE
- ..()
+ if(affected_mob.adjustBruteLoss(50 * REM, updating_health = FALSE, required_bodytype = affected_bodytype)) // holy shit your skin just FELL THE FUCK OFF
+ return UPDATE_MOB_HEALTH
/datum/reagent/drug/krokodil/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired)
- affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.25 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)
- affected_mob.adjustToxLoss(0.25 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
- ..()
- . = TRUE
-
-
+ . = ..()
+ var/need_mob_update
+ need_mob_update = affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.25 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)
+ need_mob_update = affected_mob.adjustToxLoss(0.25 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/drug/methamphetamine
name = "Methamphetamine"
@@ -159,15 +162,16 @@
var/effective_impurity = min(1, (1 - creation_purity)/0.5)
color = BlendRGB(initial(color), "#FAFAFA", effective_impurity)
-/datum/reagent/drug/methamphetamine/on_mob_metabolize(mob/living/L)
- ..()
- L.add_movespeed_modifier(/datum/movespeed_modifier/reagent/methamphetamine)
+/datum/reagent/drug/methamphetamine/on_mob_metabolize(mob/living/affected_mob)
+ . = ..()
+ affected_mob.add_movespeed_modifier(/datum/movespeed_modifier/reagent/methamphetamine)
-/datum/reagent/drug/methamphetamine/on_mob_end_metabolize(mob/living/L)
- L.remove_movespeed_modifier(/datum/movespeed_modifier/reagent/methamphetamine)
- ..()
+/datum/reagent/drug/methamphetamine/on_mob_end_metabolize(mob/living/affected_mob)
+ . = ..()
+ affected_mob.remove_movespeed_modifier(/datum/movespeed_modifier/reagent/methamphetamine)
/datum/reagent/drug/methamphetamine/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
var/high_message = pick("You feel hyper.", "You feel like you need to go faster.", "You feel like you can run the world.")
if(SPT_PROB(2.5, seconds_per_tick))
to_chat(affected_mob, span_notice("[high_message]"))
@@ -177,15 +181,17 @@
affected_mob.AdjustUnconscious(-40 * REM * seconds_per_tick)
affected_mob.AdjustParalyzed(-40 * REM * seconds_per_tick)
affected_mob.AdjustImmobilized(-40 * REM * seconds_per_tick)
- affected_mob.adjustStaminaLoss(-2 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
+ var/need_mob_update
+ need_mob_update = affected_mob.adjustStaminaLoss(-2 * REM * seconds_per_tick, updating_stamina = FALSE, required_biotype = affected_biotype)
affected_mob.set_jitter_if_lower(4 SECONDS * REM * seconds_per_tick)
- affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, rand(1, 4) * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)
+ need_mob_update += affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, rand(1, 4) * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)
+ if(need_mob_update)
+ . = UPDATE_MOB_HEALTH
if(SPT_PROB(2.5, seconds_per_tick))
affected_mob.emote(pick("twitch", "shiver"))
- ..()
- . = TRUE
/datum/reagent/drug/methamphetamine/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
if(!HAS_TRAIT(affected_mob, TRAIT_IMMOBILIZED) && !ismovable(affected_mob.loc))
for(var/i in 1 to round(4 * REM * seconds_per_tick, 1))
step(affected_mob, pick(GLOB.cardinals))
@@ -194,10 +200,11 @@
if(SPT_PROB(18, seconds_per_tick))
affected_mob.visible_message(span_danger("[affected_mob]'s hands flip out and flail everywhere!"))
affected_mob.drop_all_held_items()
- ..()
- affected_mob.adjustToxLoss(1 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
- affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, (rand(5, 10) / 10) * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)
- . = TRUE
+ var/need_mob_update
+ need_mob_update = affected_mob.adjustToxLoss(1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)
+ need_mob_update += affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, (rand(5, 10) / 10) * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/drug/bath_salts
name = "Bath Salts"
@@ -211,35 +218,38 @@
ph = 8.2
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
-/datum/reagent/drug/bath_salts/on_mob_metabolize(mob/living/L)
- ..()
- L.add_traits(list(TRAIT_STUNIMMUNE, TRAIT_SLEEPIMMUNE), type)
- if(iscarbon(L))
- var/mob/living/carbon/C = L
+/datum/reagent/drug/bath_salts/on_mob_metabolize(mob/living/affected_mob)
+ . = ..()
+ affected_mob.add_traits(list(TRAIT_STUNIMMUNE, TRAIT_SLEEPIMMUNE), type)
+ if(iscarbon(affected_mob))
+ var/mob/living/carbon/carbon_mob = affected_mob
rage = new()
- C.gain_trauma(rage, TRAUMA_RESILIENCE_ABSOLUTE)
+ carbon_mob.gain_trauma(rage, TRAUMA_RESILIENCE_ABSOLUTE)
-/datum/reagent/drug/bath_salts/on_mob_end_metabolize(mob/living/L)
- L.remove_traits(list(TRAIT_STUNIMMUNE, TRAIT_SLEEPIMMUNE), type)
+/datum/reagent/drug/bath_salts/on_mob_end_metabolize(mob/living/affected_mob)
+ . = ..()
+ affected_mob.remove_traits(list(TRAIT_STUNIMMUNE, TRAIT_SLEEPIMMUNE), type)
if(rage)
QDEL_NULL(rage)
- ..()
/datum/reagent/drug/bath_salts/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
var/high_message = pick("You feel amped up.", "You feel ready.", "You feel like you can push it to the limit.")
if(SPT_PROB(2.5, seconds_per_tick))
to_chat(affected_mob, span_notice("[high_message]"))
affected_mob.add_mood_event("salted", /datum/mood_event/stimulant_heavy, name)
- affected_mob.adjustStaminaLoss(-5 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
- affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 4 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)
+ var/need_mob_update
+ need_mob_update = affected_mob.adjustStaminaLoss(-5 * REM * seconds_per_tick, updating_stamina = FALSE, required_biotype = affected_biotype)
+ need_mob_update += affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 4 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)
affected_mob.adjust_hallucinations(10 SECONDS * REM * seconds_per_tick)
+ if(need_mob_update)
+ . = UPDATE_MOB_HEALTH
if(!HAS_TRAIT(affected_mob, TRAIT_IMMOBILIZED) && !ismovable(affected_mob.loc))
step(affected_mob, pick(GLOB.cardinals))
step(affected_mob, pick(GLOB.cardinals))
- ..()
- . = TRUE
/datum/reagent/drug/bath_salts/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
affected_mob.adjust_hallucinations(10 SECONDS * REM * seconds_per_tick)
if(!HAS_TRAIT(affected_mob, TRAIT_IMMOBILIZED) && !ismovable(affected_mob.loc))
for(var/i in 1 to round(8 * REM * seconds_per_tick, 1))
@@ -248,7 +258,6 @@
affected_mob.emote(pick("twitch","drool","moan"))
if(SPT_PROB(28, seconds_per_tick))
affected_mob.drop_all_held_items()
- ..()
/datum/reagent/drug/aranesp
name = "Aranesp"
@@ -259,16 +268,18 @@
addiction_types = list(/datum/addiction/stimulants = 8)
/datum/reagent/drug/aranesp/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
var/high_message = pick("You feel amped up.", "You feel ready.", "You feel like you can push it to the limit.")
if(SPT_PROB(2.5, seconds_per_tick))
to_chat(affected_mob, span_notice("[high_message]"))
- affected_mob.adjustStaminaLoss(-18 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
- affected_mob.adjustToxLoss(0.5 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
+ var/need_mob_update
+ need_mob_update = affected_mob.adjustStaminaLoss(-18 * REM * seconds_per_tick, updating_stamina = FALSE, required_biotype = affected_biotype)
+ need_mob_update += affected_mob.adjustToxLoss(0.5 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)
if(SPT_PROB(30, seconds_per_tick))
affected_mob.losebreath++
- affected_mob.adjustOxyLoss(1, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
- ..()
- . = TRUE
+ need_mob_update += affected_mob.adjustOxyLoss(1, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/drug/happiness
name = "Happiness"
@@ -280,25 +291,26 @@
taste_description = "paint thinner"
addiction_types = list(/datum/addiction/hallucinogens = 18)
-/datum/reagent/drug/happiness/on_mob_metabolize(mob/living/L)
- ..()
- ADD_TRAIT(L, TRAIT_FEARLESS, type)
- L.add_mood_event("happiness_drug", /datum/mood_event/happiness_drug)
+/datum/reagent/drug/happiness/on_mob_metabolize(mob/living/affected_mob)
+ . = ..()
+ ADD_TRAIT(affected_mob, TRAIT_FEARLESS, type)
+ affected_mob.add_mood_event("happiness_drug", /datum/mood_event/happiness_drug)
-/datum/reagent/drug/happiness/on_mob_delete(mob/living/L)
- REMOVE_TRAIT(L, TRAIT_FEARLESS, type)
- L.clear_mood_event("happiness_drug")
- ..()
+/datum/reagent/drug/happiness/on_mob_delete(mob/living/affected_mob)
+ . = ..()
+ REMOVE_TRAIT(affected_mob, TRAIT_FEARLESS, type)
+ affected_mob.clear_mood_event("happiness_drug")
/datum/reagent/drug/happiness/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
affected_mob.remove_status_effect(/datum/status_effect/jitter)
affected_mob.remove_status_effect(/datum/status_effect/confusion)
affected_mob.disgust = 0
- affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.2 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)
- ..()
- . = TRUE
+ if(affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.2 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags))
+ return UPDATE_MOB_HEALTH
/datum/reagent/drug/happiness/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
if(SPT_PROB(16, seconds_per_tick))
var/reaction = rand(1,3)
switch(reaction)
@@ -311,9 +323,8 @@
if(3)
affected_mob.emote("frown")
affected_mob.add_mood_event("happiness_drug", /datum/mood_event/happiness_drug_bad_od)
- affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.5 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)
- ..()
- . = TRUE
+ if(affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.5 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags))
+ return UPDATE_MOB_HEALTH
/datum/reagent/drug/pumpup
name = "Pump-Up"
@@ -334,45 +345,54 @@
metabolization_rate *= 0.8
/datum/reagent/drug/pumpup/on_mob_end_metabolize(mob/living/affected_mob)
+ . = ..()
REMOVE_TRAIT(affected_mob, TRAIT_BATON_RESISTANCE, type)
- return ..()
/datum/reagent/drug/pumpup/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
affected_mob.set_jitter_if_lower(10 SECONDS * REM * seconds_per_tick)
if(SPT_PROB(2.5, seconds_per_tick))
to_chat(affected_mob, span_notice("[pick("Go! Go! GO!", "You feel ready...", "You feel invincible...")]"))
if(SPT_PROB(7.5, seconds_per_tick))
affected_mob.losebreath++
- affected_mob.adjustToxLoss(2, FALSE, required_biotype = affected_biotype)
- . = TRUE
- ..()
-
+ affected_mob.adjustToxLoss(2, updating_health = FALSE, required_biotype = affected_biotype)
+ return UPDATE_MOB_HEALTH
/datum/reagent/drug/pumpup/overdose_start(mob/living/affected_mob)
+ . = ..()
to_chat(affected_mob, span_userdanger("You can't stop shaking, your heart beats faster and faster..."))
/datum/reagent/drug/pumpup/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
affected_mob.set_jitter_if_lower(10 SECONDS * REM * seconds_per_tick)
+ var/need_mob_update
if(SPT_PROB(2.5, seconds_per_tick))
affected_mob.drop_all_held_items()
if(SPT_PROB(7.5, seconds_per_tick))
affected_mob.emote(pick("twitch","drool"))
if(SPT_PROB(10, seconds_per_tick))
affected_mob.losebreath++
- affected_mob.adjustStaminaLoss(4, FALSE, required_biotype = affected_biotype)
+ affected_mob.adjustStaminaLoss(4, updating_stamina = FALSE, required_biotype = affected_biotype)
+ need_mob_update = TRUE
if(SPT_PROB(7.5, seconds_per_tick))
- affected_mob.adjustToxLoss(2, FALSE, required_biotype = affected_biotype)
- ..()
+ need_mob_update += affected_mob.adjustToxLoss(2, updating_health = FALSE, required_biotype = affected_biotype)
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/drug/maint
name = "Maintenance Drugs"
chemical_flags = NONE
-/datum/reagent/drug/maint/on_mob_metabolize(mob/living/carbon/L)
- var/obj/item/organ/internal/liver/liver = L.get_organ_slot(ORGAN_SLOT_LIVER)
+/datum/reagent/drug/maint/on_mob_metabolize(mob/living/affected_mob)
+ . = ..()
+ if(!iscarbon(affected_mob))
+ return
+
+ var/mob/living/carbon/carbon_mob = affected_mob
+ var/obj/item/organ/internal/liver/liver = carbon_mob.get_organ_slot(ORGAN_SLOT_LIVER)
if(HAS_TRAIT(liver, TRAIT_MAINTENANCE_METABOLISM))
- L.add_mood_event("maintenance_fun", /datum/mood_event/maintenance_high)
+ carbon_mob.add_mood_event("maintenance_fun", /datum/mood_event/maintenance_high)
metabolization_rate *= 0.8
/datum/reagent/drug/maint/powder
@@ -400,7 +420,8 @@
/datum/reagent/drug/maint/powder/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired)
. = ..()
- affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 6 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)
+ if(affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 6 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags))
+ return UPDATE_MOB_HEALTH
/datum/reagent/drug/maint/sludge
name = "Maintenance Sludge"
@@ -412,15 +433,14 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
addiction_types = list(/datum/addiction/maintenance_drugs = 8)
-/datum/reagent/drug/maint/sludge/on_mob_metabolize(mob/living/L)
-
+/datum/reagent/drug/maint/sludge/on_mob_metabolize(mob/living/affected_mob)
. = ..()
- ADD_TRAIT(L,TRAIT_HARDLY_WOUNDED,type)
+ ADD_TRAIT(affected_mob,TRAIT_HARDLY_WOUNDED,type)
/datum/reagent/drug/maint/sludge/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
. = ..()
- affected_mob.adjustToxLoss(0.5 * REM * seconds_per_tick, required_biotype = affected_biotype)
- return TRUE
+ if(affected_mob.adjustToxLoss(0.5 * REM * seconds_per_tick, required_biotype = affected_biotype))
+ return UPDATE_MOB_HEALTH
/datum/reagent/drug/maint/sludge/on_mob_end_metabolize(mob/living/affected_mob)
. = ..()
@@ -432,10 +452,13 @@
return
var/mob/living/carbon/carbie = affected_mob
//You will be vomiting so the damage is really for a few ticks before you flush it out of your system
- carbie.adjustToxLoss(1 * REM * seconds_per_tick, required_biotype = affected_biotype)
+ var/need_mob_update
+ need_mob_update = carbie.adjustToxLoss(1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)
if(SPT_PROB(5, seconds_per_tick))
- carbie.adjustToxLoss(5, required_biotype = affected_biotype)
+ need_mob_update += carbie.adjustToxLoss(5, required_biotype = affected_biotype, updating_health = FALSE)
carbie.vomit(VOMIT_CATEGORY_DEFAULT)
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/drug/maint/tar
name = "Maintenance Tar"
@@ -454,13 +477,15 @@
affected_mob.AdjustParalyzed(-10 * REM * seconds_per_tick)
affected_mob.AdjustImmobilized(-10 * REM * seconds_per_tick)
affected_mob.adjustOrganLoss(ORGAN_SLOT_LIVER, 1.5 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)
- return TRUE
+ return UPDATE_MOB_HEALTH
/datum/reagent/drug/maint/tar/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired)
. = ..()
-
- affected_mob.adjustToxLoss(5 * REM * seconds_per_tick, required_biotype = affected_biotype)
- affected_mob.adjustOrganLoss(ORGAN_SLOT_LIVER, 3 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)
+ var/need_update
+ need_update = affected_mob.adjustToxLoss(5 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)
+ need_update += affected_mob.adjustOrganLoss(ORGAN_SLOT_LIVER, 3 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)
+ if(need_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/drug/mushroomhallucinogen
name = "Mushroom Hallucinogen"
@@ -474,21 +499,21 @@
addiction_types = list(/datum/addiction/hallucinogens = 12)
/datum/reagent/drug/mushroomhallucinogen/on_mob_life(mob/living/carbon/psychonaut, seconds_per_tick, times_fired)
+ . = ..()
psychonaut.set_slurring_if_lower(1 SECONDS * REM * seconds_per_tick)
switch(current_cycle)
- if(1 to 5)
+ if(2 to 6)
if(SPT_PROB(5, seconds_per_tick))
psychonaut.emote(pick("twitch","giggle"))
- if(5 to 10)
+ if(6 to 11)
psychonaut.set_jitter_if_lower(20 SECONDS * REM * seconds_per_tick)
if(SPT_PROB(10, seconds_per_tick))
psychonaut.emote(pick("twitch","giggle"))
- if (10 to INFINITY)
+ if (11 to INFINITY)
psychonaut.set_jitter_if_lower(40 SECONDS * REM * seconds_per_tick)
if(SPT_PROB(16, seconds_per_tick))
psychonaut.emote(pick("twitch","giggle"))
- ..()
/datum/reagent/drug/mushroomhallucinogen/on_mob_metabolize(mob/living/psychonaut)
. = ..()
@@ -601,16 +626,17 @@
/datum/reagent/drug/blastoff/on_mob_life(mob/living/carbon/dancer, seconds_per_tick, times_fired)
. = ..()
- dancer.adjustOrganLoss(ORGAN_SLOT_LUNGS, 0.3 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)
+ if(dancer.adjustOrganLoss(ORGAN_SLOT_LUNGS, 0.3 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags))
+ . = UPDATE_MOB_HEALTH
dancer.AdjustKnockdown(-20)
if(SPT_PROB(BLASTOFF_DANCE_MOVE_CHANCE_PER_UNIT * volume, seconds_per_tick))
dancer.emote("flip")
- return TRUE
/datum/reagent/drug/blastoff/overdose_process(mob/living/dancer, seconds_per_tick, times_fired)
. = ..()
- dancer.adjustOrganLoss(ORGAN_SLOT_LUNGS, 0.3 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)
+ if(dancer.adjustOrganLoss(ORGAN_SLOT_LUNGS, 0.3 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags))
+ . = UPDATE_MOB_HEALTH
if(SPT_PROB(BLASTOFF_DANCE_MOVE_CHANCE_PER_UNIT * volume, seconds_per_tick))
dancer.emote("spin")
@@ -673,8 +699,8 @@
/datum/reagent/drug/saturnx/on_mob_life(mob/living/carbon/invisible_man, seconds_per_tick, times_fired)
. = ..()
- invisible_man.adjustOrganLoss(ORGAN_SLOT_LIVER, 0.3 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)
- return TRUE
+ if(invisible_man.adjustOrganLoss(ORGAN_SLOT_LIVER, 0.3 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags))
+ return UPDATE_MOB_HEALTH
/datum/reagent/drug/saturnx/on_mob_metabolize(mob/living/invisible_man)
. = ..()
@@ -750,7 +776,8 @@
invisible_man.emote("giggle")
if(SPT_PROB(5, seconds_per_tick))
invisible_man.emote("laugh")
- invisible_man.adjustOrganLoss(ORGAN_SLOT_LIVER, 0.4 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)
+ if(invisible_man.adjustOrganLoss(ORGAN_SLOT_LIVER, 0.4 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags))
+ return UPDATE_MOB_HEALTH
/datum/reagent/drug/saturnx/stable
name = "Stabilized Saturn-X"
@@ -772,27 +799,29 @@
addiction_types = list(/datum/addiction/stimulants = 20)
/datum/reagent/drug/kronkaine/on_mob_metabolize(mob/living/kronkaine_fiend)
- ..()
+ . = ..()
kronkaine_fiend.add_actionspeed_modifier(/datum/actionspeed_modifier/kronkaine)
kronkaine_fiend.sound_environment_override = SOUND_ENVIRONMENT_HANGAR
/datum/reagent/drug/kronkaine/on_mob_end_metabolize(mob/living/kronkaine_fiend)
+ . = ..()
kronkaine_fiend.remove_actionspeed_modifier(/datum/actionspeed_modifier/kronkaine)
kronkaine_fiend.sound_environment_override = NONE
- . = ..()
/datum/reagent/drug/kronkaine/on_transfer(atom/kronkaine_receptacle, methods, trans_volume)
. = ..()
if(!iscarbon(kronkaine_receptacle))
return
var/mob/living/carbon/druggo = kronkaine_receptacle
- druggo.adjustStaminaLoss(-4 * trans_volume, 0)
+ if(druggo.adjustStaminaLoss(-4 * trans_volume, updating_stamina = FALSE))
+ return UPDATE_MOB_HEALTH
//I wish i could give it some kind of bonus when smoked, but we don't have an INHALE method.
/datum/reagent/drug/kronkaine/on_mob_life(mob/living/carbon/kronkaine_fiend, seconds_per_tick, times_fired)
. = ..() || TRUE
kronkaine_fiend.add_mood_event("tweaking", /datum/mood_event/stimulant_medium, name)
- kronkaine_fiend.adjustOrganLoss(ORGAN_SLOT_HEART, 0.4 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)
+ if(kronkaine_fiend.adjustOrganLoss(ORGAN_SLOT_HEART, 0.4 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags))
+ . = UPDATE_MOB_HEALTH
kronkaine_fiend.set_jitter_if_lower(20 SECONDS * REM * seconds_per_tick)
kronkaine_fiend.AdjustSleeping(-20 * REM * seconds_per_tick)
kronkaine_fiend.adjust_drowsiness(-10 SECONDS * REM * seconds_per_tick)
@@ -805,7 +834,8 @@
/datum/reagent/drug/kronkaine/overdose_process(mob/living/kronkaine_fiend, seconds_per_tick, times_fired)
. = ..()
- kronkaine_fiend.adjustOrganLoss(ORGAN_SLOT_HEART, 1 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)
+ if(kronkaine_fiend.adjustOrganLoss(ORGAN_SLOT_HEART, 1 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags))
+ . = UPDATE_MOB_HEALTH
kronkaine_fiend.set_jitter_if_lower(20 SECONDS * REM * seconds_per_tick)
if(SPT_PROB(10, seconds_per_tick))
to_chat(kronkaine_fiend, span_danger(pick("You feel like your heart is going to explode!", "Your ears are ringing!", "You sweat like a pig!", "You clench your jaw and grind your teeth.", "You feel prickles of pain in your chest.")))
@@ -819,6 +849,7 @@
chemical_flags = NONE
/datum/reagent/drug/kronkaine/gore/overdose_start(mob/living/gored)
+ . = ..()
gored.visible_message(
span_danger("[gored] explodes in a shower of gore!"),
span_userdanger("GORE! GORE! GORE! YOU'RE GORE! TOO MUCH GORE! YOU'RE GORE! GORE! IT'S OVER! GORE! GORE! YOU'RE GORE! TOO MUCH G-"),
diff --git a/code/modules/reagents/chemistry/reagents/food_reagents.dm b/code/modules/reagents/chemistry/reagents/food_reagents.dm
index 17867389c3d..e64716296b0 100644
--- a/code/modules/reagents/chemistry/reagents/food_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/food_reagents.dm
@@ -19,15 +19,16 @@
/// affects mood, typically higher for mixed drinks with more complex recipes'
var/quality = 0
-/datum/reagent/consumable/on_mob_life(mob/living/carbon/M, seconds_per_tick, times_fired)
+/datum/reagent/consumable/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
current_cycle++
- if(ishuman(M))
- var/mob/living/carbon/human/H = M
- if(!HAS_TRAIT(H, TRAIT_NOHUNGER))
- H.adjust_nutrition(get_nutriment_factor() * REM * seconds_per_tick)
+ if(ishuman(affected_mob))
+ var/mob/living/carbon/human/affected_human = affected_mob
+ if(!HAS_TRAIT(affected_human, TRAIT_NOHUNGER))
+ affected_human.adjust_nutrition(get_nutriment_factor() * REM * seconds_per_tick)
if(length(reagent_removal_skip_list))
return
- holder.remove_reagent(type, metabolization_rate * seconds_per_tick)
+ if(holder)
+ holder.remove_reagent(type, metabolization_rate * seconds_per_tick)
/datum/reagent/consumable/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume)
. = ..()
@@ -73,11 +74,11 @@
/datum/reagent/consumable/nutriment/on_hydroponics_apply(obj/machinery/hydroponics/mytray, mob/user)
mytray.adjust_plant_health(round(volume * 0.2))
-/datum/reagent/consumable/nutriment/on_mob_life(mob/living/carbon/M, seconds_per_tick, times_fired)
+/datum/reagent/consumable/nutriment/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
if(SPT_PROB(30, seconds_per_tick))
- M.heal_bodypart_damage(brute = brute_heal, burn = burn_heal, updating_health = FALSE, required_bodytype = BODYTYPE_ORGANIC)
- . = TRUE
- ..()
+ if(affected_mob.heal_bodypart_damage(brute = brute_heal * REM * seconds_per_tick, burn = burn_heal * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = BODYTYPE_ORGANIC))
+ return UPDATE_MOB_HEALTH
/datum/reagent/consumable/nutriment/on_new(list/supplied_data)
. = ..()
@@ -128,10 +129,10 @@
brute_heal = 1
burn_heal = 1
-/datum/reagent/consumable/nutriment/vitamin/on_mob_life(mob/living/carbon/M, seconds_per_tick, times_fired)
- if(M.satiety < MAX_SATIETY)
- M.satiety += 30 * REM * seconds_per_tick
+/datum/reagent/consumable/nutriment/vitamin/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
. = ..()
+ if(affected_mob.satiety < MAX_SATIETY)
+ affected_mob.satiety += 30 * REM * seconds_per_tick
/// The basic resource of vat growing.
/datum/reagent/consumable/nutriment/protein
@@ -238,15 +239,19 @@
///Amount of satiety that will be drained when the cloth_fibers is fully metabolized
var/delayed_satiety_drain = 2 * CLOTHING_NUTRITION_GAIN
-/datum/reagent/consumable/nutriment/cloth_fibers/on_mob_life(mob/living/carbon/M, seconds_per_tick, times_fired)
- if(M.satiety < MAX_SATIETY)
- M.adjust_nutrition(CLOTHING_NUTRITION_GAIN)
+/datum/reagent/consumable/nutriment/cloth_fibers/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
+ if(affected_mob.satiety < MAX_SATIETY)
+ affected_mob.adjust_nutrition(CLOTHING_NUTRITION_GAIN)
delayed_satiety_drain += CLOTHING_NUTRITION_GAIN
- return ..()
-/datum/reagent/consumable/nutriment/cloth_fibers/on_mob_delete(mob/living/carbon/M)
- M.adjust_nutrition(-delayed_satiety_drain)
- return ..()
+/datum/reagent/consumable/nutriment/cloth_fibers/on_mob_delete(mob/living/carbon/affected_mob)
+ . = ..()
+ if(!iscarbon(affected_mob))
+ return
+
+ var/mob/living/carbon/carbon_mob = affected_mob
+ carbon_mob.adjust_nutrition(-delayed_satiety_drain)
/datum/reagent/consumable/nutriment/mineral
name = "Mineral Slurry"
@@ -256,14 +261,15 @@
brute_heal = 0
burn_heal = 0
-/datum/reagent/consumable/nutriment/mineral/on_mob_life(mob/living/carbon/eater, delta_time, times_fired)
- current_cycle++
- if (HAS_TRAIT(eater, TRAIT_ROCK_EATER) && !HAS_TRAIT(eater, TRAIT_NOHUNGER) && ishuman(eater))
- var/mob/living/carbon/human/golem_eater = eater
- golem_eater.adjust_nutrition(get_nutriment_factor() * REM * delta_time)
- if(length(reagent_removal_skip_list))
- return
- holder.remove_reagent(type, metabolization_rate * delta_time)
+/datum/reagent/consumable/nutriment/mineral/on_mob_life(mob/living/carbon/eater, seconds_per_tick, times_fired)
+ if(HAS_TRAIT(eater, TRAIT_ROCK_EATER)) // allow mobs who can eat rocks to do so
+ return ..()
+ else // otherwise just let them pass through the system
+ current_cycle++
+ if(length(reagent_removal_skip_list))
+ return
+ if(holder)
+ holder.remove_reagent(type, metabolization_rate * seconds_per_tick)
/datum/reagent/consumable/sugar
name = "Sugar"
@@ -284,15 +290,14 @@
mytray.adjust_weedlevel(rand(1, 2))
mytray.adjust_pestlevel(rand(1, 2))
-/datum/reagent/consumable/sugar/overdose_start(mob/living/M)
- to_chat(M, span_userdanger("You go into hyperglycaemic shock! Lay off the twinkies!"))
- M.AdjustSleeping(20 SECONDS)
- . = TRUE
+/datum/reagent/consumable/sugar/overdose_start(mob/living/affected_mob)
+ . = ..()
+ to_chat(affected_mob, span_userdanger("You go into hyperglycemic shock! Lay off the twinkies!"))
+ affected_mob.AdjustSleeping(20 SECONDS)
-/datum/reagent/consumable/sugar/overdose_process(mob/living/M, seconds_per_tick, times_fired)
- M.adjust_drowsiness_up_to((5 SECONDS * REM * seconds_per_tick), 60 SECONDS)
- ..()
- . = TRUE
+/datum/reagent/consumable/sugar/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
+ affected_mob.adjust_drowsiness_up_to((5 SECONDS * REM * seconds_per_tick), 60 SECONDS)
/datum/reagent/consumable/virus_food
name = "Virus Food"
@@ -332,29 +337,29 @@
taste_mult = 1.5
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
-/datum/reagent/consumable/capsaicin/on_mob_life(mob/living/carbon/M, seconds_per_tick, times_fired)
+/datum/reagent/consumable/capsaicin/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
var/heating = 0
switch(current_cycle)
if(1 to 15)
heating = 5
if(holder.has_reagent(/datum/reagent/cryostylane))
holder.remove_reagent(/datum/reagent/cryostylane, 5 * REM * seconds_per_tick)
- if(isslime(M))
+ if(isslime(affected_mob))
heating = rand(5, 20)
if(15 to 25)
heating = 10
- if(isslime(M))
+ if(isslime(affected_mob))
heating = rand(10, 20)
if(25 to 35)
heating = 15
- if(isslime(M))
+ if(isslime(affected_mob))
heating = rand(15, 20)
if(35 to INFINITY)
heating = 20
- if(isslime(M))
+ if(isslime(affected_mob))
heating = rand(20, 25)
- M.adjust_bodytemperature(heating * TEMPERATURE_DAMAGE_COEFFICIENT * REM * seconds_per_tick)
- ..()
+ affected_mob.adjust_bodytemperature(heating * TEMPERATURE_DAMAGE_COEFFICIENT * REM * seconds_per_tick)
+ return ..()
/datum/reagent/consumable/frostoil
name = "Frost Oil"
@@ -367,33 +372,33 @@
specific_heat = 40
default_container = /obj/item/reagent_containers/cup/bottle/frostoil
-/datum/reagent/consumable/frostoil/on_mob_life(mob/living/carbon/M, seconds_per_tick, times_fired)
+/datum/reagent/consumable/frostoil/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
var/cooling = 0
switch(current_cycle)
if(1 to 15)
cooling = -10
if(holder.has_reagent(/datum/reagent/consumable/capsaicin))
holder.remove_reagent(/datum/reagent/consumable/capsaicin, 5 * REM * seconds_per_tick)
- if(isslime(M))
+ if(isslime(affected_mob))
cooling = -rand(5, 20)
if(15 to 25)
cooling = -20
- if(isslime(M))
+ if(isslime(affected_mob))
cooling = -rand(10, 20)
if(25 to 35)
cooling = -30
if(prob(1))
- M.emote("shiver")
- if(isslime(M))
+ affected_mob.emote("shiver")
+ if(isslime(affected_mob))
cooling = -rand(15, 20)
if(35 to INFINITY)
cooling = -40
if(prob(5))
- M.emote("shiver")
- if(isslime(M))
+ affected_mob.emote("shiver")
+ if(isslime(affected_mob))
cooling = -rand(20, 25)
- M.adjust_bodytemperature(cooling * TEMPERATURE_DAMAGE_COEFFICIENT * REM * seconds_per_tick, 50)
- ..()
+ affected_mob.adjust_bodytemperature(cooling * TEMPERATURE_DAMAGE_COEFFICIENT * REM * seconds_per_tick, 50)
+ return ..()
/datum/reagent/consumable/frostoil/expose_turf(turf/exposed_turf, reac_volume)
. = ..()
@@ -421,7 +426,6 @@
default_container = /obj/item/reagent_containers/cup/bottle/capsaicin
/datum/reagent/consumable/condensedcapsaicin/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume)
- . = ..()
if(!ishuman(exposed_mob))
return
@@ -450,12 +454,13 @@
victim.set_dizzy_if_lower(2 SECONDS)
if(prob(5))
victim.vomit(VOMIT_CATEGORY_DEFAULT)
+ return ..()
-/datum/reagent/consumable/condensedcapsaicin/on_mob_life(mob/living/carbon/M, seconds_per_tick, times_fired)
+/datum/reagent/consumable/condensedcapsaicin/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
if(!holder.has_reagent(/datum/reagent/consumable/milk))
if(SPT_PROB(5, seconds_per_tick))
- M.visible_message(span_warning("[M] [pick("dry heaves!","coughs!","splutters!")]"))
- ..()
+ affected_mob.visible_message(span_warning("[affected_mob] [pick("dry heaves!","coughs!","splutters!")]"))
+ return ..()
/datum/reagent/consumable/salt
name = "Table Salt"
@@ -506,7 +511,6 @@
flesh_healing -= max(VALUE_PER(5, 30) * reac_volume, 0)
to_chat(victim, span_notice("The salt bits seep in and stick to [lowertext(src)], painfully irritating the skin! After a few moments, it feels marginally better."))
-
/datum/reagent/consumable/blackpepper
name = "Black Pepper"
description = "A powder ground from peppercorns. *AAAACHOOO*"
@@ -533,27 +537,27 @@
metabolization_rate = 0.15 * REAGENTS_METABOLISM
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
-/datum/reagent/consumable/garlic/on_mob_add(mob/living/L, amount)
+/datum/reagent/consumable/garlic/on_mob_add(mob/living/affected_mob, amount)
+ . = ..()
+ ADD_TRAIT(affected_mob, TRAIT_GARLIC_BREATH, type)
+
+/datum/reagent/consumable/garlic/on_mob_delete(mob/living/affected_mob)
. = ..()
- ADD_TRAIT(L, TRAIT_GARLIC_BREATH, type)
+ REMOVE_TRAIT(affected_mob, TRAIT_GARLIC_BREATH, type)
-/datum/reagent/consumable/garlic/on_mob_delete(mob/living/L)
+/datum/reagent/consumable/garlic/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
. = ..()
- REMOVE_TRAIT(L, TRAIT_GARLIC_BREATH, type)
-
-/datum/reagent/consumable/garlic/on_mob_life(mob/living/carbon/M, seconds_per_tick, times_fired)
- if(isvampire(M)) //incapacitating but not lethal. Unfortunately, vampires cannot vomit.
- if(SPT_PROB(min(current_cycle/2, 12.5), seconds_per_tick))
- to_chat(M, span_danger("You can't get the scent of garlic out of your nose! You can barely think..."))
- M.Paralyze(10)
- M.set_jitter_if_lower(20 SECONDS)
+ if(isvampire(affected_mob)) //incapacitating but not lethal. Unfortunately, vampires cannot vomit.
+ if(SPT_PROB(min((current_cycle-1)/2, 12.5), seconds_per_tick))
+ to_chat(affected_mob, span_danger("You can't get the scent of garlic out of your nose! You can barely think..."))
+ affected_mob.Paralyze(10)
+ affected_mob.set_jitter_if_lower(20 SECONDS)
else
- var/obj/item/organ/internal/liver/liver = M.get_organ_slot(ORGAN_SLOT_LIVER)
+ var/obj/item/organ/internal/liver/liver = affected_mob.get_organ_slot(ORGAN_SLOT_LIVER)
if(liver && HAS_TRAIT(liver, TRAIT_CULINARY_METABOLISM))
if(SPT_PROB(10, seconds_per_tick)) //stays in the system much longer than sprinkles/banana juice, so heals slower to partially compensate
- M.heal_bodypart_damage(brute = 1, burn = 1)
- . = TRUE
- ..()
+ if(affected_mob.heal_bodypart_damage(brute = 1 * REM * seconds_per_tick, burn = 1 * REM * seconds_per_tick, updating_health = FALSE))
+ return UPDATE_MOB_HEALTH
/datum/reagent/consumable/tearjuice
name = "Tear Juice"
@@ -582,12 +586,12 @@
taste_description = "childhood whimsy"
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
-/datum/reagent/consumable/sprinkles/on_mob_life(mob/living/carbon/M, seconds_per_tick, times_fired)
- var/obj/item/organ/internal/liver/liver = M.get_organ_slot(ORGAN_SLOT_LIVER)
+/datum/reagent/consumable/sprinkles/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
+ var/obj/item/organ/internal/liver/liver = affected_mob.get_organ_slot(ORGAN_SLOT_LIVER)
if(liver && HAS_TRAIT(liver, TRAIT_LAW_ENFORCEMENT_METABOLISM))
- M.heal_bodypart_damage(1 * REM * seconds_per_tick, 1 * REM * seconds_per_tick, 0)
- . = TRUE
- ..()
+ if(affected_mob.heal_bodypart_damage(brute = 1 * REM * seconds_per_tick, burn = 1 * REM * seconds_per_tick, updating_health = FALSE))
+ return UPDATE_MOB_HEALTH
/datum/reagent/consumable/enzyme
name = "Universal Enzyme"
@@ -623,9 +627,9 @@
taste_description = "your imprisonment"
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
-/datum/reagent/consumable/hot_ramen/on_mob_life(mob/living/carbon/M, seconds_per_tick, times_fired)
- M.adjust_bodytemperature(10 * TEMPERATURE_DAMAGE_COEFFICIENT * REM * seconds_per_tick, 0, M.get_body_temp_normal())
- ..()
+/datum/reagent/consumable/hot_ramen/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
+ affected_mob.adjust_bodytemperature(10 * TEMPERATURE_DAMAGE_COEFFICIENT * REM * seconds_per_tick, 0, affected_mob.get_body_temp_normal())
/datum/reagent/consumable/hell_ramen
name = "Hell Ramen"
@@ -635,9 +639,9 @@
taste_description = "wet and cheap noodles on fire"
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
-/datum/reagent/consumable/hell_ramen/on_mob_life(mob/living/carbon/target_mob, seconds_per_tick, times_fired)
- target_mob.adjust_bodytemperature(10 * TEMPERATURE_DAMAGE_COEFFICIENT * REM * seconds_per_tick)
- ..()
+/datum/reagent/consumable/hell_ramen/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
+ affected_mob.adjust_bodytemperature(10 * TEMPERATURE_DAMAGE_COEFFICIENT * REM * seconds_per_tick)
/datum/reagent/consumable/flour
name = "Flour"
@@ -718,7 +722,7 @@
color = "#FFFFFF" // rgb: 0, 0, 0
taste_description = "chalky wheat with rice"
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
-
+
/datum/reagent/consumable/vanilla
name = "Vanilla Powder"
description = "A fatty, bitter paste made from vanilla pods."
@@ -789,9 +793,9 @@
taste_description = "sweet slime"
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
-/datum/reagent/consumable/corn_syrup/on_mob_life(mob/living/carbon/M, seconds_per_tick, times_fired)
+/datum/reagent/consumable/corn_syrup/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
holder.add_reagent(/datum/reagent/consumable/sugar, 3 * REM * seconds_per_tick)
- ..()
+ return ..()
/datum/reagent/consumable/honey
name = "Honey"
@@ -812,15 +816,17 @@
mytray.adjust_weedlevel(rand(1, 2))
mytray.adjust_pestlevel(rand(1, 2))
-/datum/reagent/consumable/honey/on_mob_life(mob/living/carbon/M, seconds_per_tick, times_fired)
+/datum/reagent/consumable/honey/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
holder.add_reagent(/datum/reagent/consumable/sugar, 3 * REM * seconds_per_tick)
+ . = ..()
+ var/need_mob_update
if(SPT_PROB(33, seconds_per_tick))
- M.adjustBruteLoss(-1, FALSE, required_bodytype = affected_bodytype)
- M.adjustFireLoss(-1, FALSE, required_bodytype = affected_bodytype)
- M.adjustOxyLoss(-1, FALSE, required_biotype = affected_biotype)
- M.adjustToxLoss(-1, FALSE, required_biotype = affected_biotype)
- . = TRUE
- ..()
+ need_mob_update = affected_mob.adjustBruteLoss(-1, updating_health = FALSE, required_bodytype = affected_bodytype)
+ need_mob_update += affected_mob.adjustFireLoss(-1, updating_health = FALSE, required_bodytype = affected_bodytype)
+ need_mob_update += affected_mob.adjustOxyLoss(-1, updating_health = FALSE, required_biotype = affected_biotype)
+ need_mob_update += affected_mob.adjustToxLoss(-1, updating_health = FALSE, required_biotype = affected_biotype)
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/consumable/honey/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume)
. = ..()
@@ -861,10 +867,10 @@
color = "#664330" // rgb: 102, 67, 48
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
-/datum/reagent/consumable/nutriment/stabilized/on_mob_life(mob/living/carbon/M, seconds_per_tick, times_fired)
- if(M.nutrition > NUTRITION_LEVEL_FULL - 25)
- M.adjust_nutrition(-3 * REM * get_nutriment_factor() * seconds_per_tick)
- ..()
+/datum/reagent/consumable/nutriment/stabilized/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
+ if(affected_mob.nutrition > NUTRITION_LEVEL_FULL - 25)
+ affected_mob.adjust_nutrition(-3 * REM * get_nutriment_factor() * seconds_per_tick)
////Lavaland Flora Reagents////
@@ -877,19 +883,20 @@
ph = 12
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
-/datum/reagent/consumable/entpoly/on_mob_life(mob/living/carbon/M, seconds_per_tick, times_fired)
- if(current_cycle >= 10)
- M.Unconscious(40 * REM * seconds_per_tick, FALSE)
- . = TRUE
+/datum/reagent/consumable/entpoly/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
+ var/need_mob_update
+ if(current_cycle > 10)
+ affected_mob.Unconscious(40 * REM * seconds_per_tick, FALSE)
if(SPT_PROB(10, seconds_per_tick))
- M.losebreath += 4
- M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2*REM, 150, affected_biotype)
- M.adjustToxLoss(3*REM, FALSE, required_biotype = affected_biotype)
- M.adjustStaminaLoss(10*REM, FALSE, required_biotype = affected_biotype)
- M.set_eye_blur_if_lower(10 SECONDS)
- . = TRUE
- ..()
-
+ affected_mob.losebreath += 4
+ affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2*REM, 150, affected_biotype)
+ affected_mob.adjustToxLoss(3*REM, updating_health = FALSE, required_biotype = affected_biotype)
+ affected_mob.adjustStaminaLoss(10*REM, updating_stamina = FALSE, required_biotype = affected_biotype)
+ affected_mob.set_eye_blur_if_lower(10 SECONDS)
+ need_mob_update = TRUE
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/consumable/tinlux
name = "Tinea Luxor"
@@ -925,12 +932,14 @@
ph = 10.4
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
-/datum/reagent/consumable/vitfro/on_mob_life(mob/living/carbon/M, seconds_per_tick, times_fired)
+/datum/reagent/consumable/vitfro/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
+ var/need_mob_update
if(SPT_PROB(55, seconds_per_tick))
- M.adjustBruteLoss(-1, FALSE, required_bodytype = affected_bodytype)
- M.adjustFireLoss(-1, FALSE, required_bodytype = affected_bodytype)
- . = TRUE
- ..()
+ need_mob_update = affected_mob.adjustBruteLoss(-1 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
+ need_mob_update += affected_mob.adjustFireLoss(-1 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/consumable/liquidelectricity
name = "Liquid Electricity"
@@ -953,13 +962,13 @@
if(istype(stomach))
stomach.adjust_charge(reac_volume * 30)
-/datum/reagent/consumable/liquidelectricity/enriched/on_mob_life(mob/living/carbon/M, seconds_per_tick, times_fired)
- if(isethereal(M))
- M.blood_volume += 1 * seconds_per_tick
+/datum/reagent/consumable/liquidelectricity/enriched/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
+ if(isethereal(affected_mob))
+ affected_mob.blood_volume += 1 * seconds_per_tick
else if(SPT_PROB(10, seconds_per_tick)) //lmao at the newbs who eat energy bars
- M.electrocute_act(rand(5,10), "Liquid Electricity in their body", 1, SHOCK_NOGLOVES) //the shock is coming from inside the house
- playsound(M, SFX_SPARKS, 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
- return ..()
+ affected_mob.electrocute_act(rand(5,10), "Liquid Electricity in their body", 1, SHOCK_NOGLOVES) //the shock is coming from inside the house
+ playsound(affected_mob, SFX_SPARKS, 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
/datum/reagent/consumable/astrotame
name = "Astrotame"
@@ -973,11 +982,10 @@
overdose_threshold = 17
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
-/datum/reagent/consumable/astrotame/overdose_process(mob/living/carbon/M, seconds_per_tick, times_fired)
- if(M.disgust < 80)
- M.adjust_disgust(10 * REM * seconds_per_tick)
- ..()
- . = TRUE
+/datum/reagent/consumable/astrotame/overdose_process(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
+ if(affected_mob.disgust < 80)
+ affected_mob.adjust_disgust(10 * REM * seconds_per_tick)
/datum/reagent/consumable/secretsauce
name = "Secret Sauce"
@@ -1022,11 +1030,10 @@
overdose_threshold = 15
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
-/datum/reagent/consumable/char/overdose_process(mob/living/M, seconds_per_tick, times_fired)
+/datum/reagent/consumable/char/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
if(SPT_PROB(13, seconds_per_tick))
- M.say(pick_list_replacements(BOOMER_FILE, "boomer"), forced = /datum/reagent/consumable/char)
- ..()
- return
+ affected_mob.say(pick_list_replacements(BOOMER_FILE, "boomer"), forced = /datum/reagent/consumable/char)
/datum/reagent/consumable/bbqsauce
name = "BBQ Sauce"
@@ -1136,11 +1143,11 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
default_container = /obj/item/reagent_containers/condiment/peanut_butter
-/datum/reagent/consumable/peanut_butter/on_mob_life(mob/living/carbon/M, seconds_per_tick, times_fired) //ET loves peanut butter
- if(isabductor(M))
- M.add_mood_event("ET_pieces", /datum/mood_event/et_pieces, name)
- M.set_drugginess(30 SECONDS * REM * seconds_per_tick)
- ..()
+/datum/reagent/consumable/peanut_butter/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) //ET loves peanut butter
+ . = ..()
+ if(isabductor(affected_mob))
+ affected_mob.add_mood_event("ET_pieces", /datum/mood_event/et_pieces, name)
+ affected_mob.set_drugginess(30 SECONDS * REM * seconds_per_tick)
/datum/reagent/consumable/vinegar
name = "Vinegar"
@@ -1198,10 +1205,10 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/consumable/mintextract/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
if(HAS_TRAIT(affected_mob, TRAIT_FAT))
affected_mob.investigate_log("has been gibbed by consuming [src] while fat.", INVESTIGATE_DEATHS)
affected_mob.inflate_gib()
- return ..()
/datum/reagent/consumable/worcestershire
name = "Worcestershire Sauce"
diff --git a/code/modules/reagents/chemistry/reagents/impure_reagents.dm b/code/modules/reagents/chemistry/reagents/impure_reagents.dm
index f7eaba3c211..1a06ae11cd9 100644
--- a/code/modules/reagents/chemistry/reagents/impure_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/impure_reagents.dm
@@ -17,10 +17,15 @@
/datum/reagent/impurity/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
. = ..()
var/obj/item/organ/internal/liver/liver = affected_mob.get_organ_slot(ORGAN_SLOT_LIVER)
- if(isnull(liver)) //Though, lets be safe
- return affected_mob.adjustToxLoss(1 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) //Incase of no liver!
- affected_mob.adjustOrganLoss(ORGAN_SLOT_LIVER, liver_damage * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)
- return TRUE
+ var/need_mob_update
+
+ if(liver)//Though, lets be safe
+ need_mob_update = affected_mob.adjustOrganLoss(ORGAN_SLOT_LIVER, liver_damage * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)
+ else
+ need_mob_update = affected_mob.adjustToxLoss(1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)//Incase of no liver!
+
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
//Basically just so people don't forget to adjust metabolization_rate
/datum/reagent/inverse
@@ -36,7 +41,8 @@
/datum/reagent/inverse/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
. = ..()
- return affected_mob.adjustToxLoss(tox_damage * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
+ if(affected_mob.adjustToxLoss(tox_damage * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype))
+ return UPDATE_MOB_HEALTH
//Failed chems - generally use inverse if you want to use a impure subtype for it
//technically not a impure chem, but it's here because it can only be made with a failed impure reaction
@@ -96,6 +102,7 @@
var/atom/movable/screen/alert/status_effect/freon/cryostylane_alert
/datum/reagent/inverse/cryostylane/on_mob_add(mob/living/carbon/affected_mob, amount)
+ . = ..()
cube = new /obj/structure/ice_stasis(get_turf(affected_mob))
cube.color = COLOR_CYAN
cube.set_anchored(TRUE)
@@ -103,17 +110,21 @@
affected_mob.apply_status_effect(/datum/status_effect/grouped/stasis, STASIS_CHEMICAL_EFFECT)
cryostylane_alert = affected_mob.throw_alert("cryostylane_alert", /atom/movable/screen/alert/status_effect/freon/cryostylane)
cryostylane_alert.attached_effect = src //so the alert can reference us, if it needs to
- ..()
/datum/reagent/inverse/cryostylane/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ if(current_cycle >= 60)
+ holder.remove_reagent(type, volume) // remove it all if we're past 60 cycles
+ return ..()
if(!cube || affected_mob.loc != cube)
- affected_mob.reagents.remove_reagent(type, volume) //remove it all if we're past 60s
- if(current_cycle > 60)
metabolization_rate += 0.01
- ..()
+ return ..()
/datum/reagent/inverse/cryostylane/on_mob_delete(mob/living/carbon/affected_mob, amount)
+ . = ..()
QDEL_NULL(cube)
- affected_mob.remove_status_effect(/datum/status_effect/grouped/stasis, STASIS_CHEMICAL_EFFECT)
- affected_mob.clear_alert("cryostylane_alert")
- ..()
+ if(!iscarbon(affected_mob))
+ return
+
+ var/mob/living/carbon/carbon_mob = affected_mob
+ carbon_mob.remove_status_effect(/datum/status_effect/grouped/stasis, STASIS_CHEMICAL_EFFECT)
+ carbon_mob.clear_alert("cryostylane_alert")
diff --git a/code/modules/reagents/chemistry/reagents/impure_reagents/impure_medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/impure_reagents/impure_medicine_reagents.dm
index db98ed9d622..23e8537358c 100644
--- a/code/modules/reagents/chemistry/reagents/impure_reagents/impure_medicine_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/impure_reagents/impure_medicine_reagents.dm
@@ -35,19 +35,21 @@
affected_respiration_type = ALL
//Random healing of the 4 main groups
-/datum/reagent/impurity/healing/medicine_failure/on_mob_life(mob/living/carbon/owner, seconds_per_tick, times_fired)
+/datum/reagent/impurity/healing/medicine_failure/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
+ var/need_mob_update
var/pick = pick("brute", "burn", "tox", "oxy")
switch(pick)
if("brute")
- owner.adjustBruteLoss(-0.5, required_bodytype = affected_bodytype)
+ need_mob_update = affected_mob.adjustBruteLoss(-0.5, updating_health = FALSE, required_bodytype = affected_bodytype)
if("burn")
- owner.adjustFireLoss(-0.5, required_bodytype = affected_bodytype)
+ need_mob_update += affected_mob.adjustFireLoss(-0.5, updating_health = FALSE, required_bodytype = affected_bodytype)
if("tox")
- owner.adjustToxLoss(-0.5, required_biotype = affected_biotype)
+ need_mob_update += affected_mob.adjustToxLoss(-0.5, updating_health = FALSE, required_biotype = affected_biotype)
if("oxy")
- owner.adjustOxyLoss(-0.5, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
- ..()
- return TRUE
+ need_mob_update += affected_mob.adjustOxyLoss(-0.5, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
// C2 medications
// Helbital
@@ -64,10 +66,10 @@
var/list/timer_ids
//Warns you about the impenting hands
-/datum/reagent/inverse/helgrasp/on_mob_add(mob/living/L, amount)
- to_chat(L, span_hierophant("You hear laughter as malevolent hands apparate before you, eager to drag you down to hell...! Look out!"))
- playsound(L.loc, 'sound/chemistry/ahaha.ogg', 80, TRUE, -1) //Very obvious tell so people can be ready
+/datum/reagent/inverse/helgrasp/on_mob_add(mob/living/affected_mob, amount)
. = ..()
+ to_chat(affected_mob, span_hierophant("You hear laughter as malevolent hands apparate before you, eager to drag you down to hell...! Look out!"))
+ playsound(affected_mob.loc, 'sound/chemistry/ahaha.ogg', 80, TRUE, -1) //Very obvious tell so people can be ready
//Sends hands after you for your hubris
/*
@@ -81,8 +83,9 @@ Then I attempt to calculate the how many hands to created based off the current
I take the 2s interval period and divide it by the number of hands I want to make (i.e. the current seconds_per_tick) and I keep track of how many hands I'm creating (since I always create one on a tick, then I start at 1 hand). For each hand I then use this time value multiplied by the number of hands. Since we're spawning one now, and it checks to see if hands is less than, but not less than or equal to, seconds_per_tick, no hands will be created on the next expected tick.
Basically, we fill the time between now and 2s from now with hands based off the current lag.
*/
-/datum/reagent/inverse/helgrasp/on_mob_life(mob/living/carbon/owner, seconds_per_tick, times_fired)
- spawn_hands(owner)
+/datum/reagent/inverse/helgrasp/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
+ spawn_hands(affected_mob)
lag_remainder += seconds_per_tick - FLOOR(seconds_per_tick, 1)
seconds_per_tick = FLOOR(seconds_per_tick, 1)
if(lag_remainder >= 1)
@@ -91,36 +94,35 @@ Basically, we fill the time between now and 2s from now with hands based off the
var/hands = 1
var/time = 2 / seconds_per_tick
while(hands < seconds_per_tick) //we already made a hand now so start from 1
- LAZYADD(timer_ids, addtimer(CALLBACK(src, PROC_REF(spawn_hands), owner), (time*hands) SECONDS, TIMER_STOPPABLE)) //keep track of all the timers we set up
+ LAZYADD(timer_ids, addtimer(CALLBACK(src, PROC_REF(spawn_hands), affected_mob), (time*hands) SECONDS, TIMER_STOPPABLE)) //keep track of all the timers we set up
hands += time
- return ..()
-/datum/reagent/inverse/helgrasp/proc/spawn_hands(mob/living/carbon/owner)
- if(!owner && iscarbon(holder.my_atom))//Catch timer
- owner = holder.my_atom
+/datum/reagent/inverse/helgrasp/proc/spawn_hands(mob/living/carbon/affected_mob)
+ if(!affected_mob && iscarbon(holder.my_atom))//Catch timer
+ affected_mob = holder.my_atom
//Adapted from the end of the curse - but lasts a short time
- var/grab_dir = turn(owner.dir, pick(-90, 90, 180, 180)) //grab them from a random direction other than the one faced, favoring grabbing from behind
- var/turf/spawn_turf = get_ranged_target_turf(owner, grab_dir, 8)//Larger range so you have more time to dodge
+ var/grab_dir = turn(affected_mob.dir, pick(-90, 90, 180, 180)) //grab them from a random direction other than the one faced, favoring grabbing from behind
+ var/turf/spawn_turf = get_ranged_target_turf(affected_mob, grab_dir, 8)//Larger range so you have more time to dodge
if(!spawn_turf)
return
- new/obj/effect/temp_visual/dir_setting/curse/grasp_portal(spawn_turf, owner.dir)
+ new/obj/effect/temp_visual/dir_setting/curse/grasp_portal(spawn_turf, affected_mob.dir)
playsound(spawn_turf, 'sound/effects/curse2.ogg', 80, TRUE, -1)
var/obj/projectile/curse_hand/hel/hand = new (spawn_turf)
- hand.preparePixelProjectile(owner, spawn_turf)
+ hand.preparePixelProjectile(affected_mob, spawn_turf)
if(QDELETED(hand)) //safety check if above fails - above has a stack trace if it does fail
return
hand.fire()
//At the end, we clear up any loose hanging timers just in case and spawn any remaining lag_remaining hands all at once.
-/datum/reagent/inverse/helgrasp/on_mob_delete(mob/living/owner)
+/datum/reagent/inverse/helgrasp/on_mob_delete(mob/living/affected_mob)
+ . = ..()
var/hands = 0
while(lag_remainder > hands)
- spawn_hands(owner)
+ spawn_hands(affected_mob)
hands++
for(var/id in timer_ids) // So that we can be certain that all timers are deleted at the end.
deltimer(id)
timer_ids.Cut()
- return ..()
/datum/reagent/inverse/helgrasp/heretic
name = "Grasp of the Mansus"
@@ -139,9 +141,9 @@ Basically, we fill the time between now and 2s from now with hands based off the
liver_damage = 0.1
addiction_types = list(/datum/addiction/medicine = 4)
-/datum/reagent/impurity/libitoil/on_mob_add(mob/living/L, amount)
+/datum/reagent/impurity/libitoil/on_mob_add(mob/living/affected_mob, amount)
. = ..()
- var/mob/living/carbon/consumer = L
+ var/mob/living/carbon/consumer = affected_mob
if(!consumer)
return
RegisterSignal(consumer, COMSIG_CARBON_GAIN_ORGAN, PROC_REF(on_gained_organ))
@@ -163,9 +165,9 @@ Basically, we fill the time between now and 2s from now with hands based off the
var/obj/item/organ/internal/liver/this_liver = organ
this_liver.alcohol_tolerance /= 2
-/datum/reagent/impurity/libitoil/on_mob_delete(mob/living/L)
+/datum/reagent/impurity/libitoil/on_mob_delete(mob/living/affected_mob)
. = ..()
- var/mob/living/carbon/consumer = L
+ var/mob/living/carbon/consumer = affected_mob
UnregisterSignal(consumer, COMSIG_CARBON_LOSE_ORGAN)
UnregisterSignal(consumer, COMSIG_CARBON_GAIN_ORGAN)
var/obj/item/organ/internal/liver/this_liver = consumer.get_organ_slot(ORGAN_SLOT_LIVER)
@@ -187,8 +189,8 @@ Basically, we fill the time between now and 2s from now with hands based off the
liver_damage = 0
/datum/reagent/impurity/probital_failed/overdose_start(mob/living/carbon/M)
+ . = ..()
metabolization_rate = 4 * REAGENTS_METABOLISM
- ..()
/datum/reagent/peptides_failed
name = "Prion Peptides"
@@ -196,11 +198,11 @@ Basically, we fill the time between now and 2s from now with hands based off the
description = "These inhibitory peptides drains nutrition and causes brain damage in the patient!"
ph = 2.1
-/datum/reagent/peptides_failed/on_mob_life(mob/living/carbon/owner, seconds_per_tick, times_fired)
- owner.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.25 * seconds_per_tick, 170)
- owner.adjust_nutrition(-5 * REAGENTS_METABOLISM * seconds_per_tick)
- ..()
- return TRUE
+/datum/reagent/peptides_failed/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
+ if(affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.25 * seconds_per_tick, 170))
+ . = UPDATE_MOB_HEALTH
+ affected_mob.adjust_nutrition(-5 * REAGENTS_METABOLISM * seconds_per_tick)
//Lenturi
//impure
@@ -210,13 +212,13 @@ Basically, we fill the time between now and 2s from now with hands based off the
addiction_types = list(/datum/addiction/medicine = 8)
liver_damage = 0
-/datum/reagent/impurity/lentslurri/on_mob_metabolize(mob/living/carbon/owner)
- owner.add_movespeed_modifier(/datum/movespeed_modifier/reagent/lenturi)
- return ..()
+/datum/reagent/impurity/lentslurri/on_mob_metabolize(mob/living/carbon/affected_mob)
+ . = ..()
+ affected_mob.add_movespeed_modifier(/datum/movespeed_modifier/reagent/lenturi)
-/datum/reagent/impurity/lentslurri/on_mob_end_metabolize(mob/living/carbon/owner)
- owner.remove_movespeed_modifier(/datum/movespeed_modifier/reagent/lenturi)
- return ..()
+/datum/reagent/impurity/lentslurri/on_mob_end_metabolize(mob/living/carbon/affected_mob)
+ . = ..()
+ affected_mob.remove_movespeed_modifier(/datum/movespeed_modifier/reagent/lenturi)
//failed
/datum/reagent/inverse/ichiyuri
@@ -233,19 +235,19 @@ Basically, we fill the time between now and 2s from now with hands based off the
var/spammer = 0
//Just the removed itching mechanism - omage to it's origins.
-/datum/reagent/inverse/ichiyuri/on_mob_life(mob/living/carbon/owner, seconds_per_tick, times_fired)
- if(prob(resetting_probability) && !(HAS_TRAIT(owner, TRAIT_RESTRAINED) || owner.incapacitated()))
+/datum/reagent/inverse/ichiyuri/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
+ if(prob(resetting_probability) && !(HAS_TRAIT(affected_mob, TRAIT_RESTRAINED) || affected_mob.incapacitated()))
. = TRUE
if(spammer < world.time)
- to_chat(owner,span_warning("You can't help but itch yourself."))
+ to_chat(affected_mob,span_warning("You can't help but itch yourself."))
spammer = world.time + (10 SECONDS)
var/scab = rand(1,7)
- owner.adjustBruteLoss(scab*REM)
- owner.bleed(scab)
+ if(affected_mob.adjustBruteLoss(scab*REM, updating_health = FALSE))
+ . = UPDATE_MOB_HEALTH
+ affected_mob.bleed(scab)
resetting_probability = 0
- resetting_probability += (5*(current_cycle/10) * seconds_per_tick) // 10 iterations = >51% to itch
- ..()
- return .
+ resetting_probability += (5*((current_cycle-1)/10) * seconds_per_tick) // 10 iterations = >51% to itch
//Aiuri
//impure
@@ -258,14 +260,14 @@ Basically, we fill the time between now and 2s from now with hands based off the
/// blurriness at the start of taking the med
var/amount_of_blur_applied = 0 SECONDS
-/datum/reagent/impurity/aiuri/on_mob_add(mob/living/owner, amount)
+/datum/reagent/impurity/aiuri/on_mob_add(mob/living/affected_mob, amount)
. = ..()
amount_of_blur_applied = creation_purity * (volume / metabolization_rate) * 2 SECONDS
- owner.adjust_eye_blur(amount_of_blur_applied)
+ affected_mob.adjust_eye_blur(amount_of_blur_applied)
-/datum/reagent/impurity/aiuri/on_mob_delete(mob/living/owner, amount)
+/datum/reagent/impurity/aiuri/on_mob_delete(mob/living/affected_mob, amount)
. = ..()
- owner.adjust_eye_blur(-amount_of_blur_applied)
+ affected_mob.adjust_eye_blur(-amount_of_blur_applied)
//Hercuri
//inverse
@@ -280,14 +282,14 @@ Basically, we fill the time between now and 2s from now with hands based off the
taste_description = "heat! Ouch!"
addiction_types = list(/datum/addiction/medicine = 2.5)
-/datum/reagent/inverse/hercuri/on_mob_life(mob/living/carbon/owner, seconds_per_tick, times_fired)
+/datum/reagent/inverse/hercuri/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
. = ..()
var/heating = rand(5, 25) * creation_purity * REM * seconds_per_tick
- owner.reagents?.chem_temp += heating
- owner.adjust_bodytemperature(heating * TEMPERATURE_DAMAGE_COEFFICIENT)
- if(!ishuman(owner))
+ affected_mob.reagents?.chem_temp += heating
+ affected_mob.adjust_bodytemperature(heating * TEMPERATURE_DAMAGE_COEFFICIENT)
+ if(!ishuman(affected_mob))
return
- var/mob/living/carbon/human/human = owner
+ var/mob/living/carbon/human/human = affected_mob
human.adjust_coretemperature(heating * TEMPERATURE_DAMAGE_COEFFICIENT)
/datum/reagent/inverse/hercuri/expose_mob(mob/living/carbon/exposed_mob, methods=VAPOR, reac_volume)
@@ -298,13 +300,14 @@ Basically, we fill the time between now and 2s from now with hands based off the
exposed_mob.adjust_bodytemperature(reac_volume * TEMPERATURE_DAMAGE_COEFFICIENT)
exposed_mob.adjust_fire_stacks(reac_volume / 2)
-/datum/reagent/inverse/hercuri/overdose_process(mob/living/carbon/owner, seconds_per_tick, times_fired)
+/datum/reagent/inverse/hercuri/overdose_process(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
. = ..()
- owner.adjustOrganLoss(ORGAN_SLOT_LIVER, 2 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) //Makes it so you can't abuse it with pyroxadone very easily (liver dies from 25u unless it's fully upgraded)
+ if(affected_mob.adjustOrganLoss(ORGAN_SLOT_LIVER, 2 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)) //Makes it so you can't abuse it with pyroxadone very easily (liver dies from 25u unless it's fully upgraded)
+ . = UPDATE_MOB_HEALTH
var/heating = 10 * creation_purity * REM * seconds_per_tick * TEMPERATURE_DAMAGE_COEFFICIENT
- owner.adjust_bodytemperature(heating) //hot hot
- if(ishuman(owner))
- var/mob/living/carbon/human/human = owner
+ affected_mob.adjust_bodytemperature(heating) //hot hot
+ if(ishuman(affected_mob))
+ var/mob/living/carbon/human/human = affected_mob
human.adjust_coretemperature(heating)
/datum/reagent/inverse/healing/tirimol
@@ -317,16 +320,17 @@ Basically, we fill the time between now and 2s from now with hands based off the
addiction_types = list(/datum/addiction/medicine = 5)
//Makes patients fall asleep, then boosts the purirty of their medicine reagents if they're asleep
-/datum/reagent/inverse/healing/tirimol/on_mob_life(mob/living/carbon/owner, seconds_per_tick, times_fired)
+/datum/reagent/inverse/healing/tirimol/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
switch(current_cycle)
- if(1 to 10)//same delay as chloral hydrate
+ if(2 to 11)//same delay as chloral hydrate
if(prob(50))
- owner.emote("yawn")
- if(10 to INFINITY)
- owner.Sleeping(40)
+ affected_mob.emote("yawn")
+ if(11 to INFINITY)
+ affected_mob.Sleeping(40)
. = 1
- if(owner.IsSleeping())
- for(var/datum/reagent/reagent as anything in owner.reagents.reagent_list)
+ if(affected_mob.IsSleeping())
+ for(var/datum/reagent/reagent as anything in affected_mob.reagents.reagent_list)
if(reagent in cached_reagent_list)
continue
if(!istype(reagent, /datum/reagent/medicine))
@@ -334,23 +338,22 @@ Basically, we fill the time between now and 2s from now with hands based off the
reagent.creation_purity *= 1.25
cached_reagent_list += reagent
- else if(!owner.IsSleeping() && length(cached_reagent_list))
+ else if(!affected_mob.IsSleeping() && length(cached_reagent_list))
for(var/datum/reagent/reagent as anything in cached_reagent_list)
if(!reagent)
continue
reagent.creation_purity *= 0.8
cached_reagent_list = list()
- ..()
-/datum/reagent/inverse/healing/tirimol/on_mob_delete(mob/living/owner)
- if(owner.IsSleeping())
- owner.visible_message(span_notice("[icon2html(owner, viewers(DEFAULT_MESSAGE_RANGE, src))] [owner] lets out a hearty snore!"))//small way of letting people know the supersnooze is ended
+/datum/reagent/inverse/healing/tirimol/on_mob_delete(mob/living/affected_mob)
+ . = ..()
+ if(affected_mob.IsSleeping())
+ affected_mob.visible_message(span_notice("[icon2html(affected_mob, viewers(DEFAULT_MESSAGE_RANGE, src))] [affected_mob] lets out a hearty snore!"))//small way of letting people know the supersnooze is ended
for(var/datum/reagent/reagent as anything in cached_reagent_list)
if(!reagent)
continue
reagent.creation_purity *= 0.8
cached_reagent_list = list()
- ..()
//convermol
//inverse
@@ -369,11 +372,11 @@ Basically, we fill the time between now and 2s from now with hands based off the
var/cached_cold_level_2
var/cached_cold_level_3
-/datum/reagent/inverse/healing/convermol/on_mob_add(mob/living/owner, amount)
+/datum/reagent/inverse/healing/convermol/on_mob_add(mob/living/affected_mob, amount)
. = ..()
- RegisterSignal(owner, COMSIG_CARBON_GAIN_ORGAN, PROC_REF(on_gained_organ))
- RegisterSignal(owner, COMSIG_CARBON_LOSE_ORGAN, PROC_REF(on_removed_organ))
- var/obj/item/organ/internal/lungs/lungs = owner.get_organ_slot(ORGAN_SLOT_LUNGS)
+ RegisterSignal(affected_mob, COMSIG_CARBON_GAIN_ORGAN, PROC_REF(on_gained_organ))
+ RegisterSignal(affected_mob, COMSIG_CARBON_LOSE_ORGAN, PROC_REF(on_removed_organ))
+ var/obj/item/organ/internal/lungs/lungs = affected_mob.get_organ_slot(ORGAN_SLOT_LUNGS)
if(!lungs)
return
apply_lung_levels(lungs)
@@ -416,11 +419,11 @@ Basically, we fill the time between now and 2s from now with hands based off the
lungs.cold_level_2_threshold = cached_cold_level_2
lungs.cold_level_3_threshold = cached_cold_level_3
-/datum/reagent/inverse/healing/convermol/on_mob_delete(mob/living/owner)
+/datum/reagent/inverse/healing/convermol/on_mob_delete(mob/living/affected_mob)
. = ..()
- UnregisterSignal(owner, COMSIG_CARBON_LOSE_ORGAN)
- UnregisterSignal(owner, COMSIG_CARBON_GAIN_ORGAN)
- var/obj/item/organ/internal/lungs/lungs = owner.get_organ_slot(ORGAN_SLOT_LUNGS)
+ UnregisterSignal(affected_mob, COMSIG_CARBON_LOSE_ORGAN)
+ UnregisterSignal(affected_mob, COMSIG_CARBON_GAIN_ORGAN)
+ var/obj/item/organ/internal/lungs/lungs = affected_mob.get_organ_slot(ORGAN_SLOT_LUNGS)
if(!lungs)
return
restore_lung_levels(lungs)
@@ -439,13 +442,13 @@ Basically, we fill the time between now and 2s from now with hands based off the
var/poison_interval = (9 SECONDS)
-/datum/reagent/inverse/technetium/on_mob_life(mob/living/carbon/owner, seconds_per_tick, times_fired)
+/datum/reagent/inverse/technetium/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
time_until_next_poison -= seconds_per_tick * (1 SECONDS)
if (time_until_next_poison <= 0)
time_until_next_poison = poison_interval
- owner.adjustToxLoss(creation_purity * 1, required_biotype = affected_biotype)
- . = TRUE
- ..()
+ if(affected_mob.adjustToxLoss(creation_purity * 1, updating_health = FALSE, required_biotype = affected_biotype))
+ return UPDATE_MOB_HEALTH
//Kind of a healing effect, Presumably you're using syrinver to purge so this helps that
/datum/reagent/inverse/healing/syriniver
@@ -457,7 +460,7 @@ Basically, we fill the time between now and 2s from now with hands based off the
var/cached_reagent_list = list()
addiction_types = list(/datum/addiction/medicine = 1.75)
-/datum/reagent/inverse/healing/syriniver/on_mob_add(mob/living/affected_mob)
+/datum/reagent/inverse/healing/syriniver/on_mob_add(mob/living/affected_mob, amount)
if(!(iscarbon(affected_mob)))
return ..()
var/mob/living/carbon/affected_carbon = affected_mob
@@ -493,12 +496,13 @@ Basically, we fill the time between now and 2s from now with hands based off the
//Heals toxins if it's the only thing present - kinda the oposite of multiver! Maybe that's why it's inverse!
/datum/reagent/inverse/healing/monover/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ var/need_mob_update
if(length(affected_mob.reagents.reagent_list) > 1)
- affected_mob.adjustOrganLoss(ORGAN_SLOT_LUNGS, 0.5 * seconds_per_tick, required_organ_flag = affected_organ_flags) //Hey! It's everyone's favourite drawback from multiver!
- return ..()
- affected_mob.adjustToxLoss(-2 * REM * creation_purity * seconds_per_tick, FALSE, required_biotype = affected_biotype)
- ..()
- return TRUE
+ need_mob_update = affected_mob.adjustOrganLoss(ORGAN_SLOT_LUNGS, 0.5 * seconds_per_tick, required_organ_flag = affected_organ_flags) //Hey! It's everyone's favourite drawback from multiver!
+ else
+ need_mob_update = affected_mob.adjustToxLoss(-2 * REM * creation_purity * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
///Can bring a corpse back to life temporarily (if heart is intact)
///Makes wounds bleed more, if it brought someone back, they take additional brute and heart damage
@@ -527,9 +531,10 @@ Basically, we fill the time between now and 2s from now with hands based off the
)
/datum/reagent/inverse/penthrite/on_mob_dead(mob/living/carbon/affected_mob, seconds_per_tick)
+ . = ..()
var/obj/item/organ/internal/heart/heart = affected_mob.get_organ_slot(ORGAN_SLOT_HEART)
if(!heart || heart.organ_flags & ORGAN_FAILING)
- return ..()
+ return
metabolization_rate = 0.2 * REM
affected_mob.add_traits(trait_buffs, type)
affected_mob.set_stat(CONSCIOUS) //This doesn't touch knocked out
@@ -544,18 +549,19 @@ Basically, we fill the time between now and 2s from now with hands based off the
back_from_the_dead = TRUE
affected_mob.emote("gasp")
affected_mob.playsound_local(affected_mob, 'sound/health/fastbeat.ogg', 65)
- ..()
/datum/reagent/inverse/penthrite/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
if(!back_from_the_dead)
- return ..()
+ return
//Following is for those brought back from the dead only
REMOVE_TRAIT(affected_mob, TRAIT_KNOCKEDOUT, CRIT_HEALTH_TRAIT)
REMOVE_TRAIT(affected_mob, TRAIT_KNOCKEDOUT, OXYLOSS_TRAIT)
for(var/datum/wound/iter_wound as anything in affected_mob.all_wounds)
iter_wound.adjust_blood_flow(1-creation_purity)
- affected_mob.adjustBruteLoss(5 * (1-creation_purity) * seconds_per_tick, required_bodytype = affected_bodytype)
- affected_mob.adjustOrganLoss(ORGAN_SLOT_HEART, (1 + (1-creation_purity)) * seconds_per_tick, required_organ_flag = affected_organ_flags)
+ var/need_mob_update
+ need_mob_update = affected_mob.adjustBruteLoss(5 * (1-creation_purity) * seconds_per_tick, required_bodytype = affected_bodytype)
+ need_mob_update += affected_mob.adjustOrganLoss(ORGAN_SLOT_HEART, (1 + (1-creation_purity)) * seconds_per_tick, required_organ_flag = affected_organ_flags)
if(affected_mob.health < HEALTH_THRESHOLD_CRIT)
affected_mob.add_movespeed_modifier(/datum/movespeed_modifier/reagent/nooartrium)
if(affected_mob.health < HEALTH_THRESHOLD_FULLCRIT)
@@ -563,19 +569,20 @@ Basically, we fill the time between now and 2s from now with hands based off the
var/obj/item/organ/internal/heart/heart = affected_mob.get_organ_slot(ORGAN_SLOT_HEART)
if(!heart || heart.organ_flags & ORGAN_FAILING)
remove_buffs(affected_mob)
- ..()
- return TRUE
-
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
+
/datum/reagent/inverse/penthrite/on_mob_delete(mob/living/carbon/affected_mob)
+ . = ..()
remove_buffs(affected_mob)
var/obj/item/organ/internal/heart/heart = affected_mob.get_organ_slot(ORGAN_SLOT_HEART)
if(affected_mob.health < -500 || heart.organ_flags & ORGAN_FAILING)//Honestly commendable if you get -500
explosion(affected_mob, light_impact_range = 1, explosion_cause = src)
qdel(heart)
affected_mob.visible_message(span_boldwarning("[affected_mob]'s heart explodes!"))
- return ..()
/datum/reagent/inverse/penthrite/overdose_start(mob/living/carbon/affected_mob)
+ . = ..()
if(!back_from_the_dead)
return ..()
var/obj/item/organ/internal/heart/heart = affected_mob.get_organ_slot(ORGAN_SLOT_HEART)
@@ -650,7 +657,7 @@ Basically, we fill the time between now and 2s from now with hands based off the
var/datum/brain_trauma/temp_trauma
/datum/reagent/inverse/neurine/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
- .=..()
+ . = ..()
if(temp_trauma)
return
if(!(SPT_PROB(creation_purity*10, seconds_per_tick)))
@@ -658,7 +665,7 @@ Basically, we fill the time between now and 2s from now with hands based off the
var/traumalist = subtypesof(/datum/brain_trauma)
var/list/forbiddentraumas = list(
/datum/brain_trauma/severe/split_personality, // Split personality uses a ghost, I don't want to use a ghost for a temp thing
- /datum/brain_trauma/special/obsessed, // Obsessed sets the owner as an antag - I presume this will lead to problems, so we'll remove it
+ /datum/brain_trauma/special/obsessed, // Obsessed sets the affected_mob as an antag - I presume this will lead to problems, so we'll remove it
/datum/brain_trauma/hypnosis, // Hypnosis, same reason as obsessed, plus a bug makes it remain even after the neurowhine purges and then turn into "nothing" on the med reading upon a second application
/datum/brain_trauma/special/honorbound, // Designed to be chaplain exclusive
)
@@ -672,7 +679,7 @@ Basically, we fill the time between now and 2s from now with hands based off the
return
/datum/reagent/inverse/neurine/on_mob_delete(mob/living/carbon/affected_mob)
- .=..()
+ . = ..()
if(!temp_trauma)
return
if(istype(temp_trauma, /datum/brain_trauma/special/imaginary_friend))//Good friends stay by you, no matter what
@@ -680,7 +687,7 @@ Basically, we fill the time between now and 2s from now with hands based off the
affected_mob.cure_trauma_type(temp_trauma, resilience = TRAUMA_RESILIENCE_MAGIC)
/datum/reagent/inverse/corazargh
- name = "Corazargh" //It's what you yell! Though, if you've a better name feel free. Also an omage to an older chem
+ name = "Corazargh" //It's what you yell! Though, if you've a better name feel free. Also an homage to an older chem
description = "Interferes with the body's natural pacemaker, forcing the patient to manually beat their heart."
color = "#5F5F5F"
self_consuming = TRUE
@@ -689,82 +696,22 @@ Basically, we fill the time between now and 2s from now with hands based off the
metabolization_rate = REM
chemical_flags = REAGENT_DEAD_PROCESS
tox_damage = 0
- ///Weakref to the old heart we're swapping for
- var/datum/weakref/original_heart_ref
- ///Weakref to the new heart that's temp added
- var/datum/weakref/manual_heart_ref
-///Creates a new cursed heart and puts the old inside of it, then replaces the position of the old
+///Give the victim the manual heart beating component.
/datum/reagent/inverse/corazargh/on_mob_metabolize(mob/living/affected_mob)
+ . = ..()
if(!iscarbon(affected_mob))
return
var/mob/living/carbon/carbon_mob = affected_mob
- var/obj/item/organ/internal/heart/original_heart = affected_mob.get_organ_slot(ORGAN_SLOT_HEART)
- if(!original_heart)
- return
- original_heart_ref = WEAKREF(original_heart)
-
- var/obj/item/organ/internal/heart/cursed/manual_heart = new(null, src)
- manual_heart_ref = WEAKREF(manual_heart)
- original_heart.Remove(carbon_mob, special = TRUE) //So we don't suddenly die
- original_heart.forceMove(manual_heart)
- original_heart.organ_flags |= ORGAN_FROZEN //Not actually frozen, but we want to pause decay
- manual_heart.Insert(carbon_mob, special = TRUE)
- //these last so instert doesn't call them
- RegisterSignal(carbon_mob, COMSIG_CARBON_GAIN_ORGAN, PROC_REF(on_gained_organ))
- RegisterSignal(carbon_mob, COMSIG_CARBON_LOSE_ORGAN, PROC_REF(on_removed_organ))
- to_chat(affected_mob, span_userdanger("You feel your heart suddenly stop beating on it's own - you'll have to manually beat it!"))
- ..()
-
-///Intercepts the new heart and creates a new cursed heart - putting the old inside of it
-/datum/reagent/inverse/corazargh/proc/on_gained_organ(mob/affected_mob, obj/item/organ/organ)
- SIGNAL_HANDLER
- if(!istype(organ, /obj/item/organ/internal/heart))
- return
- // DO NOT REACT TO YOUR OWN HEART ADDITION I SWEAR TO CHRIST
- var/obj/item/organ/internal/heart/cursed/manual_heart = manual_heart_ref?.resolve()
- if(organ == manual_heart)
- return
-
- var/mob/living/carbon/affected_carbon = affected_mob
- var/obj/item/organ/internal/heart/original_heart = organ
- original_heart_ref = WEAKREF(original_heart)
- original_heart.Remove(affected_carbon, special = TRUE)
- if(!manual_heart)
- manual_heart = new(null, src)
- manual_heart_ref = WEAKREF(manual_heart)
- original_heart.forceMove(manual_heart)
- original_heart.organ_flags |= ORGAN_FROZEN //Not actually frozen, but we want to pause decay
- manual_heart.Insert(affected_carbon, special = TRUE)
-
-///If we're ejecting out the organ - replace it with the original
-/datum/reagent/inverse/corazargh/proc/on_removed_organ(mob/prev_owner, obj/item/organ/organ)
- SIGNAL_HANDLER
- var/obj/item/organ/internal/heart/cursed/manual_heart = manual_heart_ref?.resolve()
- if(organ != manual_heart)
- return
- var/obj/item/organ/internal/heart/original_heart = original_heart_ref?.resolve()
- if(!original_heart)
+ var/obj/item/organ/internal/heart/affected_heart = carbon_mob.get_organ_slot(ORGAN_SLOT_HEART)
+ if(isnull(affected_heart))
return
+ carbon_mob.AddComponent(/datum/component/manual_heart)
+ return ..()
- original_heart.forceMove(manual_heart.loc)
- original_heart.organ_flags &= ~ORGAN_FROZEN //enable decay again
- QDEL_NULL(manual_heart_ref)
-
-///We're done - remove the curse and restore the old one
+///We're done - remove the curse
/datum/reagent/inverse/corazargh/on_mob_end_metabolize(mob/living/affected_mob)
- //Do these first so Insert doesn't call them
- UnregisterSignal(affected_mob, COMSIG_CARBON_LOSE_ORGAN)
- UnregisterSignal(affected_mob, COMSIG_CARBON_GAIN_ORGAN)
- if(!iscarbon(affected_mob))
- return
- var/mob/living/carbon/affected_carbon = affected_mob
- var/obj/item/organ/internal/heart/original_heart = original_heart_ref?.resolve()
- if(original_heart) //Mostly a just in case
- original_heart.organ_flags &= ~ORGAN_FROZEN //enable decay again
- original_heart.Insert(affected_carbon, special = TRUE)
- QDEL_NULL(manual_heart_ref)
- to_chat(affected_mob, span_userdanger("You feel your heart start beating normally again!"))
+ qdel(affected_mob.GetComponent(/datum/component/manual_heart))
..()
/datum/reagent/inverse/antihol
@@ -778,9 +725,9 @@ Basically, we fill the time between now and 2s from now with hands based off the
tox_damage = 0
/datum/reagent/inverse/antihol/on_mob_life(mob/living/carbon/C, seconds_per_tick, times_fired)
+ . = ..()
for(var/datum/reagent/consumable/ethanol/alcohol in C.reagents.reagent_list)
alcohol.boozepwr += seconds_per_tick
- ..()
/datum/reagent/inverse/oculine
name = "Oculater"
@@ -797,19 +744,19 @@ Basically, we fill the time between now and 2s from now with hands based off the
var/headache = FALSE
/datum/reagent/inverse/oculine/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
if(headache)
return ..()
if(SPT_PROB(100 * creation_purity, seconds_per_tick))
affected_mob.become_blind(IMPURE_OCULINE)
to_chat(affected_mob, span_danger("You suddenly develop a pounding headache as your vision fluxuates."))
headache = TRUE
- ..()
/datum/reagent/inverse/oculine/on_mob_end_metabolize(mob/living/affected_mob)
+ . = ..()
affected_mob.cure_blind(IMPURE_OCULINE)
if(headache)
to_chat(affected_mob, span_notice("Your headache clears up!"))
- ..()
/datum/reagent/impurity/inacusiate
name = "Tinacusiate"
@@ -825,15 +772,15 @@ Basically, we fill the time between now and 2s from now with hands based off the
var/randomSpan
/datum/reagent/impurity/inacusiate/on_mob_metabolize(mob/living/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
randomSpan = pick(list("clown", "small", "big", "hypnophrase", "alien", "cult", "alert", "danger", "emote", "yell", "brass", "sans", "papyrus", "robot", "his_grace", "phobia"))
RegisterSignal(affected_mob, COMSIG_MOVABLE_HEAR, PROC_REF(owner_hear))
to_chat(affected_mob, span_warning("Your hearing seems to be a bit off!"))
- ..()
/datum/reagent/impurity/inacusiate/on_mob_end_metabolize(mob/living/affected_mob)
+ . = ..()
UnregisterSignal(affected_mob, COMSIG_MOVABLE_HEAR)
to_chat(affected_mob, span_notice("You start hearing things normally again."))
- ..()
/datum/reagent/impurity/inacusiate/proc/owner_hear(mob/living/owner, list/hearing_args)
SIGNAL_HANDLER
diff --git a/code/modules/reagents/chemistry/reagents/impure_reagents/impure_toxin_reagents.dm b/code/modules/reagents/chemistry/reagents/impure_reagents/impure_toxin_reagents.dm
index 947c83c3166..0872fa66588 100644
--- a/code/modules/reagents/chemistry/reagents/impure_reagents/impure_toxin_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/impure_reagents/impure_toxin_reagents.dm
@@ -18,7 +18,6 @@
owner.adjust_disgust(50)
..()
-
//Formaldehyde - Impure Version
/datum/reagent/impurity/methanol
name = "Methanol"
@@ -29,9 +28,10 @@
liver_damage = 0
/datum/reagent/impurity/methanol/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
var/obj/item/organ/internal/eyes/eyes = affected_mob.get_organ_slot(ORGAN_SLOT_EYES)
- eyes?.apply_organ_damage(0.5 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)
- return ..()
+ if(eyes?.apply_organ_damage(0.5 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags))
+ return UPDATE_MOB_HEALTH
//Chloral Hydrate - Impure Version
/datum/reagent/impurity/chloralax
@@ -43,9 +43,9 @@
liver_damage = 0
/datum/reagent/impurity/chloralax/on_mob_life(mob/living/carbon/owner, seconds_per_tick)
- owner.adjustToxLoss(1 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
- ..()
-
+ . = ..()
+ if(owner.adjustToxLoss(1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype))
+ return UPDATE_MOB_HEALTH
//Mindbreaker Toxin - Impure Version
/datum/reagent/impurity/rosenol
@@ -58,12 +58,12 @@
metabolization_rate = 0.5 * REAGENTS_METABOLISM
/datum/reagent/impurity/rosenol/on_mob_life(mob/living/carbon/owner, seconds_per_tick)
+ . = ..()
var/obj/item/organ/internal/tongue/tongue = owner.get_organ_slot(ORGAN_SLOT_TONGUE)
if(!tongue)
- return ..()
+ return
if(SPT_PROB(4.0, seconds_per_tick))
owner.manual_emote("clicks with [owner.p_their()] tongue.")
owner.say("Noice.", forced = /datum/reagent/impurity/rosenol)
if(SPT_PROB(2.0, seconds_per_tick))
owner.say(pick("Ah! That was a mistake!", "Horrible.", "Watch out everybody, the potato is really hot.", "When I was six I ate a bag of plums.", "And if there is one thing I can't stand it's tomatoes.", "And if there is one thing I love it's tomatoes.", "We had a captain who was so strict, you weren't allowed to breathe in their station.", "The unrobust ones just used to keel over and die, you'd hear them going down behind you."), forced = /datum/reagent/impurity/rosenol)
- ..()
diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
index 30fae4db9c7..ff1671852c1 100644
--- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
@@ -13,7 +13,8 @@
current_cycle++
if(length(reagent_removal_skip_list))
return
- holder.remove_reagent(type, metabolization_rate * seconds_per_tick / affected_mob.metabolism_efficiency) //medicine reagents stay longer if you have a better metabolism
+ if(holder)
+ holder.remove_reagent(type, metabolization_rate * seconds_per_tick / affected_mob.metabolism_efficiency) //medicine reagents stay longer if you have a better metabolism
/datum/reagent/medicine/leporazine
name = "Leporazine"
@@ -23,6 +24,7 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/medicine/leporazine/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
var/target_temp = affected_mob.get_body_temp_normal(apply_change = FALSE)
if(affected_mob.bodytemperature > target_temp)
affected_mob.adjust_bodytemperature(-40 * TEMPERATURE_DAMAGE_COEFFICIENT * REM * seconds_per_tick, target_temp)
@@ -34,7 +36,6 @@
affected_human.adjust_coretemperature(-40 * TEMPERATURE_DAMAGE_COEFFICIENT * REM * seconds_per_tick, target_temp)
else if(affected_human.coretemperature < (target_temp + 1))
affected_human.adjust_coretemperature(40 * TEMPERATURE_DAMAGE_COEFFICIENT * REM * seconds_per_tick, 0, target_temp)
- ..()
/datum/reagent/medicine/adminordrazine //An OP chemical for admins
name = "Adminordrazine"
@@ -66,12 +67,11 @@
mytray.visible_message(span_warning("Nothing happens..."))
/datum/reagent/medicine/adminordrazine/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
- affected_mob.heal_bodypart_damage(5 * REM * seconds_per_tick, 5 * REM * seconds_per_tick, 0, FALSE, affected_bodytype)
- affected_mob.adjustToxLoss(-5 * REM * seconds_per_tick, FALSE, TRUE, affected_biotype)
+ . = ..()
+ affected_mob.heal_bodypart_damage(brute = 5 * REM * seconds_per_tick, burn = 5 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
+ affected_mob.adjustToxLoss(-5 * REM * seconds_per_tick, updating_health = FALSE, forced = TRUE, required_biotype = affected_biotype)
// Heal everything! That we want to. But really don't heal reagents. Otherwise we'll lose ... us.
- affected_mob.fully_heal(full_heal_flags & ~HEAL_ALL_REAGENTS)
- ..()
- return TRUE
+ affected_mob.fully_heal(full_heal_flags & ~HEAL_ALL_REAGENTS) // there is no need to return UPDATE_MOB_HEALTH because this proc calls updatehealth()
/datum/reagent/medicine/adminordrazine/quantum_heal
name = "Quantum Medicine"
@@ -95,11 +95,11 @@
affected_mob.AdjustParalyzed(-20 * REM * seconds_per_tick)
if(holder.has_reagent(/datum/reagent/toxin/mindbreaker))
holder.remove_reagent(/datum/reagent/toxin/mindbreaker, 5 * REM * seconds_per_tick)
+ . = ..()
affected_mob.adjust_hallucinations(-20 SECONDS * REM * seconds_per_tick)
if(SPT_PROB(16, seconds_per_tick))
- affected_mob.adjustToxLoss(1, FALSE, required_biotype = affected_biotype)
- . = TRUE
- ..()
+ if(affected_mob.adjustToxLoss(1, updating_health = FALSE, required_biotype = affected_biotype))
+ return UPDATE_MOB_HEALTH
/datum/reagent/medicine/synaphydramine
name = "Diphen-Synaptizine"
@@ -114,11 +114,11 @@
holder.remove_reagent(/datum/reagent/toxin/mindbreaker, 5 * REM * seconds_per_tick)
if(holder.has_reagent(/datum/reagent/toxin/histamine))
holder.remove_reagent(/datum/reagent/toxin/histamine, 5 * REM * seconds_per_tick)
+ . = ..()
affected_mob.adjust_hallucinations(-20 SECONDS * REM * seconds_per_tick)
if(SPT_PROB(16, seconds_per_tick))
- affected_mob.adjustToxLoss(1, FALSE, required_biotype = affected_biotype)
- . = TRUE
- ..()
+ if(affected_mob.adjustToxLoss(1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype))
+ return UPDATE_MOB_HEALTH
/datum/reagent/medicine/sansufentanyl
name = "Sansufentanyl"
@@ -128,16 +128,16 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/medicine/sansufentanyl/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
affected_mob.adjust_confusion_up_to(3 SECONDS * REM * seconds_per_tick, 5 SECONDS)
affected_mob.adjust_dizzy_up_to(6 SECONDS * REM * seconds_per_tick, 12 SECONDS)
- affected_mob.adjustStaminaLoss(1 * REM * seconds_per_tick)
+ if(affected_mob.adjustStaminaLoss(1 * REM * seconds_per_tick, updating_stamina = FALSE))
+ . = UPDATE_MOB_HEALTH
if(SPT_PROB(10, seconds_per_tick))
to_chat(affected_mob, "You feel confused and disoriented.")
if(prob(30))
SEND_SOUND(affected_mob, sound('sound/weapons/flash_ring.ogg'))
- ..()
- return TRUE
/datum/reagent/medicine/cryoxadone
name = "Cryoxadone"
@@ -150,22 +150,23 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/medicine/cryoxadone/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
metabolization_rate = REAGENTS_METABOLISM * (0.00001 * (affected_mob.bodytemperature ** 2) + 0.5)
if(affected_mob.bodytemperature >= T0C || !HAS_TRAIT(affected_mob, TRAIT_KNOCKEDOUT))
- ..()
return
var/power = -0.00003 * (affected_mob.bodytemperature ** 2) + 3
- affected_mob.adjustOxyLoss(-3 * power * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
- affected_mob.adjustBruteLoss(-power * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype)
- affected_mob.adjustFireLoss(-power * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype)
- affected_mob.adjustToxLoss(-power * REM * seconds_per_tick, FALSE, TRUE, affected_biotype) //heals TOXINLOVERs
- affected_mob.adjustCloneLoss(-power * REM * seconds_per_tick, FALSE, affected_biotype)
+ var/need_mob_update
+ need_mob_update = affected_mob.adjustOxyLoss(-3 * power * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
+ need_mob_update += affected_mob.adjustBruteLoss(-power * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
+ need_mob_update += affected_mob.adjustFireLoss(-power * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
+ need_mob_update += affected_mob.adjustToxLoss(-power * REM * seconds_per_tick, updating_health = FALSE, forced = TRUE, required_biotype = affected_biotype) //heals TOXINLOVERs
+ need_mob_update += affected_mob.adjustCloneLoss(-power * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)
for(var/i in affected_mob.all_wounds)
var/datum/wound/iter_wound = i
iter_wound.on_xadone(power * REM * seconds_per_tick)
REMOVE_TRAIT(affected_mob, TRAIT_DISFIGURED, TRAIT_GENERIC) //fixes common causes for disfiguration
- ..()
- return TRUE
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
// Healing
/datum/reagent/medicine/cryoxadone/on_hydroponics_apply(obj/machinery/hydroponics/mytray, mob/user)
@@ -181,12 +182,12 @@
metabolization_rate = 1.5 * REAGENTS_METABOLISM
/datum/reagent/medicine/clonexadone/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
if(affected_mob.bodytemperature < T0C)
- affected_mob.adjustCloneLoss((0.00006 * (affected_mob.bodytemperature ** 2) - 6) * REM * seconds_per_tick, FALSE)
+ if(affected_mob.adjustCloneLoss((0.00006 * (affected_mob.bodytemperature ** 2) - 6) * REM * seconds_per_tick, updating_health = FALSE))
+ . = UPDATE_MOB_HEALTH
REMOVE_TRAIT(affected_mob, TRAIT_DISFIGURED, TRAIT_GENERIC)
- . = TRUE
metabolization_rate = REAGENTS_METABOLISM * (0.000015 * (affected_mob.bodytemperature ** 2) + 0.75)
- ..()
/datum/reagent/medicine/pyroxadone
name = "Pyroxadone"
@@ -197,6 +198,7 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/medicine/pyroxadone/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
if(affected_mob.bodytemperature > BODYTEMP_HEAT_DAMAGE_LIMIT)
var/power = 0
switch(affected_mob.bodytemperature)
@@ -209,17 +211,18 @@
if(affected_mob.on_fire)
power *= 2
- affected_mob.adjustOxyLoss(-2 * power * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
- affected_mob.adjustBruteLoss(-power * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype)
- affected_mob.adjustFireLoss(-1.5 * power * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype)
- affected_mob.adjustToxLoss(-power * REM * seconds_per_tick, FALSE, TRUE, affected_biotype)
- affected_mob.adjustCloneLoss(-power * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
+ var/need_mob_update
+ need_mob_update = affected_mob.adjustOxyLoss(-2 * power * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
+ need_mob_update += affected_mob.adjustBruteLoss(-power * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
+ need_mob_update += affected_mob.adjustFireLoss(-1.5 * power * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
+ need_mob_update += affected_mob.adjustToxLoss(-power * REM * seconds_per_tick, updating_health = FALSE, forced = TRUE, required_biotype = affected_biotype)
+ need_mob_update += affected_mob.adjustCloneLoss(-power * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)
+ if(need_mob_update)
+ . = UPDATE_MOB_HEALTH
for(var/i in affected_mob.all_wounds)
var/datum/wound/iter_wound = i
iter_wound.on_xadone(power * REM * seconds_per_tick)
REMOVE_TRAIT(affected_mob, TRAIT_DISFIGURED, TRAIT_GENERIC)
- . = TRUE
- ..()
/datum/reagent/medicine/rezadone
name = "Rezadone"
@@ -232,18 +235,20 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/medicine/rezadone/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
- affected_mob.setCloneLoss(0) //Rezadone is almost never used in favor of cryoxadone. Hopefully this will change that. // No such luck so far
- affected_mob.heal_bodypart_damage(1 * REM * seconds_per_tick, 1 * REM * seconds_per_tick)
+ . = ..()
+ var/need_mob_update
+ need_mob_update = affected_mob.setCloneLoss(0) //Rezadone is almost never used in favor of cryoxadone. Hopefully this will change that. // No such luck so far
+ need_mob_update += affected_mob.heal_bodypart_damage(brute = 1 * REM * seconds_per_tick, burn = 1 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_biotype)
+ if(need_mob_update)
+ . = UPDATE_MOB_HEALTH
REMOVE_TRAIT(affected_mob, TRAIT_DISFIGURED, TRAIT_GENERIC)
- ..()
- . = TRUE
/datum/reagent/medicine/rezadone/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired)
- affected_mob.adjustToxLoss(1 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
+ . = ..()
+ if(affected_mob.adjustToxLoss(1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype))
+ . = UPDATE_MOB_HEALTH
affected_mob.set_dizzy_if_lower(10 SECONDS * REM * seconds_per_tick)
affected_mob.set_jitter_if_lower(10 SECONDS * REM * seconds_per_tick)
- ..()
- . = TRUE
/datum/reagent/medicine/rezadone/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume)
. = ..()
@@ -263,13 +268,13 @@
ph = 8.1
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
-/datum/reagent/medicine/spaceacillin/on_mob_add(mob/living/L)
+/datum/reagent/medicine/spaceacillin/on_mob_add(mob/living/affected_mob)
. = ..()
- ADD_TRAIT(L, TRAIT_VIRUS_RESISTANCE, type)
+ ADD_TRAIT(affected_mob, TRAIT_VIRUS_RESISTANCE, type)
-/datum/reagent/medicine/spaceacillin/on_mob_delete(mob/living/L)
+/datum/reagent/medicine/spaceacillin/on_mob_delete(mob/living/affected_mob)
. = ..()
- REMOVE_TRAIT(L, TRAIT_VIRUS_RESISTANCE, type)
+ REMOVE_TRAIT(affected_mob, TRAIT_VIRUS_RESISTANCE, type)
//Goon Chems. Ported mainly from Goonstation. Easily mixable (or not so easily) and provide a variety of effects.
@@ -284,18 +289,20 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/medicine/oxandrolone/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
+ var/need_mob_update
if(affected_mob.getFireLoss() > 25)
- affected_mob.adjustFireLoss(-4 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) //Twice as effective as AIURI for severe burns
+ need_mob_update = affected_mob.adjustFireLoss(-4 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) //Twice as effective as AIURI for severe burns
else
- affected_mob.adjustFireLoss(-0.5 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) //But only a quarter as effective for more minor ones
- ..()
- . = TRUE
+ need_mob_update = affected_mob.adjustFireLoss(-0.5 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) //But only a quarter as effective for more minor ones
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/medicine/oxandrolone/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
if(affected_mob.getFireLoss()) //It only makes existing burns worse
- affected_mob.adjustFireLoss(4.5 * REM * seconds_per_tick, FALSE, FALSE, BODYTYPE_ORGANIC) // it's going to be healing either 4 or 0.5
- . = TRUE
- ..()
+ if(affected_mob.adjustFireLoss(4.5 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_biotype)) // it's going to be healing either 4 or 0.5
+ return UPDATE_MOB_HEALTH
/datum/reagent/medicine/salglu_solution
name = "Saline-Glucose Solution"
@@ -312,6 +319,8 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/medicine/salglu_solution/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
+ var/need_mob_update
if(last_added)
affected_mob.blood_volume -= last_added
last_added = 0
@@ -321,25 +330,29 @@
last_added = new_blood_level - affected_mob.blood_volume
affected_mob.blood_volume = new_blood_level + (extra_regen * REM * seconds_per_tick)
if(SPT_PROB(18, seconds_per_tick))
- affected_mob.adjustBruteLoss(-0.5, FALSE, required_bodytype = affected_bodytype)
- affected_mob.adjustFireLoss(-0.5, FALSE, required_bodytype = affected_bodytype)
- . = TRUE
- ..()
+ need_mob_update = affected_mob.adjustBruteLoss(-0.5 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_biotype)
+ need_mob_update += affected_mob.adjustFireLoss(-0.5 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_biotype)
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/medicine/salglu_solution/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
+ var/need_mob_update
if(SPT_PROB(1.5, seconds_per_tick))
- to_chat(affected_mob, span_warning("You feel salty."))
- holder.add_reagent(/datum/reagent/consumable/salt, 1)
- holder.remove_reagent(/datum/reagent/medicine/salglu_solution, 0.5)
+ if(holder)
+ to_chat(affected_mob, span_warning("You feel salty."))
+ holder.add_reagent(/datum/reagent/consumable/salt, 1)
+ holder.remove_reagent(/datum/reagent/medicine/salglu_solution, 0.5)
else if(SPT_PROB(1.5, seconds_per_tick))
- to_chat(affected_mob, span_warning("You feel sweet."))
- holder.add_reagent(/datum/reagent/consumable/sugar, 1)
- holder.remove_reagent(/datum/reagent/medicine/salglu_solution, 0.5)
+ if(holder)
+ to_chat(affected_mob, span_warning("You feel sweet."))
+ holder.add_reagent(/datum/reagent/consumable/sugar, 1)
+ holder.remove_reagent(/datum/reagent/medicine/salglu_solution, 0.5)
if(SPT_PROB(18, seconds_per_tick))
- affected_mob.adjustBruteLoss(0.5, FALSE, FALSE, BODYTYPE_ORGANIC)
- affected_mob.adjustFireLoss(0.5, FALSE, FALSE, BODYTYPE_ORGANIC)
- . = TRUE
- ..()
+ need_mob_update = affected_mob.adjustBruteLoss(0.5 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_biotype)
+ need_mob_update += affected_mob.adjustFireLoss(0.5 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_biotype)
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/medicine/mine_salve
name = "Miner's Salve"
@@ -351,10 +364,12 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_AFFECTS_WOUNDS
/datum/reagent/medicine/mine_salve/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
- affected_mob.adjustBruteLoss(-0.25 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype)
- affected_mob.adjustFireLoss(-0.25 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype)
- ..()
- return TRUE
+ . = ..()
+ var/need_mob_update
+ need_mob_update = affected_mob.adjustBruteLoss(-0.25 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype)
+ need_mob_update += affected_mob.adjustFireLoss(-0.25 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype)
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/medicine/mine_salve/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message = TRUE)
. = ..()
@@ -374,13 +389,13 @@
if(show_message)
to_chat(exposed_carbon, span_danger("You feel your injuries fade away to nothing!") )
-/datum/reagent/medicine/mine_salve/on_mob_metabolize(mob/living/metabolizer)
+/datum/reagent/medicine/mine_salve/on_mob_metabolize(mob/living/affected_mob)
. = ..()
- metabolizer.apply_status_effect(/datum/status_effect/grouped/screwy_hud/fake_healthy, type)
+ affected_mob.apply_status_effect(/datum/status_effect/grouped/screwy_hud/fake_healthy, type)
-/datum/reagent/medicine/mine_salve/on_mob_end_metabolize(mob/living/metabolizer)
+/datum/reagent/medicine/mine_salve/on_mob_end_metabolize(mob/living/affected_mob)
. = ..()
- metabolizer.remove_status_effect(/datum/status_effect/grouped/screwy_hud/fake_healthy, type)
+ affected_mob.remove_status_effect(/datum/status_effect/grouped/screwy_hud/fake_healthy, type)
/datum/reagent/medicine/mine_salve/on_burn_wound_processing(datum/wound/burn/flesh/burn_wound)
burn_wound.sanitization += 0.3
@@ -398,20 +413,24 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/medicine/omnizine/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
- affected_mob.adjustToxLoss(-healing * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
- affected_mob.adjustOxyLoss(-healing * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
- affected_mob.adjustBruteLoss(-healing * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype)
- affected_mob.adjustFireLoss(-healing * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype)
- ..()
- . = TRUE
+ . = ..()
+ var/need_mob_update
+ need_mob_update = affected_mob.adjustToxLoss(-healing * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)
+ need_mob_update += affected_mob.adjustOxyLoss(-healing * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
+ need_mob_update += affected_mob.adjustBruteLoss(-healing * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
+ need_mob_update += affected_mob.adjustFireLoss(-healing * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/medicine/omnizine/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired)
- affected_mob.adjustToxLoss(1.5 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
- affected_mob.adjustOxyLoss(1.5 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
- affected_mob.adjustBruteLoss(1.5 * REM * seconds_per_tick, FALSE, FALSE, BODYTYPE_ORGANIC)
- affected_mob.adjustFireLoss(1.5 * REM * seconds_per_tick, FALSE, FALSE, BODYTYPE_ORGANIC)
- ..()
- . = TRUE
+ . = ..()
+ var/need_mob_update
+ need_mob_update = affected_mob.adjustToxLoss(1.5 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)
+ need_mob_update += affected_mob.adjustOxyLoss(1.5 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
+ need_mob_update += affected_mob.adjustBruteLoss(1.5 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
+ need_mob_update += affected_mob.adjustFireLoss(1.5 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/medicine/omnizine/protozine
name = "Protozine"
@@ -433,21 +452,21 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/medicine/calomel/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
for(var/datum/reagent/target_reagent in affected_mob.reagents.reagent_list)
if(istype(target_reagent, /datum/reagent/medicine/calomel))
continue
affected_mob.reagents.remove_reagent(target_reagent.type, 3 * REM * seconds_per_tick)
var/toxin_amount = round(affected_mob.health / 40, 0.1)
- affected_mob.adjustToxLoss(toxin_amount * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
- ..()
- return TRUE
+ if(affected_mob.adjustToxLoss(toxin_amount * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype))
+ return UPDATE_MOB_HEALTH
/datum/reagent/medicine/calomel/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
for(var/datum/reagent/medicine/calomel/target_reagent in affected_mob.reagents.reagent_list)
affected_mob.reagents.remove_reagent(target_reagent.type, 2 * REM * seconds_per_tick)
- affected_mob.adjustToxLoss(2.5 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
- ..()
- return TRUE
+ if(affected_mob.adjustToxLoss(2.5 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype))
+ return UPDATE_MOB_HEALTH
/datum/reagent/medicine/ammoniated_mercury
name = "Ammoniated Mercury"
@@ -463,22 +482,22 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/medicine/ammoniated_mercury/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
var/toxin_chem_amount = 0
for(var/datum/reagent/toxin/target_reagent in affected_mob.reagents.reagent_list)
toxin_chem_amount += 1
affected_mob.reagents.remove_reagent(target_reagent.type, 5 * REM * seconds_per_tick)
var/toxin_amount = round(affected_mob.getBruteLoss() / 15, 0.1) + round(affected_mob.getFireLoss() / 30, 0.1) - 3
- affected_mob.adjustToxLoss(toxin_amount * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
+ if(affected_mob.adjustToxLoss(toxin_amount * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype))
+ . = UPDATE_MOB_HEALTH
if(toxin_chem_amount == 0)
for(var/datum/reagent/medicine/ammoniated_mercury/target_reagent in affected_mob.reagents.reagent_list)
affected_mob.reagents.remove_reagent(target_reagent.type, 1 * REM * seconds_per_tick)
- ..()
- return TRUE
/datum/reagent/medicine/ammoniated_mercury/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired)
- affected_mob.adjustToxLoss(3 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
- ..()
- return TRUE
+ . = ..()
+ if(affected_mob.adjustToxLoss(3 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype))
+ return UPDATE_MOB_HEALTH
/datum/reagent/medicine/potass_iodide
name = "Potassium Iodide"
@@ -494,15 +513,14 @@
ADD_TRAIT(affected_mob, TRAIT_HALT_RADIATION_EFFECTS, "[type]")
/datum/reagent/medicine/potass_iodide/on_mob_end_metabolize(mob/living/affected_mob)
+ . = ..()
REMOVE_TRAIT(affected_mob, TRAIT_HALT_RADIATION_EFFECTS, "[type]")
- return ..()
/datum/reagent/medicine/potass_iodide/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
- if (HAS_TRAIT(affected_mob, TRAIT_IRRADIATED))
- affected_mob.adjustToxLoss(-1 * REM * seconds_per_tick, required_biotype = affected_biotype)
-
- ..()
- return TRUE
+ . = ..()
+ if(HAS_TRAIT(affected_mob, TRAIT_IRRADIATED))
+ if(affected_mob.adjustToxLoss(-1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype))
+ return UPDATE_MOB_HEALTH
/datum/reagent/medicine/pen_acid
name = "Pentetic Acid"
@@ -518,16 +536,16 @@
ADD_TRAIT(affected_mob, TRAIT_HALT_RADIATION_EFFECTS, "[type]")
/datum/reagent/medicine/pen_acid/on_mob_end_metabolize(mob/living/affected_mob)
+ . = ..()
REMOVE_TRAIT(affected_mob, TRAIT_HALT_RADIATION_EFFECTS, "[type]")
- return ..()
/datum/reagent/medicine/pen_acid/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
- affected_mob.adjustToxLoss(-2 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
+ . = ..()
+ if(affected_mob.adjustToxLoss(-2 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype))
+ . = UPDATE_MOB_HEALTH
for(var/datum/reagent/R in affected_mob.reagents.reagent_list)
if(R != src)
affected_mob.reagents.remove_reagent(R.type, 2 * REM * seconds_per_tick)
- ..()
- . = TRUE
/datum/reagent/medicine/sal_acid
name = "Salicylic Acid"
@@ -540,18 +558,20 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/medicine/sal_acid/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
+ var/need_mob_update
if(affected_mob.getBruteLoss() > 25)
- affected_mob.adjustBruteLoss(-4 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype)
+ need_mob_update = affected_mob.adjustBruteLoss(-4 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
else
- affected_mob.adjustBruteLoss(-0.5 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype)
- ..()
- . = TRUE
+ need_mob_update = affected_mob.adjustBruteLoss(-0.5 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/medicine/sal_acid/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
if(affected_mob.getBruteLoss()) //It only makes existing bruises worse
- affected_mob.adjustBruteLoss(4.5 * REM * seconds_per_tick, FALSE, FALSE, BODYTYPE_ORGANIC) // it's going to be healing either 4 or 0.5
- . = TRUE
- ..()
+ if(affected_mob.adjustBruteLoss(4.5 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = BODYTYPE_ORGANIC)) // it's going to be healing either 4 or 0.5
+ return UPDATE_MOB_HEALTH
/datum/reagent/medicine/salbutamol
name = "Salbutamol"
@@ -563,14 +583,17 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/medicine/salbutamol/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
- affected_mob.adjustOxyLoss(-3 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
+ . = ..()
+ var/need_mob_update
+ need_mob_update = affected_mob.adjustOxyLoss(-3 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
if(affected_mob.losebreath >= 4)
var/obj/item/organ/internal/lungs/affected_lungs = affected_mob.get_organ_slot(ORGAN_SLOT_LUNGS)
var/our_respiration_type = affected_lungs ? affected_lungs.respiration_type : affected_mob.mob_respiration_type // use lungs' respiration type or mob_respiration_type if no lungs
if(our_respiration_type & affected_respiration_type)
affected_mob.losebreath -= 2 * REM * seconds_per_tick
- ..()
- . = TRUE
+ need_mob_update = TRUE
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/medicine/ephedrine
name = "Ephedrine"
@@ -587,16 +610,17 @@
inverse_chem_val = 0.4
/datum/reagent/medicine/ephedrine/on_mob_metabolize(mob/living/affected_mob)
- ..()
+ . = ..()
affected_mob.add_movespeed_modifier(/datum/movespeed_modifier/reagent/ephedrine)
ADD_TRAIT(affected_mob, TRAIT_BATON_RESISTANCE, type)
/datum/reagent/medicine/ephedrine/on_mob_end_metabolize(mob/living/affected_mob)
+ . = ..()
affected_mob.remove_movespeed_modifier(/datum/movespeed_modifier/reagent/ephedrine)
REMOVE_TRAIT(affected_mob, TRAIT_BATON_RESISTANCE, type)
- ..()
/datum/reagent/medicine/ephedrine/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
if(SPT_PROB(10 * (1.5-creation_purity), seconds_per_tick) && iscarbon(affected_mob))
var/obj/item/I = affected_mob.get_active_held_item()
if(I && affected_mob.dropItemToGround(I))
@@ -604,11 +628,11 @@
affected_mob.set_jitter_if_lower(20 SECONDS)
affected_mob.AdjustAllImmobility(-20 * REM * seconds_per_tick * normalise_creation_purity())
- affected_mob.adjustStaminaLoss(-1 * REM * seconds_per_tick * normalise_creation_purity(), FALSE)
- ..()
- return TRUE
+ affected_mob.adjustStaminaLoss(-1 * REM * seconds_per_tick * normalise_creation_purity(), updating_stamina = FALSE)
+ return UPDATE_MOB_HEALTH
/datum/reagent/medicine/ephedrine/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
if(SPT_PROB(1 * (1 + (1-normalise_creation_purity())), seconds_per_tick) && iscarbon(affected_mob))
var/datum/disease/D = new /datum/disease/heart_failure
affected_mob.ForceContractDisease(D)
@@ -619,10 +643,9 @@
to_chat(affected_mob, span_notice("[pick("Your head pounds.", "You feel a tight pain in your chest.", "You find it hard to stay still.", "You feel your heart practically beating out of your chest.")]"))
if(SPT_PROB(18 * (1 + (1-normalise_creation_purity())), seconds_per_tick))
- affected_mob.adjustToxLoss(1, FALSE, required_biotype = affected_biotype)
+ affected_mob.adjustToxLoss(1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)
affected_mob.losebreath++
- . = TRUE
- return TRUE
+ return UPDATE_MOB_HEALTH
/datum/reagent/medicine/diphenhydramine
name = "Diphenhydramine"
@@ -638,7 +661,7 @@
affected_mob.adjust_drowsiness(2 SECONDS)
affected_mob.adjust_jitter(-2 SECONDS * REM * seconds_per_tick)
holder.remove_reagent(/datum/reagent/toxin/histamine, 3 * REM * seconds_per_tick)
- ..()
+ return ..()
/datum/reagent/medicine/morphine
name = "Morphine"
@@ -652,32 +675,31 @@
addiction_types = list(/datum/addiction/opioids = 10)
/datum/reagent/medicine/morphine/on_mob_metabolize(mob/living/affected_mob)
- ..()
+ . = ..()
affected_mob.add_movespeed_mod_immunities(type, /datum/movespeed_modifier/damage_slowdown)
/datum/reagent/medicine/morphine/on_mob_end_metabolize(mob/living/affected_mob)
+ . = ..()
affected_mob.remove_movespeed_mod_immunities(type, /datum/movespeed_modifier/damage_slowdown)
- ..()
/datum/reagent/medicine/morphine/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
- if(current_cycle >= 5)
+ . = ..()
+ if(current_cycle > 5)
affected_mob.add_mood_event("numb", /datum/mood_event/narcotic_medium, name)
switch(current_cycle)
- if(11)
+ if(12)
to_chat(affected_mob, span_warning("You start to feel tired...") )
- if(12 to 24)
+ if(13 to 25)
affected_mob.adjust_drowsiness(2 SECONDS * REM * seconds_per_tick)
- if(24 to INFINITY)
+ if(25 to INFINITY)
affected_mob.Sleeping(40 * REM * seconds_per_tick)
- . = TRUE
- ..()
/datum/reagent/medicine/morphine/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
if(SPT_PROB(18, seconds_per_tick))
affected_mob.drop_all_held_items()
affected_mob.set_dizzy_if_lower(4 SECONDS)
affected_mob.set_jitter_if_lower(4 SECONDS)
- ..()
/datum/reagent/medicine/oculine
@@ -729,33 +751,31 @@
restore_eyesight(prev_affected_mob, eyes)
/datum/reagent/medicine/oculine/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
var/normalized_purity = normalise_creation_purity()
affected_mob.adjust_temp_blindness(-4 SECONDS * REM * seconds_per_tick * normalized_purity)
affected_mob.adjust_eye_blur(-4 SECONDS * REM * seconds_per_tick * normalized_purity)
var/obj/item/organ/internal/eyes/eyes = affected_mob.get_organ_slot(ORGAN_SLOT_EYES)
- if(isnull(eyes))
- return ..()
-
- // Healing eye damage will cure nearsightedness and blindness from ... eye damage
- eyes.apply_organ_damage(-2 * REM * seconds_per_tick * normalise_creation_purity(), required_organ_flag = affected_organ_flags)
- // If our eyes are seriously damaged, we have a probability of causing eye blur while healing depending on purity
- if(eyes.damaged && IS_ORGANIC_ORGAN(eyes) && SPT_PROB(16 - min(normalized_purity * 6, 12), seconds_per_tick))
- // While healing, gives some eye blur
- if(affected_mob.is_blind_from(EYE_DAMAGE))
- to_chat(affected_mob, span_warning("Your vision slowly returns..."))
- affected_mob.adjust_eye_blur(20 SECONDS)
- else if(affected_mob.is_nearsighted_from(EYE_DAMAGE))
- to_chat(affected_mob, span_warning("The blackness in your peripheral vision begins to fade."))
- affected_mob.adjust_eye_blur(5 SECONDS)
-
- return ..() || TRUE
+ if(eyes)
+ // Healing eye damage will cure nearsightedness and blindness from ... eye damage
+ if(eyes.apply_organ_damage(-2 * REM * seconds_per_tick * normalise_creation_purity(), required_organ_flag = affected_organ_flags))
+ . = UPDATE_MOB_HEALTH
+ // If our eyes are seriously damaged, we have a probability of causing eye blur while healing depending on purity
+ if(eyes.damaged && IS_ORGANIC_ORGAN(eyes) && SPT_PROB(16 - min(normalized_purity * 6, 12), seconds_per_tick))
+ // While healing, gives some eye blur
+ if(affected_mob.is_blind_from(EYE_DAMAGE))
+ to_chat(affected_mob, span_warning("Your vision slowly returns..."))
+ affected_mob.adjust_eye_blur(20 SECONDS)
+ else if(affected_mob.is_nearsighted_from(EYE_DAMAGE))
+ to_chat(affected_mob, span_warning("The blackness in your peripheral vision begins to fade."))
+ affected_mob.adjust_eye_blur(5 SECONDS)
/datum/reagent/medicine/oculine/on_mob_delete(mob/living/affected_mob)
+ . = ..()
var/obj/item/organ/internal/eyes/eyes = affected_mob.get_organ_slot(ORGAN_SLOT_EYES)
if(!eyes)
return
restore_eyesight(affected_mob, eyes)
- ..()
/datum/reagent/medicine/inacusiate
name = "Inacusiate"
@@ -783,12 +803,12 @@
message = composer.compose_message(affected_mob, message_language, message, null, spans, message_mods)
/datum/reagent/medicine/inacusiate/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
var/obj/item/organ/internal/ears/ears = affected_mob.get_organ_slot(ORGAN_SLOT_EARS)
if(!ears)
- return ..()
+ return
ears.adjustEarDamage(-4 * REM * seconds_per_tick * normalise_creation_purity(), -4 * REM * seconds_per_tick * normalise_creation_purity())
- ..()
- return TRUE
+ return UPDATE_MOB_HEALTH
/datum/reagent/medicine/inacusiate/on_mob_delete(mob/living/affected_mob)
. = ..()
@@ -809,16 +829,19 @@
ADD_TRAIT(affected_mob, TRAIT_PREVENT_IMPLANT_AUTO_EXPLOSION, "[type]")
/datum/reagent/medicine/atropine/on_mob_delete(mob/living/affected_mob)
+ . = ..()
REMOVE_TRAIT(affected_mob, TRAIT_PREVENT_IMPLANT_AUTO_EXPLOSION, "[type]")
- return ..()
/datum/reagent/medicine/atropine/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
if(affected_mob.health <= affected_mob.crit_threshold)
- affected_mob.adjustToxLoss(-2 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
- affected_mob.adjustBruteLoss(-2* REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype)
- affected_mob.adjustFireLoss(-2 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype)
- affected_mob.adjustOxyLoss(-5 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
- . = TRUE
+ var/need_mob_update
+ need_mob_update = affected_mob.adjustToxLoss(-2 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)
+ need_mob_update += affected_mob.adjustBruteLoss(-2* REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
+ need_mob_update += affected_mob.adjustFireLoss(-2 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
+ need_mob_update += affected_mob.adjustOxyLoss(-5 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
+ if(need_mob_update)
+ . = UPDATE_MOB_HEALTH
var/obj/item/organ/internal/lungs/affected_lungs = affected_mob.get_organ_slot(ORGAN_SLOT_LUNGS)
var/our_respiration_type = affected_lungs ? affected_lungs.respiration_type : affected_mob.mob_respiration_type
if(our_respiration_type & affected_respiration_type)
@@ -826,14 +849,13 @@
if(SPT_PROB(10, seconds_per_tick))
affected_mob.set_dizzy_if_lower(10 SECONDS)
affected_mob.set_jitter_if_lower(10 SECONDS)
- ..()
/datum/reagent/medicine/atropine/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired)
- affected_mob.adjustToxLoss(0.5 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
- . = TRUE
+ . = ..()
+ if(affected_mob.adjustToxLoss(0.5 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype))
+ . = UPDATE_MOB_HEALTH
affected_mob.set_dizzy_if_lower(2 SECONDS * REM * seconds_per_tick)
affected_mob.set_jitter_if_lower(2 SECONDS * REM * seconds_per_tick)
- ..()
/datum/reagent/medicine/epinephrine
name = "Epinephrine"
@@ -845,13 +867,13 @@
ph = 10.2
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
-/datum/reagent/medicine/epinephrine/on_mob_metabolize(mob/living/carbon/affected_mob)
- ..()
+/datum/reagent/medicine/epinephrine/on_mob_metabolize(mob/living/affected_mob)
+ . = ..()
ADD_TRAIT(affected_mob, TRAIT_NOCRITDAMAGE, type)
-/datum/reagent/medicine/epinephrine/on_mob_end_metabolize(mob/living/carbon/affected_mob)
+/datum/reagent/medicine/epinephrine/on_mob_end_metabolize(mob/living/affected_mob)
+ . = ..()
REMOVE_TRAIT(affected_mob, TRAIT_NOCRITDAMAGE, type)
- ..()
/datum/reagent/medicine/epinephrine/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
if(holder.has_reagent(/datum/reagent/toxin/lexorin))
@@ -859,36 +881,45 @@
holder.remove_reagent(/datum/reagent/medicine/epinephrine, 1 * REM * seconds_per_tick)
if(SPT_PROB(10, seconds_per_tick))
holder.add_reagent(/datum/reagent/toxin/histamine, 4)
- ..()
- return FALSE
+ return ..()
+
+ . = ..()
+
+ var/need_mob_update
if(affected_mob.health <= affected_mob.crit_threshold)
- affected_mob.adjustToxLoss(-0.5 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
- affected_mob.adjustBruteLoss(-0.5 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype)
- affected_mob.adjustFireLoss(-0.5 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype)
- affected_mob.adjustOxyLoss(-0.5 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
+ need_mob_update = affected_mob.adjustToxLoss(-0.5 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)
+ need_mob_update += affected_mob.adjustBruteLoss(-0.5 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
+ need_mob_update += affected_mob.adjustFireLoss(-0.5 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
+ need_mob_update += affected_mob.adjustOxyLoss(-0.5 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
if(affected_mob.losebreath >= 4)
var/obj/item/organ/internal/lungs/affected_lungs = affected_mob.get_organ_slot(ORGAN_SLOT_LUNGS)
var/our_respiration_type = affected_lungs ? affected_lungs.respiration_type : affected_mob.mob_respiration_type
if(our_respiration_type & affected_respiration_type)
affected_mob.losebreath -= 2 * REM * seconds_per_tick
+ need_mob_update = TRUE
if(affected_mob.losebreath < 0)
affected_mob.losebreath = 0
- affected_mob.adjustStaminaLoss(-0.5 * REM * seconds_per_tick, 0)
+ need_mob_update = TRUE
+ need_mob_update += affected_mob.adjustStaminaLoss(-0.5 * REM * seconds_per_tick, updating_stamina = FALSE)
if(SPT_PROB(10, seconds_per_tick))
affected_mob.AdjustAllImmobility(-20)
- ..()
- return TRUE
+ need_mob_update = TRUE
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/medicine/epinephrine/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
if(SPT_PROB(18, REM * seconds_per_tick))
- affected_mob.adjustStaminaLoss(2.5, 0)
- affected_mob.adjustToxLoss(1, FALSE, required_biotype = affected_biotype)
+ var/need_mob_update
+ need_mob_update = affected_mob.adjustStaminaLoss(2.5 * REM * seconds_per_tick, updating_stamina = FALSE)
+ need_mob_update += affected_mob.adjustToxLoss(1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)
var/obj/item/organ/internal/lungs/affected_lungs = affected_mob.get_organ_slot(ORGAN_SLOT_LUNGS)
var/our_respiration_type = affected_lungs ? affected_lungs.respiration_type : affected_mob.mob_respiration_type
if(our_respiration_type & affected_respiration_type)
affected_mob.losebreath++
- . = TRUE
- ..()
+ need_mob_update = TRUE
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/medicine/strange_reagent
name = "Strange Reagent"
@@ -990,11 +1021,13 @@
return ..()
/datum/reagent/medicine/strange_reagent/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
var/damage_at_random = rand(0, 250)/100 //0 to 2.5
- affected_mob.adjustBruteLoss(damage_at_random * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype)
- affected_mob.adjustFireLoss(damage_at_random * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype)
- ..()
- return TRUE
+ var/need_mob_update
+ need_mob_update = affected_mob.adjustBruteLoss(damage_at_random * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
+ need_mob_update += affected_mob.adjustFireLoss(damage_at_random * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/medicine/mannitol
name = "Mannitol"
@@ -1009,9 +1042,9 @@
inverse_chem_val = 0.45
/datum/reagent/medicine/mannitol/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
- affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, -2 * REM * seconds_per_tick * normalise_creation_purity(), required_organ_flag = affected_organ_flags)
- ..()
- return TRUE
+ . = ..()
+ if(affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, -2 * REM * seconds_per_tick * normalise_creation_purity(), required_organ_flag = affected_organ_flags))
+ return UPDATE_MOB_HEALTH
//Having mannitol in you will pause the brain damage from brain tumor (so it heals an even 2 brain damage instead of 1.8)
/datum/reagent/medicine/mannitol/on_mob_metabolize(mob/living/carbon/affected_mob)
@@ -1019,13 +1052,15 @@
ADD_TRAIT(affected_mob, TRAIT_TUMOR_SUPPRESSED, TRAIT_GENERIC)
/datum/reagent/medicine/mannitol/on_mob_end_metabolize(mob/living/carbon/affected_mob)
- REMOVE_TRAIT(affected_mob, TRAIT_TUMOR_SUPPRESSED, TRAIT_GENERIC)
. = ..()
+ REMOVE_TRAIT(affected_mob, TRAIT_TUMOR_SUPPRESSED, TRAIT_GENERIC)
/datum/reagent/medicine/mannitol/overdose_start(mob/living/affected_mob)
+ . = ..()
to_chat(affected_mob, span_notice("You suddenly feel E N L I G H T E N E D!"))
/datum/reagent/medicine/mannitol/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
if(SPT_PROB(65, seconds_per_tick))
return
var/list/tips
@@ -1037,7 +1072,6 @@
tips = world.file2list("strings/chemistrytips.txt")
var/message = pick(tips)
send_tip_of_the_round(affected_mob, message)
- return ..()
/datum/reagent/medicine/neurine
name = "Neurine"
@@ -1073,11 +1107,12 @@
holder.remove_reagent(/datum/reagent/consumable/ethanol/neurotoxin, 5 * REM * seconds_per_tick * normalise_creation_purity())
if(SPT_PROB(8 * normalise_creation_purity(), seconds_per_tick))
affected_mob.cure_trauma_type(resilience = TRAUMA_RESILIENCE_BASIC)
- ..()
+ return ..()
/datum/reagent/medicine/neurine/on_mob_dead(mob/living/carbon/affected_mob, seconds_per_tick)
- affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, -1 * REM * seconds_per_tick * normalise_creation_purity(), required_organ_flag = affected_organ_flags)
- ..()
+ . = ..()
+ if(affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, -1 * REM * seconds_per_tick * normalise_creation_purity(), required_organ_flag = affected_organ_flags))
+ return UPDATE_MOB_HEALTH
/datum/reagent/medicine/mutadone
name = "Mutadone"
@@ -1088,11 +1123,10 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/medicine/mutadone/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
affected_mob.remove_status_effect(/datum/status_effect/jitter)
if(affected_mob.has_dna())
affected_mob.dna.remove_all_mutations(list(MUT_NORMAL, MUT_EXTRA), TRUE)
- if(!QDELETED(affected_mob)) //We were a monkey, now a human
- ..()
/datum/reagent/medicine/antihol
name = "Antihol"
@@ -1114,13 +1148,13 @@
)
/datum/reagent/medicine/antihol/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
for(var/effect in status_effects_to_clear)
affected_mob.remove_status_effect(effect)
affected_mob.reagents.remove_all_type(/datum/reagent/consumable/ethanol, 3 * REM * seconds_per_tick * normalise_creation_purity(), FALSE, TRUE)
- affected_mob.adjustToxLoss(-0.2 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
+ if(affected_mob.adjustToxLoss(-0.2 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype))
+ . = UPDATE_MOB_HEALTH
affected_mob.adjust_drunk_effect(-10 * REM * seconds_per_tick * normalise_creation_purity())
- ..()
- . = TRUE
/datum/reagent/medicine/antihol/expose_mob(mob/living/carbon/exposed_carbon, methods=TOUCH, reac_volume)
. = ..()
@@ -1141,33 +1175,35 @@
addiction_types = list(/datum/addiction/stimulants = 4) //0.8 per 2 seconds
/datum/reagent/medicine/stimulants/on_mob_metabolize(mob/living/affected_mob)
- ..()
+ . = ..()
affected_mob.add_movespeed_modifier(/datum/movespeed_modifier/reagent/stimulants)
ADD_TRAIT(affected_mob, TRAIT_BATON_RESISTANCE, type)
/datum/reagent/medicine/stimulants/on_mob_end_metabolize(mob/living/affected_mob)
+ . = ..()
affected_mob.remove_movespeed_modifier(/datum/movespeed_modifier/reagent/stimulants)
REMOVE_TRAIT(affected_mob, TRAIT_BATON_RESISTANCE, type)
- ..()
/datum/reagent/medicine/stimulants/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
if(affected_mob.health < 50 && affected_mob.health > 0)
- affected_mob.adjustOxyLoss(-1 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
- affected_mob.adjustToxLoss(-1 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
- affected_mob.adjustBruteLoss(-1 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype)
- affected_mob.adjustFireLoss(-1 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype)
+ var/need_mob_update
+ need_mob_update += affected_mob.adjustOxyLoss(-1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
+ need_mob_update += affected_mob.adjustToxLoss(-1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)
+ need_mob_update += affected_mob.adjustBruteLoss(-1 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
+ need_mob_update += affected_mob.adjustFireLoss(-1 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
+ if(need_mob_update)
+ . = UPDATE_MOB_HEALTH
affected_mob.AdjustAllImmobility(-60 * REM * seconds_per_tick)
- affected_mob.adjustStaminaLoss(-5 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
- ..()
- . = TRUE
+ affected_mob.adjustStaminaLoss(-5 * REM * seconds_per_tick, updating_stamina = FALSE, required_biotype = affected_biotype)
/datum/reagent/medicine/stimulants/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
if(SPT_PROB(18, seconds_per_tick))
- affected_mob.adjustStaminaLoss(2.5, FALSE, required_biotype = affected_biotype)
- affected_mob.adjustToxLoss(1, FALSE, required_biotype = affected_biotype)
+ affected_mob.adjustStaminaLoss(2.5, updating_stamina = FALSE, required_biotype = affected_biotype)
+ affected_mob.adjustToxLoss(1, updating_health = FALSE, required_biotype = affected_biotype)
affected_mob.losebreath++
- . = TRUE
- ..()
+ return UPDATE_MOB_HEALTH
/datum/reagent/medicine/insulin
name = "Insulin"
@@ -1179,10 +1215,9 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/medicine/insulin/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
- if(affected_mob.AdjustSleeping(-20 * REM * seconds_per_tick))
- . = TRUE
+ affected_mob.AdjustSleeping(-20 * REM * seconds_per_tick)
holder.remove_reagent(/datum/reagent/consumable/sugar, 3 * REM * seconds_per_tick)
- ..()
+ return ..()
//Trek Chems, used primarily by medibots. Only heals a specific damage type, but is very efficient.
@@ -1195,9 +1230,10 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_NO_RANDOM_RECIPE
/datum/reagent/medicine/inaprovaline/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
if(affected_mob.losebreath >= 5)
affected_mob.losebreath -= 5 * REM * seconds_per_tick
- ..()
+ return UPDATE_MOB_HEALTH
/datum/reagent/medicine/regen_jelly
name = "Regenerative Jelly"
@@ -1219,12 +1255,14 @@
exposed_human.set_haircolor(color, update = TRUE)
/datum/reagent/medicine/regen_jelly/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
- affected_mob.adjustBruteLoss(-1.5 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype)
- affected_mob.adjustFireLoss(-1.5 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype)
- affected_mob.adjustOxyLoss(-1.5 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
- affected_mob.adjustToxLoss(-1.5 * REM * seconds_per_tick, FALSE, TRUE, affected_biotype) //heals TOXINLOVERs
- ..()
- . = TRUE
+ . = ..()
+ var/need_mob_update
+ need_mob_update = affected_mob.adjustBruteLoss(-1.5 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
+ need_mob_update += affected_mob.adjustFireLoss(-1.5 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
+ need_mob_update += affected_mob.adjustOxyLoss(-1.5 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
+ need_mob_update += affected_mob.adjustToxLoss(-1.5 * REM * seconds_per_tick, updating_health = FALSE, forced = TRUE, required_biotype = affected_biotype) //heals TOXINLOVERs
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/medicine/syndicate_nanites //Used exclusively by Syndicate medical cyborgs
name = "Restorative Nanites"
@@ -1236,21 +1274,22 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_NO_RANDOM_RECIPE
/datum/reagent/medicine/syndicate_nanites/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
- affected_mob.adjustBruteLoss(-5 * REM * seconds_per_tick, FALSE) //A ton of healing - this is a 50 telecrystal investment.
- affected_mob.adjustFireLoss(-5 * REM * seconds_per_tick, FALSE)
- affected_mob.adjustOxyLoss(-15 * REM * seconds_per_tick, FALSE)
- affected_mob.adjustToxLoss(-5 * REM * seconds_per_tick, FALSE)
- affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, -15 * REM * seconds_per_tick)
- affected_mob.adjustCloneLoss(-3 * REM * seconds_per_tick, FALSE)
- ..()
- . = TRUE
+ . = ..()
+ var/need_mob_update
+ need_mob_update = affected_mob.adjustBruteLoss(-5 * REM * seconds_per_tick, updating_health = FALSE) //A ton of healing - this is a 50 telecrystal investment.
+ need_mob_update += affected_mob.adjustFireLoss(-5 * REM * seconds_per_tick, updating_health = FALSE)
+ need_mob_update += affected_mob.adjustOxyLoss(-15 * REM * seconds_per_tick, updating_health = FALSE)
+ need_mob_update += affected_mob.adjustToxLoss(-5 * REM * seconds_per_tick, updating_health = FALSE)
+ need_mob_update += affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, -15 * REM * seconds_per_tick)
+ need_mob_update += affected_mob.adjustCloneLoss(-3 * REM * seconds_per_tick, updating_health = FALSE)
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/medicine/syndicate_nanites/overdose_process(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) //wtb flavortext messages that hint that you're vomitting up robots
+ . = ..()
if(SPT_PROB(13, seconds_per_tick))
affected_mob.reagents.remove_reagent(type, metabolization_rate*15) // ~5 units at a rate of 0.4 but i wanted a nice number in code
affected_mob.vomit(vomit_flags = VOMIT_CATEGORY_DEFAULT, vomit_type = /obj/effect/decal/cleanable/vomit/nanites, lost_nutrition = 20) // nanite safety protocols make your body expel them to prevent harmies
- ..()
- . = TRUE
/datum/reagent/medicine/earthsblood //Created by ambrosia gaia plants
name = "Earthsblood"
@@ -1263,48 +1302,53 @@
addiction_types = list(/datum/addiction/hallucinogens = 14)
/datum/reagent/medicine/earthsblood/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
- if(current_cycle <= 25) //10u has to be processed before u get into THE FUN ZONE
- affected_mob.adjustBruteLoss(-1 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype)
- affected_mob.adjustFireLoss(-1 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype)
- affected_mob.adjustOxyLoss(-0.5 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
- affected_mob.adjustToxLoss(-0.5 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
- affected_mob.adjustCloneLoss(-0.1 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
- affected_mob.adjustStaminaLoss(-0.5 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
- affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 1 * REM * seconds_per_tick, 150, affected_organ_flags) //This does, after all, come from ambrosia, and the most powerful ambrosia in existence, at that!
+ . = ..()
+ var/need_mob_update
+ if(current_cycle < 25) //10u has to be processed before u get into THE FUN ZONE
+ need_mob_update = affected_mob.adjustBruteLoss(-1 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
+ need_mob_update += affected_mob.adjustFireLoss(-1 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
+ need_mob_update += affected_mob.adjustOxyLoss(-0.5 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
+ need_mob_update += affected_mob.adjustToxLoss(-0.5 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)
+ need_mob_update += affected_mob.adjustCloneLoss(-0.1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)
+ need_mob_update += affected_mob.adjustStaminaLoss(-0.5 * REM * seconds_per_tick, updating_stamina = FALSE, required_biotype = affected_biotype)
+ need_mob_update += affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 1 * REM * seconds_per_tick, 150, affected_organ_flags) //This does, after all, come from ambrosia, and the most powerful ambrosia in existence, at that!
else
- affected_mob.adjustBruteLoss(-5 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) //slow to start, but very quick healing once it gets going
- affected_mob.adjustFireLoss(-5 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype)
- affected_mob.adjustOxyLoss(-3 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
- affected_mob.adjustToxLoss(-3 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
- affected_mob.adjustCloneLoss(-1 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
- affected_mob.adjustStaminaLoss(-3 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
+ need_mob_update = affected_mob.adjustBruteLoss(-5 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) //slow to start, but very quick healing once it gets going
+ need_mob_update += affected_mob.adjustFireLoss(-5 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
+ need_mob_update += affected_mob.adjustOxyLoss(-3 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
+ need_mob_update += affected_mob.adjustToxLoss(-3 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)
+ need_mob_update += affected_mob.adjustCloneLoss(-1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)
+ need_mob_update += affected_mob.adjustStaminaLoss(-3 * REM * seconds_per_tick, updating_stamina = FALSE, required_biotype = affected_biotype)
+ need_mob_update += affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2 * REM * seconds_per_tick, 150, affected_organ_flags)
affected_mob.adjust_jitter_up_to(6 SECONDS * REM * seconds_per_tick, 1 MINUTES)
- affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2 * REM * seconds_per_tick, 150, affected_organ_flags)
if(SPT_PROB(5, seconds_per_tick))
affected_mob.say(return_hippie_line(), forced = /datum/reagent/medicine/earthsblood)
affected_mob.adjust_drugginess_up_to(20 SECONDS * REM * seconds_per_tick, 30 SECONDS * REM * seconds_per_tick)
- ..()
- . = TRUE
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/medicine/earthsblood/on_mob_metabolize(mob/living/affected_mob)
- ..()
+ . = ..()
ADD_TRAIT(affected_mob, TRAIT_PACIFISM, type)
/datum/reagent/medicine/earthsblood/on_mob_end_metabolize(mob/living/affected_mob)
+ . = ..()
REMOVE_TRAIT(affected_mob, TRAIT_PACIFISM, type)
- ..()
/datum/reagent/medicine/earthsblood/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
affected_mob.adjust_hallucinations_up_to(10 SECONDS * REM * seconds_per_tick, 120 SECONDS)
- if(current_cycle > 25)
- affected_mob.adjustToxLoss(4 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
- if(current_cycle > 100) //podpeople get out reeeeeeeeeeeeeeeeeeeee
- affected_mob.adjustToxLoss(6 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
+ var/need_mob_update
+ if(current_cycle > 26)
+ need_mob_update = affected_mob.adjustToxLoss(4 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)
+ if(current_cycle > 101) //podpeople get out reeeeeeeeeeeeeeeeeeeee
+ need_mob_update += affected_mob.adjustToxLoss(6 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)
if(iscarbon(affected_mob))
var/mob/living/carbon/hippie = affected_mob
hippie.gain_trauma(/datum/brain_trauma/severe/pacifism)
- ..()
- . = TRUE
+
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/// Returns a hippie-esque string for the person affected by the reagent to say.
/datum/reagent/medicine/earthsblood/proc/return_hippie_line()
@@ -1330,6 +1374,7 @@
harmful = TRUE
/datum/reagent/medicine/haloperidol/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
for(var/datum/reagent/drug/R in affected_mob.reagents.reagent_list)
affected_mob.reagents.remove_reagent(R.type, 5 * REM * seconds_per_tick)
affected_mob.adjust_drowsiness(4 SECONDS * REM * seconds_per_tick)
@@ -1340,11 +1385,12 @@
if (affected_mob.get_timed_status_effect_duration(/datum/status_effect/hallucination) >= 10 SECONDS)
affected_mob.adjust_hallucinations(-10 SECONDS * REM * seconds_per_tick)
+ var/need_mob_update = FALSE
if(SPT_PROB(10, seconds_per_tick))
- affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 1, 50, affected_organ_flags)
- affected_mob.adjustStaminaLoss(2.5 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
- ..()
- return TRUE
+ need_mob_update += affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 1, 50, affected_organ_flags)
+ need_mob_update += affected_mob.adjustStaminaLoss(2.5 * REM * seconds_per_tick, updating_stamina = FALSE, required_biotype = affected_biotype)
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
//used for changeling's adrenaline power
/datum/reagent/medicine/changelingadrenaline
@@ -1355,29 +1401,29 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_NO_RANDOM_RECIPE
/datum/reagent/medicine/changelingadrenaline/on_mob_life(mob/living/carbon/metabolizer, seconds_per_tick, times_fired)
- ..()
+ . = ..()
metabolizer.AdjustAllImmobility(-20 * REM * seconds_per_tick)
- metabolizer.adjustStaminaLoss(-10 * REM * seconds_per_tick, 0)
+ if(metabolizer.adjustStaminaLoss(-10 * REM * seconds_per_tick, updating_stamina = FALSE))
+ . = UPDATE_MOB_HEALTH
metabolizer.set_jitter_if_lower(20 SECONDS * REM * seconds_per_tick)
metabolizer.set_dizzy_if_lower(20 SECONDS * REM * seconds_per_tick)
- return TRUE
/datum/reagent/medicine/changelingadrenaline/on_mob_metabolize(mob/living/affected_mob)
- ..()
+ . = ..()
affected_mob.add_traits(list(TRAIT_SLEEPIMMUNE, TRAIT_BATON_RESISTANCE), type)
affected_mob.add_movespeed_mod_immunities(type, /datum/movespeed_modifier/damage_slowdown)
/datum/reagent/medicine/changelingadrenaline/on_mob_end_metabolize(mob/living/affected_mob)
- ..()
+ . = ..()
affected_mob.remove_traits(list(TRAIT_SLEEPIMMUNE, TRAIT_BATON_RESISTANCE), type)
affected_mob.remove_movespeed_mod_immunities(type, /datum/movespeed_modifier/damage_slowdown)
affected_mob.remove_status_effect(/datum/status_effect/dizziness)
affected_mob.remove_status_effect(/datum/status_effect/jitter)
/datum/reagent/medicine/changelingadrenaline/overdose_process(mob/living/metabolizer, seconds_per_tick, times_fired)
- metabolizer.adjustToxLoss(1 * REM * seconds_per_tick, FALSE)
- ..()
- return TRUE
+ . = ..()
+ if(metabolizer.adjustToxLoss(1 * REM * seconds_per_tick, updating_health = FALSE))
+ return UPDATE_MOB_HEALTH
/datum/reagent/medicine/changelinghaste
name = "Changeling Haste"
@@ -1387,17 +1433,17 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_NO_RANDOM_RECIPE
/datum/reagent/medicine/changelinghaste/on_mob_metabolize(mob/living/affected_mob)
- ..()
+ . = ..()
affected_mob.add_movespeed_modifier(/datum/movespeed_modifier/reagent/changelinghaste)
/datum/reagent/medicine/changelinghaste/on_mob_end_metabolize(mob/living/affected_mob)
+ . = ..()
affected_mob.remove_movespeed_modifier(/datum/movespeed_modifier/reagent/changelinghaste)
- ..()
/datum/reagent/medicine/changelinghaste/on_mob_life(mob/living/carbon/metabolizer, seconds_per_tick, times_fired)
- metabolizer.adjustToxLoss(2 * REM * seconds_per_tick, FALSE)
- ..()
- return TRUE
+ . = ..()
+ if(metabolizer.adjustToxLoss(2 * REM * seconds_per_tick, updating_health = FALSE))
+ return UPDATE_MOB_HEALTH
/datum/reagent/medicine/higadrite
name = "Higadrite"
@@ -1411,7 +1457,7 @@
ADD_TRAIT(affected_mob, TRAIT_STABLELIVER, type)
/datum/reagent/medicine/higadrite/on_mob_end_metabolize(mob/living/affected_mob)
- ..()
+ . = ..()
REMOVE_TRAIT(affected_mob, TRAIT_STABLELIVER, type)
/datum/reagent/medicine/cordiolis_hepatico
@@ -1422,11 +1468,11 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_NO_RANDOM_RECIPE
/datum/reagent/medicine/cordiolis_hepatico/on_mob_add(mob/living/affected_mob)
- ..()
+ . = ..()
affected_mob.add_traits(list(TRAIT_STABLELIVER, TRAIT_STABLEHEART), type)
/datum/reagent/medicine/cordiolis_hepatico/on_mob_end_metabolize(mob/living/affected_mob)
- ..()
+ . = ..()
affected_mob.remove_traits(list(TRAIT_STABLELIVER, TRAIT_STABLEHEART), type)
/datum/reagent/medicine/muscle_stimulant
@@ -1455,29 +1501,32 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/medicine/modafinil/on_mob_metabolize(mob/living/affected_mob)
+ . = ..()
ADD_TRAIT(affected_mob, TRAIT_SLEEPIMMUNE, type)
- ..()
/datum/reagent/medicine/modafinil/on_mob_end_metabolize(mob/living/affected_mob)
+ . = ..()
REMOVE_TRAIT(affected_mob, TRAIT_SLEEPIMMUNE, type)
- ..()
/datum/reagent/medicine/modafinil/on_mob_life(mob/living/carbon/metabolizer, seconds_per_tick, times_fired)
+ . = ..()
if(!overdosed) // We do not want any effects on OD
overdose_threshold = overdose_threshold + ((rand(-10, 10) / 10) * REM * seconds_per_tick) // for extra fun
metabolizer.AdjustAllImmobility(-5 * REM * seconds_per_tick)
- metabolizer.adjustStaminaLoss(-0.5 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
+ metabolizer.adjustStaminaLoss(-0.5 * REM * seconds_per_tick, updating_stamina = FALSE, required_biotype = affected_biotype)
metabolizer.set_jitter_if_lower(1 SECONDS * REM * seconds_per_tick)
metabolization_rate = 0.005 * REAGENTS_METABOLISM * rand(5, 20) // randomizes metabolism between 0.02 and 0.08 per second
- . = TRUE
- ..()
+ return UPDATE_MOB_HEALTH
/datum/reagent/medicine/modafinil/overdose_start(mob/living/affected_mob)
+ . = ..()
to_chat(affected_mob, span_userdanger("You feel awfully out of breath and jittery!"))
metabolization_rate = 0.025 * REAGENTS_METABOLISM // sets metabolism to 0.005 per second on overdose
/datum/reagent/medicine/modafinil/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
overdose_progress++
+ var/need_mob_update
switch(overdose_progress)
if(1 to 40)
affected_mob.adjust_jitter_up_to(2 SECONDS * REM * seconds_per_tick, 20 SECONDS)
@@ -1485,29 +1534,31 @@
affected_mob.set_dizzy_if_lower(10 SECONDS * REM * seconds_per_tick)
if(SPT_PROB(30, seconds_per_tick))
affected_mob.losebreath++
+ need_mob_update = TRUE
if(41 to 80)
- affected_mob.adjustOxyLoss(0.1 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
- affected_mob.adjustStaminaLoss(0.1 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
+ need_mob_update = affected_mob.adjustOxyLoss(0.1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
+ need_mob_update += affected_mob.adjustStaminaLoss(0.1 * REM * seconds_per_tick, updating_stamina = FALSE, required_biotype = affected_biotype)
affected_mob.adjust_jitter_up_to(2 SECONDS * REM * seconds_per_tick, 40 SECONDS)
affected_mob.adjust_stutter_up_to(2 SECONDS * REM * seconds_per_tick, 40 SECONDS)
affected_mob.set_dizzy_if_lower(20 SECONDS * REM * seconds_per_tick)
if(SPT_PROB(30, seconds_per_tick))
affected_mob.losebreath++
+ need_mob_update = TRUE
if(SPT_PROB(10, seconds_per_tick))
to_chat(affected_mob, span_userdanger("You have a sudden fit!"))
affected_mob.emote("moan")
affected_mob.Paralyze(20) // you should be in a bad spot at this point unless epipen has been used
if(81)
to_chat(affected_mob, span_userdanger("You feel too exhausted to continue!")) // at this point you will eventually die unless you get charcoal
- affected_mob.adjustOxyLoss(0.1 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
- affected_mob.adjustStaminaLoss(0.1 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
+ need_mob_update = affected_mob.adjustOxyLoss(0.1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
+ need_mob_update += affected_mob.adjustStaminaLoss(0.1 * REM * seconds_per_tick, updating_stamina = FALSE, required_biotype = affected_biotype)
if(82 to INFINITY)
REMOVE_TRAIT(affected_mob, TRAIT_SLEEPIMMUNE, type)
affected_mob.Sleeping(100 * REM * seconds_per_tick)
- affected_mob.adjustOxyLoss(1.5 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
- affected_mob.adjustStaminaLoss(1.5 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
- ..()
- return TRUE
+ need_mob_update += affected_mob.adjustOxyLoss(1.5 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
+ need_mob_update += affected_mob.adjustStaminaLoss(1.5 * REM * seconds_per_tick, updating_stamina = FALSE, required_biotype = affected_biotype)
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/medicine/psicodine
name = "Psicodine"
@@ -1520,28 +1571,27 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/medicine/psicodine/on_mob_metabolize(mob/living/affected_mob)
- ..()
+ . = ..()
ADD_TRAIT(affected_mob, TRAIT_FEARLESS, type)
/datum/reagent/medicine/psicodine/on_mob_end_metabolize(mob/living/affected_mob)
+ . = ..()
REMOVE_TRAIT(affected_mob, TRAIT_FEARLESS, type)
- ..()
/datum/reagent/medicine/psicodine/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
affected_mob.adjust_jitter(-12 SECONDS * REM * seconds_per_tick)
affected_mob.adjust_dizzy(-12 SECONDS * REM * seconds_per_tick)
affected_mob.adjust_confusion(-6 SECONDS * REM * seconds_per_tick)
affected_mob.disgust = max(affected_mob.disgust - (6 * REM * seconds_per_tick), 0)
if(affected_mob.mob_mood != null && affected_mob.mob_mood.sanity <= SANITY_NEUTRAL) // only take effect if in negative sanity and then...
affected_mob.mob_mood.set_sanity(min(affected_mob.mob_mood.sanity + (5 * REM * seconds_per_tick), SANITY_NEUTRAL)) // set minimum to prevent unwanted spiking over neutral
- ..()
- . = TRUE
/datum/reagent/medicine/psicodine/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
affected_mob.adjust_hallucinations_up_to(10 SECONDS * REM * seconds_per_tick, 120 SECONDS)
- affected_mob.adjustToxLoss(1 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
- ..()
- . = TRUE
+ if(affected_mob.adjustToxLoss(1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype))
+ return UPDATE_MOB_HEALTH
/datum/reagent/medicine/metafactor
name = "Mitogen Metabolism Factor"
@@ -1555,12 +1605,13 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/medicine/metafactor/overdose_start(mob/living/carbon/affected_mob)
+ . = ..()
metabolization_rate = 2 * REAGENTS_METABOLISM
/datum/reagent/medicine/metafactor/overdose_process(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
if(SPT_PROB(13, seconds_per_tick))
affected_mob.vomit(VOMIT_CATEGORY_DEFAULT)
- ..()
/datum/reagent/medicine/silibinin
name = "Silibinin"
@@ -1571,9 +1622,8 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/medicine/silibinin/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
- affected_mob.adjustOrganLoss(ORGAN_SLOT_LIVER, -2 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)//Add a chance to cure liver trauma once implemented.
- ..()
- . = TRUE
+ if(affected_mob.adjustOrganLoss(ORGAN_SLOT_LIVER, -2 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)) // Add a chance to cure liver trauma once implemented.
+ return UPDATE_MOB_HEALTH
/datum/reagent/medicine/polypyr //This is intended to be an ingredient in advanced chems.
name = "Polypyrylium Oligomers"
@@ -1587,9 +1637,11 @@
/datum/reagent/medicine/polypyr/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) //I wanted a collection of small positive effects, this is as hard to obtain as coniine after all.
. = ..()
- affected_mob.adjustOrganLoss(ORGAN_SLOT_LUNGS, -0.25 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)
- affected_mob.adjustBruteLoss(-0.35 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype)
- return TRUE
+ var/need_mob_update
+ need_mob_update = affected_mob.adjustOrganLoss(ORGAN_SLOT_LUNGS, -0.25 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)
+ need_mob_update += affected_mob.adjustBruteLoss(-0.35 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/medicine/polypyr/expose_mob(mob/living/carbon/human/exposed_human, methods=TOUCH, reac_volume)
. = ..()
@@ -1600,9 +1652,9 @@
exposed_human.update_body_parts()
/datum/reagent/medicine/polypyr/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired)
- affected_mob.adjustOrganLoss(ORGAN_SLOT_LUNGS, 0.5 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)
- ..()
- . = TRUE
+ . = ..()
+ if(affected_mob.adjustOrganLoss(ORGAN_SLOT_LUNGS, 0.5 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags))
+ return UPDATE_MOB_HEALTH
/datum/reagent/medicine/granibitaluri
name = "Granibitaluri" //achieve "GRANular" amounts of C2
@@ -1615,16 +1667,19 @@
/datum/reagent/medicine/granibitaluri/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
var/healamount = max(0.5 - round(0.01 * (affected_mob.getBruteLoss() + affected_mob.getFireLoss()), 0.1), 0) //base of 0.5 healing per cycle and loses 0.1 healing for every 10 combined brute/burn damage you have
- affected_mob.adjustBruteLoss(-healamount * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype)
- affected_mob.adjustFireLoss(-healamount * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype)
- ..()
- . = TRUE
+ var/need_mob_update
+ need_mob_update = affected_mob.adjustBruteLoss(-healamount * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
+ need_mob_update += affected_mob.adjustFireLoss(-healamount * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/medicine/granibitaluri/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired)
- . = TRUE
- affected_mob.adjustOrganLoss(ORGAN_SLOT_LIVER, 0.2 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)
- affected_mob.adjustToxLoss(0.2 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) //Only really deadly if you eat over 100u
- ..()
+ . = ..()
+ var/need_mob_update
+ need_mob_update = affected_mob.adjustOrganLoss(ORGAN_SLOT_LIVER, 0.2 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)
+ need_mob_update += affected_mob.adjustToxLoss(0.2 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype) //Only really deadly if you eat over 100u
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
// helps bleeding wounds clot faster
/datum/reagent/medicine/coagulant
@@ -1643,15 +1698,15 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/medicine/coagulant/on_mob_metabolize(mob/living/affected_mob)
+ . = ..()
ADD_TRAIT(affected_mob, TRAIT_COAGULATING, /datum/reagent/medicine/coagulant)
if(ishuman(affected_mob))
var/mob/living/carbon/human/blood_boy = affected_mob
blood_boy.physiology?.bleed_mod *= passive_bleed_modifier
- return ..()
-
/datum/reagent/medicine/coagulant/on_mob_end_metabolize(mob/living/affected_mob)
+ . = ..()
REMOVE_TRAIT(affected_mob, TRAIT_COAGULATING, /datum/reagent/medicine/coagulant)
if(was_working)
@@ -1660,8 +1715,6 @@
var/mob/living/carbon/human/blood_boy = affected_mob
blood_boy.physiology?.bleed_mod /= passive_bleed_modifier
- return ..()
-
/datum/reagent/medicine/coagulant/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
. = ..()
if(!affected_mob.blood_volume || !affected_mob.all_wounds)
@@ -1690,19 +1743,21 @@
if(SPT_PROB(7.5, seconds_per_tick))
affected_mob.losebreath += rand(2, 4)
- affected_mob.adjustOxyLoss(rand(1, 3), required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
+ affected_mob.adjustOxyLoss(rand(1, 3), updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
if(prob(30))
to_chat(affected_mob, span_danger("You can feel your blood clotting up in your veins!"))
else if(prob(10))
to_chat(affected_mob, span_userdanger("You feel like your blood has stopped moving!"))
- affected_mob.adjustOxyLoss(rand(3, 4), required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
+ affected_mob.adjustOxyLoss(rand(3, 4) * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
if(prob(50))
var/obj/item/organ/internal/lungs/our_lungs = affected_mob.get_organ_slot(ORGAN_SLOT_LUNGS)
- our_lungs.apply_organ_damage(1)
+ our_lungs.apply_organ_damage(1 * REM * seconds_per_tick)
else
var/obj/item/organ/internal/heart/our_heart = affected_mob.get_organ_slot(ORGAN_SLOT_HEART)
- our_heart.apply_organ_damage(1)
+ our_heart.apply_organ_damage(1 * REM * seconds_per_tick)
+
+ return UPDATE_MOB_HEALTH
// i googled "natural coagulant" and a couple of results came up for banana peels, so after precisely 30 more seconds of research, i now dub grinding banana peels good for your blood
/datum/reagent/medicine/coagulant/banana_peel
@@ -1745,11 +1800,11 @@
ph = 10.6
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
-/datum/reagent/medicine/ondansetron/on_mob_life(mob/living/carbon/M, seconds_per_tick, times_fired)
+/datum/reagent/medicine/ondansetron/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
. = ..()
if(SPT_PROB(8, seconds_per_tick))
- M.adjust_drowsiness(2 SECONDS * REM * seconds_per_tick)
- if(SPT_PROB(15, seconds_per_tick) && !M.getStaminaLoss())
- M.adjustStaminaLoss(10)
- . = TRUE
- M.adjust_disgust(-10 * REM * seconds_per_tick)
+ affected_mob.adjust_drowsiness(2 SECONDS * REM * seconds_per_tick)
+ if(SPT_PROB(15, seconds_per_tick) && !affected_mob.getStaminaLoss())
+ if(affected_mob.adjustStaminaLoss(10 * REM * seconds_per_tick, updating_stamina = FALSE))
+ . = UPDATE_MOB_HEALTH
+ affected_mob.adjust_disgust(-10 * REM * seconds_per_tick)
diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm
index dddf966be72..5e1d7b849e6 100644
--- a/code/modules/reagents/chemistry/reagents/other_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm
@@ -369,7 +369,7 @@
mytray.myseed?.adjust_instability(round(volume * 0.15))
/datum/reagent/water/holywater/on_mob_metabolize(mob/living/affected_mob)
- ..()
+ . = ..()
ADD_TRAIT(affected_mob, TRAIT_HOLY, type)
/datum/reagent/water/holywater/on_mob_add(mob/living/affected_mob, amount)
@@ -378,8 +378,8 @@
data["misc"] = 0
/datum/reagent/water/holywater/on_mob_end_metabolize(mob/living/affected_mob)
+ . = ..()
REMOVE_TRAIT(affected_mob, TRAIT_HOLY, type)
- ..()
/datum/reagent/water/holywater/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume)
. = ..()
@@ -387,8 +387,7 @@
to_chat(exposed_mob, span_userdanger("A vile holiness begins to spread its shining tendrils through your mind, purging the Geometer of Blood's influence!"))
/datum/reagent/water/holywater/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
- if(affected_mob.blood_volume)
- affected_mob.blood_volume += 0.1 * REM * seconds_per_tick // water is good for you!
+ . = ..()
if(!data)
data = list("misc" = 0)
@@ -415,9 +414,11 @@
affected_mob.Unconscious(100)
affected_mob.remove_status_effect(/datum/status_effect/jitter)
affected_mob.remove_status_effect(/datum/status_effect/speech/stutter)
- holder.remove_reagent(type, volume) // maybe this is a little too perfect and a max() cap on the statuses would be better??
+ if(holder)
+ holder.remove_reagent(type, volume) // maybe this is a little too perfect and a max() cap on the statuses would be better??
return
- holder.remove_reagent(type, 1 * REAGENTS_METABOLISM * seconds_per_tick) //fixed consumption to prevent balancing going out of whack
+ if(holder)
+ holder.remove_reagent(type, 1 * REAGENTS_METABOLISM * seconds_per_tick) //fixed consumption to prevent balancing going out of whack
/datum/reagent/water/holywater/expose_turf(turf/exposed_turf, reac_volume)
. = ..()
@@ -484,24 +485,27 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/fuel/unholywater/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
+ var/need_mob_update = FALSE
if(IS_CULTIST(affected_mob))
affected_mob.adjust_drowsiness(-10 SECONDS * REM * seconds_per_tick)
affected_mob.AdjustAllImmobility(-40 * REM * seconds_per_tick)
- affected_mob.adjustStaminaLoss(-10 * REM * seconds_per_tick, 0)
- affected_mob.adjustToxLoss(-2 * REM * seconds_per_tick, 0)
- affected_mob.adjustOxyLoss(-2 * REM * seconds_per_tick, 0)
- affected_mob.adjustBruteLoss(-2 * REM * seconds_per_tick, 0)
- affected_mob.adjustFireLoss(-2 * REM * seconds_per_tick, 0)
+ need_mob_update += affected_mob.adjustStaminaLoss(-10 * REM * seconds_per_tick, updating_stamina = FALSE)
+ need_mob_update += affected_mob.adjustToxLoss(-2 * REM * seconds_per_tick, updating_health = FALSE)
+ need_mob_update += affected_mob.adjustOxyLoss(-2 * REM * seconds_per_tick, updating_health = FALSE)
+ need_mob_update += affected_mob.adjustBruteLoss(-2 * REM * seconds_per_tick, updating_health = FALSE)
+ need_mob_update += affected_mob.adjustFireLoss(-2 * REM * seconds_per_tick, updating_health = FALSE)
+ need_mob_update = TRUE
if(ishuman(affected_mob) && affected_mob.blood_volume < BLOOD_VOLUME_NORMAL)
affected_mob.blood_volume += 3 * REM * seconds_per_tick
else // Will deal about 90 damage when 50 units are thrown
- affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 3 * REM * seconds_per_tick, 150)
- affected_mob.adjustToxLoss(1 * REM * seconds_per_tick, 0)
- affected_mob.adjustFireLoss(1 * REM * seconds_per_tick, 0)
- affected_mob.adjustOxyLoss(1 * REM * seconds_per_tick, 0)
- affected_mob.adjustBruteLoss(1 * REM * seconds_per_tick, 0)
- ..()
- return TRUE
+ need_mob_update += affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 3 * REM * seconds_per_tick, 150)
+ need_mob_update += affected_mob.adjustToxLoss(1 * REM * seconds_per_tick, updating_health = FALSE)
+ need_mob_update += affected_mob.adjustFireLoss(1 * REM * seconds_per_tick, updating_health = FALSE)
+ need_mob_update += affected_mob.adjustOxyLoss(1 * REM * seconds_per_tick, updating_health = FALSE)
+ need_mob_update += affected_mob.adjustBruteLoss(1 * REM * seconds_per_tick, updating_health = FALSE)
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/hellwater //if someone has this in their system they've really pissed off an eldrich god
name = "Hell Water"
@@ -511,13 +515,17 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_NO_RANDOM_RECIPE
/datum/reagent/hellwater/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
affected_mob.set_fire_stacks(min(affected_mob.fire_stacks + (1.5 * seconds_per_tick), 5))
affected_mob.ignite_mob() //Only problem with igniting people is currently the commonly available fire suits make you immune to being on fire
- affected_mob.adjustToxLoss(0.5*seconds_per_tick, 0)
- affected_mob.adjustFireLoss(0.5*seconds_per_tick, 0) //Hence the other damages... ain't I a bastard?
+ var/need_mob_update
+ need_mob_update = affected_mob.adjustToxLoss(0.5*seconds_per_tick, updating_health = FALSE)
+ need_mob_update += affected_mob.adjustFireLoss(0.5*seconds_per_tick, updating_health = FALSE) //Hence the other damages... ain't I a bastard?
affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2.5*seconds_per_tick, 150)
- holder.remove_reagent(type, 0.5*seconds_per_tick)
- return TRUE
+ if(holder)
+ holder.remove_reagent(type, 0.5*seconds_per_tick)
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/medicine/omnizine/godblood
name = "Godblood"
@@ -629,8 +637,8 @@
if((methods & INGEST) && show_message)
to_chat(exposed_mob, span_notice("That tasted horrible."))
-
/datum/reagent/spraytan/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
metabolization_rate = 1 * REAGENTS_METABOLISM
if(ishuman(affected_mob))
@@ -656,13 +664,18 @@
affected_mob.visible_message("[affected_mob] flexes [affected_mob.p_their()] arms.")
if(SPT_PROB(5, seconds_per_tick))
affected_mob.say(pick("Shit was SO cash.", "You are everything bad in the world.", "What sports do you play, other than 'jack off to naked drawn Japanese people?'", "Don???t be a stranger. Just hit me with your best shot.", "My name is John and I hate every single one of you."), forced = /datum/reagent/spraytan)
- ..()
- return
#define MUT_MSG_IMMEDIATE 1
#define MUT_MSG_EXTENDED 2
#define MUT_MSG_ABOUT2TURN 3
+/// the current_cycle threshold / iterations needed before one can transform
+#define CYCLES_TO_TURN 20
+/// the cycle at which 'immediate' mutation text begins displaying
+#define CYCLES_MSG_IMMEDIATE 6
+/// the cycle at which 'extended' mutation text begins displaying
+#define CYCLES_MSG_EXTENDED 16
+
/datum/reagent/mutationtoxin
name = "Stable Mutation Toxin"
description = "A humanizing toxin."
@@ -675,21 +688,20 @@
"Your limbs begin to take on a different shape." = MUT_MSG_EXTENDED,
"Your appendages begin morphing." = MUT_MSG_EXTENDED,
"You feel as though you're about to change at any moment!" = MUT_MSG_ABOUT2TURN)
- var/cycles_to_turn = 20 //the current_cycle threshold / iterations needed before one can transform
/datum/reagent/mutationtoxin/on_mob_life(mob/living/carbon/human/affected_mob, seconds_per_tick, times_fired)
- . = TRUE
+ . = ..()
if(!istype(affected_mob))
return
- if(!(affected_mob.dna?.species) || !(affected_mob.mob_biotypes & MOB_ORGANIC))
+ if(!(affected_mob.dna?.species) || !(affected_mob.mob_biotypes & affected_biotype))
return
if(SPT_PROB(5, seconds_per_tick))
var/list/pick_ur_fav = list()
var/filter = NONE
- if(current_cycle <= (cycles_to_turn*0.3))
+ if(current_cycle <= CYCLES_MSG_IMMEDIATE)
filter = MUT_MSG_IMMEDIATE
- else if(current_cycle <= (cycles_to_turn*0.8))
+ else if(current_cycle <= CYCLES_MSG_EXTENDED)
filter = MUT_MSG_EXTENDED
else
filter = MUT_MSG_ABOUT2TURN
@@ -699,14 +711,15 @@
pick_ur_fav += i
to_chat(affected_mob, span_warning("[pick(pick_ur_fav)]"))
- if(current_cycle >= cycles_to_turn)
+ if(current_cycle >= CYCLES_TO_TURN)
var/datum/species/species_type = race
//affected_mob.set_species(species_type) //ORIGINAL
affected_mob.set_species(species_type, TRUE, FALSE, null, null, null, null, TRUE) //SKYRAT EDIT CHANGE - CUSTOMIZATION
holder.del_reagent(type)
to_chat(affected_mob, span_warning("You've become \a [lowertext(initial(species_type.name))]!"))
return
- ..()
+
+ return ..()
/datum/reagent/mutationtoxin/classic //The one from plasma on green slimes
name = "Mutation Toxin"
@@ -769,14 +782,14 @@
//affected_mob.set_species(species_type) //ORIGINAL
affected_mob.set_species(species_type, TRUE, FALSE, null, null, null, null, TRUE, TRUE) //SKYRAT EDIT CHANGE - CUSTOMIZATION
holder.del_reagent(type)
- return TRUE
- if(current_cycle >= cycles_to_turn) //overwrite since we want subtypes of jelly
+ return UPDATE_MOB_HEALTH
+ if(current_cycle >= CYCLES_TO_TURN) //overwrite since we want subtypes of jelly
var/datum/species/species_type = pick(subtypesof(race))
//affected_mob.set_species(species_type) //ORIGINAL
affected_mob.set_species(species_type, TRUE, FALSE, null, null, null, null, TRUE, TRUE) //SKYRAT EDIT CHANGE - CUSTOMIZATION
holder.del_reagent(type)
to_chat(affected_mob, span_warning("You've become \a [initial(species_type.name)]!"))
- return TRUE
+ return UPDATE_MOB_HEALTH
return ..()
/datum/reagent/mutationtoxin/golem
@@ -849,6 +862,10 @@
#undef MUT_MSG_EXTENDED
#undef MUT_MSG_ABOUT2TURN
+#undef CYCLES_TO_TURN
+#undef CYCLES_MSG_IMMEDIATE
+#undef CYCLES_MSG_EXTENDED
+
/datum/reagent/mulligan
name = "Mulligan Toxin"
description = "This toxin will rapidly change the DNA of humanoid beings. Commonly used by Syndicate spies and assassins in need of an emergency ID change."
@@ -858,7 +875,7 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/mulligan/on_mob_life(mob/living/carbon/human/affected_mob, seconds_per_tick, times_fired)
- ..()
+ . = ..()
if (!istype(affected_mob))
return
to_chat(affected_mob, span_warning("You grit your teeth in pain as your body rapidly mutates!"))
@@ -900,10 +917,10 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/serotrotium/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
if(ishuman(affected_mob))
if(SPT_PROB(3.5, seconds_per_tick))
affected_mob.emote(pick("twitch","drool","moan","gasp"))
- ..()
/datum/reagent/oxygen
name = "Oxygen"
@@ -978,13 +995,13 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/mercury/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
if(!HAS_TRAIT(src, TRAIT_IMMOBILIZED) && !isspaceturf(affected_mob.loc))
step(affected_mob, pick(GLOB.cardinals))
if(SPT_PROB(3.5, seconds_per_tick))
affected_mob.emote(pick("twitch","drool","moan"))
- affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.5*seconds_per_tick)
- ..()
- return TRUE
+ if(affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.5*seconds_per_tick))
+ return UPDATE_MOB_HEALTH
/datum/reagent/sulfur
name = "Sulfur"
@@ -1052,9 +1069,9 @@
mytray.adjust_weedlevel(-rand(1, 4))
/datum/reagent/fluorine/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
- affected_mob.adjustToxLoss(0.5*REM*seconds_per_tick, 0)
- . = TRUE
- ..()
+ . = ..()
+ if(affected_mob.adjustToxLoss(0.5*REM*seconds_per_tick, updating_health = FALSE))
+ . = TRUE
/datum/reagent/sodium
name = "Sodium"
@@ -1090,11 +1107,11 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/lithium/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
if(!HAS_TRAIT(affected_mob, TRAIT_IMMOBILIZED) && !isspaceturf(affected_mob.loc) && isturf(affected_mob.loc))
step(affected_mob, pick(GLOB.cardinals))
if(SPT_PROB(2.5, seconds_per_tick))
affected_mob.emote(pick("twitch","drool","moan"))
- ..()
/datum/reagent/glycerol
name = "Glycerol"
@@ -1134,9 +1151,9 @@
ph = 6
/datum/reagent/iron/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
if(affected_mob.blood_volume < BLOOD_VOLUME_NORMAL)
affected_mob.blood_volume += 0.25 * seconds_per_tick
- ..()
/datum/reagent/gold
name = "Gold"
@@ -1170,9 +1187,9 @@
var/tox_damage = 0.5
/datum/reagent/uranium/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
- affected_mob.adjustToxLoss(tox_damage * seconds_per_tick * REM)
- ..()
- return TRUE
+ . = ..()
+ if(affected_mob.adjustToxLoss(tox_damage * seconds_per_tick * REM, updating_health = FALSE))
+ return UPDATE_MOB_HEALTH
/datum/reagent/uranium/expose_turf(turf/exposed_turf, reac_volume)
. = ..()
@@ -1216,12 +1233,12 @@
do_teleport(exposed_mob, get_turf(exposed_mob), (reac_volume / 5), asoundin = 'sound/effects/phasein.ogg', channel = TELEPORT_CHANNEL_BLUESPACE) //4 tiles per crystal
/datum/reagent/bluespace/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
if(current_cycle > 10 && SPT_PROB(7.5, seconds_per_tick))
to_chat(affected_mob, span_warning("You feel unstable..."))
affected_mob.set_jitter_if_lower(2 SECONDS)
current_cycle = 1
addtimer(CALLBACK(affected_mob, TYPE_PROC_REF(/mob/living, bluespace_shuffle)), 30)
- ..()
/mob/living/proc/bluespace_shuffle()
do_teleport(src, get_turf(src), 5, asoundin = 'sound/effects/phasein.ogg', channel = TELEPORT_CHANNEL_BLUESPACE)
@@ -1268,9 +1285,9 @@
exposed_mob.adjust_fire_stacks(reac_volume / 10)
/datum/reagent/fuel/on_mob_life(mob/living/carbon/victim, seconds_per_tick, times_fired)
- victim.adjustToxLoss(0.5 * seconds_per_tick, FALSE, required_biotype = affected_biotype)
- ..()
- return TRUE
+ . = ..()
+ if(victim.adjustToxLoss(0.5 * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype))
+ return UPDATE_MOB_HEALTH
/datum/reagent/fuel/expose_turf(turf/exposed_turf, reac_volume)
. = ..()
@@ -1337,11 +1354,13 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/space_cleaner/ez_clean/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
- affected_mob.adjustBruteLoss(1.665*seconds_per_tick)
- affected_mob.adjustFireLoss(1.665*seconds_per_tick)
- affected_mob.adjustToxLoss(1.665*seconds_per_tick)
- ..()
- return TRUE
+ . = ..()
+ var/need_mob_update
+ need_mob_update = affected_mob.adjustBruteLoss(1.665*seconds_per_tick, updating_health = FALSE)
+ need_mob_update += affected_mob.adjustFireLoss(1.665*seconds_per_tick, updating_health = FALSE)
+ need_mob_update += affected_mob.adjustToxLoss(1.665*seconds_per_tick, updating_health = FALSE)
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/space_cleaner/ez_clean/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume)
. = ..()
@@ -1359,6 +1378,7 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/cryptobiolin/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
affected_mob.set_dizzy_if_lower(2 SECONDS)
// Cryptobiolin adjusts the mob's confusion down to 20 seconds if it's higher,
@@ -1370,8 +1390,6 @@
else if(confusion_left > 20 SECONDS)
affected_mob.set_confusion(20 SECONDS)
- ..()
-
/datum/reagent/impedrezene
name = "Impedrezene"
description = "Impedrezene is a narcotic that impedes one's ability by slowing down the higher brain cell functions."
@@ -1382,6 +1400,7 @@
addiction_types = list(/datum/addiction/opioids = 10)
/datum/reagent/impedrezene/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
affected_mob.adjust_jitter(-5 SECONDS * seconds_per_tick)
. = FALSE
if(SPT_PROB(55, seconds_per_tick))
@@ -1391,7 +1410,6 @@
affected_mob.adjust_drowsiness(6 SECONDS)
if(SPT_PROB(5, seconds_per_tick))
affected_mob.emote("drool")
- ..()
/datum/reagent/cyborg_mutation_nanomachines
name = "Nanomachines"
@@ -1542,13 +1560,13 @@
exposed_mob.adjust_drowsiness(drowsiness_to_apply)
/datum/reagent/nitrous_oxide/on_mob_metabolize(mob/living/affected_mob)
+ . = ..()
if(!HAS_TRAIT(affected_mob, TRAIT_COAGULATING)) //IF the mob does not have a coagulant in them, we add the blood mess trait to make the bleed quicker
ADD_TRAIT(affected_mob, TRAIT_BLOODY_MESS, type)
- return ..()
/datum/reagent/nitrous_oxide/on_mob_end_metabolize(mob/living/affected_mob)
+ . = ..()
REMOVE_TRAIT(affected_mob, TRAIT_BLOODY_MESS, type)
- return ..()
/datum/reagent/nitrous_oxide/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
affected_mob.adjust_drowsiness(4 SECONDS * REM * seconds_per_tick)
@@ -1706,10 +1724,10 @@
ph = 3
/datum/reagent/plantnutriment/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
if(SPT_PROB(tox_prob, seconds_per_tick))
- affected_mob.adjustToxLoss(1, FALSE, required_biotype = affected_biotype)
- . = TRUE
- ..()
+ if(affected_mob.adjustToxLoss(1, updating_health = FALSE, required_biotype = affected_biotype))
+ return UPDATE_MOB_HEALTH
/datum/reagent/plantnutriment/eznutriment
name = "E-Z Nutrient"
@@ -2214,7 +2232,7 @@
/datum/reagent/concentrated_barbers_aid/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
. = ..()
- if(current_cycle > 20 / creation_purity)
+ if(current_cycle > 21 / creation_purity)
if(!ishuman(affected_mob))
return
var/mob/living/carbon/human/human_mob = affected_mob
@@ -2362,9 +2380,9 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/royal_bee_jelly/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
if(SPT_PROB(1, seconds_per_tick))
affected_mob.say(pick("Bzzz...","BZZ BZZ","Bzzzzzzzzzzz..."), forced = "royal bee jelly")
- ..()
//Misc reagents
@@ -2396,8 +2414,8 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_NO_RANDOM_RECIPE
/datum/reagent/magillitis/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
- ..()
- if((ishuman(affected_mob)) && current_cycle >= 10)
+ . = ..()
+ if((ishuman(affected_mob)) && current_cycle > 10)
affected_mob.gorillize()
/datum/reagent/growthserum
@@ -2409,6 +2427,7 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/growthserum/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
var/newsize = current_size
switch(volume)
if(0 to 19)
@@ -2424,12 +2443,11 @@
affected_mob.update_transform(newsize/current_size)
current_size = newsize
- ..()
/datum/reagent/growthserum/on_mob_end_metabolize(mob/living/affected_mob)
+ . = ..()
affected_mob.update_transform(RESIZE_DEFAULT_SIZE/current_size)
current_size = RESIZE_DEFAULT_SIZE
- ..()
/datum/reagent/plastic_polymers
name = "Plastic Polymers"
@@ -2491,12 +2509,12 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/pax/on_mob_metabolize(mob/living/affected_mob)
- ..()
+ . = ..()
ADD_TRAIT(affected_mob, TRAIT_PACIFISM, type)
/datum/reagent/pax/on_mob_end_metabolize(mob/living/affected_mob)
+ . = ..()
REMOVE_TRAIT(affected_mob, TRAIT_PACIFISM, type)
- ..()
/datum/reagent/bz_metabolites
name = "BZ Metabolites"
@@ -2507,19 +2525,19 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_NO_RANDOM_RECIPE
/datum/reagent/bz_metabolites/on_mob_metabolize(mob/living/ling)
- ..()
+ . = ..()
ADD_TRAIT(ling, CHANGELING_HIVEMIND_MUTE, type)
/datum/reagent/bz_metabolites/on_mob_end_metabolize(mob/living/ling)
- ..()
+ . = ..()
REMOVE_TRAIT(ling, CHANGELING_HIVEMIND_MUTE, type)
/datum/reagent/bz_metabolites/on_mob_life(mob/living/carbon/target, seconds_per_tick, times_fired)
+ . = ..()
if(target.mind)
var/datum/antagonist/changeling/changeling = target.mind.has_antag_datum(/datum/antagonist/changeling)
if(changeling)
- changeling.adjust_chemicals(-4 * REM * seconds_per_tick) //SKYRAT EDIT - BZ-BUFF-VS-LING - ORIGINAL: changeling.adjust_chemicals(-2 * REM * delta_time)
- return ..()
+ changeling.adjust_chemicals(-4 * REM * seconds_per_tick) //SKYRAT EDIT - BZ-BUFF-VS-LING - ORIGINAL: changeling.adjust_chemicals(-2 * REM * seconds_per_tick)
/datum/reagent/pax/peaceborg
name = "Synthpax"
@@ -2550,14 +2568,14 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_NO_RANDOM_RECIPE
/datum/reagent/peaceborg/tire/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
var/healthcomp = (100 - affected_mob.health) //DOES NOT ACCOUNT FOR ADMINBUS THINGS THAT MAKE YOU HAVE MORE THAN 200/210 HEALTH, OR SOMETHING OTHER THAN A HUMAN PROCESSING THIS.
. = FALSE
if(affected_mob.getStaminaLoss() < (45 - healthcomp)) //At 50 health you would have 200 - 150 health meaning 50 compensation. 60 - 50 = 10, so would only do 10-19 stamina.)
- affected_mob.adjustStaminaLoss(10 * REM * seconds_per_tick)
- . = TRUE
+ if(affected_mob.adjustStaminaLoss(10 * REM * seconds_per_tick, updating_stamina = FALSE))
+ . = UPDATE_MOB_HEALTH
if(SPT_PROB(16, seconds_per_tick))
to_chat(affected_mob, "You should sit down and take a rest...")
- ..()
/datum/reagent/gondola_mutation_toxin
name = "Tranquility"
@@ -2595,13 +2613,14 @@
desc = "It smells like a carcass, and doesn't look much better."
/datum/reagent/yuck/on_mob_add(mob/living/affected_mob)
- . = ..()
if(HAS_TRAIT(affected_mob, TRAIT_NOHUNGER)) //they can't puke
holder.del_reagent(type)
+ return ..()
#define YUCK_PUKE_CYCLES 3 // every X cycle is a puke
#define YUCK_PUKES_TO_STUN 3 // hit this amount of pukes in a row to start stunning
/datum/reagent/yuck/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
if(!yuck_cycle)
if(SPT_PROB(4, seconds_per_tick))
var/dread = pick("Something is moving in your stomach...", \
@@ -2613,19 +2632,19 @@
var/yuck_cycles = current_cycle - yuck_cycle
if(yuck_cycles % YUCK_PUKE_CYCLES == 0)
if(yuck_cycles >= YUCK_PUKE_CYCLES * YUCK_PUKES_TO_STUN)
- holder.remove_reagent(type, 5)
+ if(holder)
+ holder.remove_reagent(type, 5)
var/passable_flags = (MOB_VOMIT_MESSAGE | MOB_VOMIT_HARM)
if(yuck_cycles >= (YUCK_PUKE_CYCLES * YUCK_PUKES_TO_STUN))
passable_flags |= MOB_VOMIT_STUN
affected_mob.vomit(vomit_flags = passable_flags, lost_nutrition = rand(14, 26))
- if(holder)
- return ..()
+
#undef YUCK_PUKE_CYCLES
#undef YUCK_PUKES_TO_STUN
/datum/reagent/yuck/on_mob_end_metabolize(mob/living/affected_mob)
+ . = ..()
yuck_cycle = 0 // reset vomiting
- return ..()
/datum/reagent/yuck/on_transfer(atom/A, methods=TOUCH, trans_volume)
if((methods & INGEST) || !iscarbon(A))
@@ -2724,10 +2743,11 @@
addtimer(CALLBACK(exposed_obj, PROC_REF(_RemoveElement), list(/datum/element/forced_gravity, 0)), volume * time_multiplier, TIMER_UNIQUE|TIMER_OVERRIDE)
/datum/reagent/gravitum/on_mob_metabolize(mob/living/affected_mob)
+ . = ..()
affected_mob.AddElement(/datum/element/forced_gravity, 0) //0 is the gravity, and in this case weightless
- return ..()
/datum/reagent/gravitum/on_mob_end_metabolize(mob/living/affected_mob)
+ . = ..()
affected_mob.RemoveElement(/datum/element/forced_gravity, 0)
/datum/reagent/cellulose
@@ -2751,6 +2771,7 @@
var/significant = FALSE
/datum/reagent/determination/on_mob_end_metabolize(mob/living/carbon/affected_mob)
+ . = ..()
if(significant)
var/stam_crash = 0
for(var/thing in affected_mob.all_wounds)
@@ -2758,9 +2779,9 @@
stam_crash += (W.severity + 1) * 3 // spike of 3 stam damage per wound severity (moderate = 6, severe = 9, critical = 12) when the determination wears off if it was a combat rush
affected_mob.adjustStaminaLoss(stam_crash)
affected_mob.remove_status_effect(/datum/status_effect/determined)
- ..()
/datum/reagent/determination/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
if(!significant && volume >= WOUND_DETERMINATION_SEVERE)
significant = TRUE
affected_mob.apply_status_effect(/datum/status_effect/determined) // in addition to the slight healing, limping cooldowns are divided by 4 during the combat high
@@ -2772,8 +2793,8 @@
var/obj/item/bodypart/wounded_part = W.limb
if(wounded_part)
wounded_part.heal_damage(0.25 * REM * seconds_per_tick, 0.25 * REM * seconds_per_tick)
- affected_mob.adjustStaminaLoss(-0.25 * REM * seconds_per_tick) // the more wounds, the more stamina regen
- ..()
+ if(affected_mob.adjustStaminaLoss(-0.25 * REM * seconds_per_tick, updating_stamina = FALSE)) // the more wounds, the more stamina regen
+ return UPDATE_MOB_HEALTH
// unholy water, but for heretics.
// why couldn't they have both just used the same reagent?
@@ -2791,24 +2812,26 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_NO_RANDOM_RECIPE
/datum/reagent/eldritch/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired)
+ . = ..()
+ var/need_mob_update = FALSE
if(IS_HERETIC(drinker))
drinker.adjust_drowsiness(-10 * REM * seconds_per_tick)
drinker.AdjustAllImmobility(-40 * REM * seconds_per_tick)
- drinker.adjustStaminaLoss(-10 * REM * seconds_per_tick, FALSE)
- drinker.adjustToxLoss(-2 * REM * seconds_per_tick, FALSE, forced = TRUE)
- drinker.adjustOxyLoss(-2 * REM * seconds_per_tick, FALSE)
- drinker.adjustBruteLoss(-2 * REM * seconds_per_tick, FALSE)
- drinker.adjustFireLoss(-2 * REM * seconds_per_tick, FALSE)
+ need_mob_update += drinker.adjustStaminaLoss(-10 * REM * seconds_per_tick, updating_stamina = FALSE)
+ need_mob_update += drinker.adjustToxLoss(-2 * REM * seconds_per_tick, updating_health = FALSE, forced = TRUE)
+ need_mob_update += drinker.adjustOxyLoss(-2 * REM * seconds_per_tick, updating_health = FALSE)
+ need_mob_update += drinker.adjustBruteLoss(-2 * REM * seconds_per_tick, updating_health = FALSE)
+ need_mob_update += drinker.adjustFireLoss(-2 * REM * seconds_per_tick, updating_health = FALSE)
if(drinker.blood_volume < BLOOD_VOLUME_NORMAL)
drinker.blood_volume += 3 * REM * seconds_per_tick
else
- drinker.adjustOrganLoss(ORGAN_SLOT_BRAIN, 3 * REM * seconds_per_tick, 150)
- drinker.adjustToxLoss(2 * REM * seconds_per_tick, FALSE)
- drinker.adjustFireLoss(2 * REM * seconds_per_tick, FALSE)
- drinker.adjustOxyLoss(2 * REM * seconds_per_tick, FALSE)
- drinker.adjustBruteLoss(2 * REM * seconds_per_tick, FALSE)
- ..()
- return TRUE
+ need_mob_update = drinker.adjustOrganLoss(ORGAN_SLOT_BRAIN, 3 * REM * seconds_per_tick, 150)
+ need_mob_update += drinker.adjustToxLoss(2 * REM * seconds_per_tick, updating_health = FALSE)
+ need_mob_update += drinker.adjustFireLoss(2 * REM * seconds_per_tick, updating_health = FALSE)
+ need_mob_update += drinker.adjustOxyLoss(2 * REM * seconds_per_tick, updating_health = FALSE)
+ need_mob_update += drinker.adjustBruteLoss(2 * REM * seconds_per_tick, updating_health = FALSE)
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/universal_indicator
name = "Universal Indicator"
@@ -2854,10 +2877,11 @@
desc = "Bottoms up...?"
/datum/reagent/ants/on_mob_life(mob/living/carbon/victim, seconds_per_tick)
+ . = ..()
victim.adjustBruteLoss(max(0.1, round((ant_damage * 0.025),0.1))) //Scales with time. Roughly 32 brute with 100u.
ant_damage++
if(ant_damage < 5) // Makes ant food a little more appetizing, since you won't be screaming as much.
- return ..()
+ return
if(SPT_PROB(5, seconds_per_tick))
if(SPT_PROB(5, seconds_per_tick)) //Super rare statement
victim.say("AUGH NO NOT THE ANTS! NOT THE ANTS! AAAAUUGH THEY'RE IN MY EYES! MY EYES! AUUGH!!", forced = /datum/reagent/ants)
@@ -2866,14 +2890,12 @@
if(SPT_PROB(15, seconds_per_tick))
victim.emote("scream")
if(SPT_PROB(2, seconds_per_tick)) // Stuns, but purges ants.
- victim.vomit(rand(5,10), FALSE, TRUE, 1, TRUE, FALSE, purge_ratio = 1)
- ..()
- return TRUE
+ victim.vomit(VOMIT_CATEGORY_DEFAULT, lost_nutrition = rand(5,10), purge_ratio = 1)
/datum/reagent/ants/on_mob_end_metabolize(mob/living/living_anthill)
+ . = ..()
ant_damage = 0
to_chat(living_anthill, "You feel like the last of the ants are out of your system.")
- return ..()
/datum/reagent/ants/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume)
. = ..()
@@ -2918,9 +2940,9 @@
metabolization_rate = 0.4 * REAGENTS_METABOLISM
/datum/reagent/lead/on_mob_life(mob/living/carbon/victim)
- victim.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.5)
- ..()
- return TRUE
+ . = ..()
+ if(victim.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.5))
+ return UPDATE_MOB_HEALTH
//The main feedstock for kronkaine production, also a shitty stamina healer.
/datum/reagent/kronkus_extract
@@ -2932,10 +2954,12 @@
addiction_types = list(/datum/addiction/stimulants = 5)
/datum/reagent/kronkus_extract/on_mob_life(mob/living/carbon/kronkus_enjoyer)
- ..()
- kronkus_enjoyer.adjustOrganLoss(ORGAN_SLOT_HEART, 0.1)
- kronkus_enjoyer.adjustStaminaLoss(-2, FALSE)
- return TRUE
+ . = ..()
+ var/need_mob_update
+ need_mob_update = kronkus_enjoyer.adjustOrganLoss(ORGAN_SLOT_HEART, 0.1)
+ need_mob_update += kronkus_enjoyer.adjustStaminaLoss(-2, updating_stamina = FALSE)
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/brimdust
name = "Brimdust"
@@ -2947,7 +2971,8 @@
/datum/reagent/brimdust/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
. = ..()
- return affected_mob.adjustFireLoss((ispodperson(affected_mob) ? -1 : 1) * seconds_per_tick)
+ if(affected_mob.adjustFireLoss((ispodperson(affected_mob) ? -1 : 1 * seconds_per_tick), updating_health = FALSE))
+ return UPDATE_MOB_HEALTH
/datum/reagent/brimdust/on_hydroponics_apply(obj/machinery/hydroponics/mytray, mob/user)
mytray.adjust_weedlevel(-1)
@@ -2975,14 +3000,15 @@
. = ..()
metabolizer.add_mood_event(name, /datum/mood_event/love_reagent)
-/datum/reagent/love/on_mob_delete(mob/living/deleted_from)
+/datum/reagent/love/on_mob_delete(mob/living/affected_mob)
. = ..()
// When we exit the system we'll leave the moodlet based on the amount we had
var/duration_of_moodlet = current_cycle * 20 SECONDS
- deleted_from.clear_mood_event(name)
- deleted_from.add_mood_event(name, /datum/mood_event/love_reagent, duration_of_moodlet)
+ affected_mob.clear_mood_event(name)
+ affected_mob.add_mood_event(name, /datum/mood_event/love_reagent, duration_of_moodlet)
/datum/reagent/love/overdose_process(mob/living/metabolizer, seconds_per_tick, times_fired)
+ . = ..()
var/mob/living/carbon/carbon_metabolizer = metabolizer
if(!istype(carbon_metabolizer) || !carbon_metabolizer.can_heartattack() || carbon_metabolizer.undergoing_cardiac_arrest())
metabolizer.reagents.del_reagent(type)
@@ -3016,6 +3042,8 @@
affected_mob.add_mood_event("hauntium_spirits", /datum/mood_event/hauntium_spirits, name) //8 minutes of mood debuff
/datum/reagent/hauntium/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
+
if(affected_mob.mob_biotypes & MOB_UNDEAD || HAS_MIND_TRAIT(affected_mob, TRAIT_MORBID)) //if morbid or undead,acts like an addiction-less drug
affected_mob.remove_status_effect(/datum/status_effect/jitter)
affected_mob.AdjustStun(-50 * REM * seconds_per_tick)
@@ -3023,10 +3051,13 @@
affected_mob.AdjustUnconscious(-50 * REM * seconds_per_tick)
affected_mob.AdjustParalyzed(-50 * REM * seconds_per_tick)
affected_mob.AdjustImmobilized(-50 * REM * seconds_per_tick)
- ..()
else
- affected_mob.adjustOrganLoss(ORGAN_SLOT_HEART, REM * seconds_per_tick) //1 heart damage per tick
+ if(affected_mob.adjustOrganLoss(ORGAN_SLOT_HEART, REM * seconds_per_tick)) //1 heart damage per tick
+ . = UPDATE_MOB_HEALTH
if(SPT_PROB(10, seconds_per_tick))
affected_mob.emote(pick("twitch","choke","shiver","gag"))
- ..()
- return TRUE
+
+// The same as gold just with a slower metabolism rate, to make using the Hand of Midas easier.
+/datum/reagent/gold/cursed
+ name = "Cursed Gold"
+ metabolization_rate = 0.2 * REAGENTS_METABOLISM
diff --git a/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm b/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm
index 6f99273ad4e..2db3682ef21 100644
--- a/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm
@@ -13,9 +13,9 @@
exposed_turf.AddComponent(/datum/component/thermite, reac_volume)
/datum/reagent/thermite/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
- affected_mob.adjustFireLoss(1 * REM * seconds_per_tick, 0)
- ..()
- return TRUE
+ . = ..()
+ if(affected_mob.adjustFireLoss(1 * REM * seconds_per_tick, updating_health = FALSE))
+ return UPDATE_MOB_HEALTH
/datum/reagent/nitroglycerin
name = "Nitroglycerin"
@@ -47,10 +47,10 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/clf3/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
affected_mob.adjust_fire_stacks(2 * REM * seconds_per_tick)
- affected_mob.adjustFireLoss(0.3 * max(affected_mob.fire_stacks, 1) * REM * seconds_per_tick, 0)
- ..()
- return TRUE
+ if(affected_mob.adjustFireLoss(0.3 * max(affected_mob.fire_stacks, 1) * REM * seconds_per_tick, updating_health = FALSE))
+ return UPDATE_MOB_HEALTH
/datum/reagent/clf3/expose_turf(turf/exposed_turf, reac_volume)
. = ..()
@@ -177,10 +177,10 @@
exposed_mob.ignite_mob()
/datum/reagent/phlogiston/on_mob_life(mob/living/carbon/metabolizer, seconds_per_tick, times_fired)
+ . = ..()
metabolizer.adjust_fire_stacks(1 * REM * seconds_per_tick)
- metabolizer.adjustFireLoss(0.3 * max(metabolizer.fire_stacks, 0.15) * REM * seconds_per_tick, 0)
- ..()
- return TRUE
+ if(metabolizer.adjustFireLoss(0.3 * max(metabolizer.fire_stacks, 0.15) * REM * seconds_per_tick, updating_health = FALSE))
+ return UPDATE_MOB_HEALTH
/datum/reagent/napalm
name = "Napalm"
@@ -201,9 +201,8 @@
mytray.adjust_weedlevel(-rand(5,9)) //At least give them a small reward if they bother.
/datum/reagent/napalm/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
affected_mob.adjust_fire_stacks(1 * REM * seconds_per_tick)
- ..()
- return TRUE
/datum/reagent/napalm/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume)
. = ..()
@@ -249,6 +248,7 @@
metabolization_rate = 0.05 * REM //slower consumption when dead
/datum/reagent/cryostylane/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
metabolization_rate = 0.25 * REM//faster consumption when alive
if(affected_mob.reagents.has_reagent(/datum/reagent/oxygen))
affected_mob.reagents.remove_reagent(/datum/reagent/oxygen, 0.5 * REM * seconds_per_tick)
@@ -256,7 +256,6 @@
if(ishuman(affected_mob))
var/mob/living/carbon/human/humi = affected_mob
humi.adjust_coretemperature(-15 * REM * seconds_per_tick)
- ..()
/datum/reagent/cryostylane/expose_turf(turf/exposed_turf, reac_volume)
. = ..()
@@ -284,9 +283,9 @@
holder.remove_reagent(/datum/reagent/oxygen, 0.5 * REM * seconds_per_tick)
affected_mob.adjust_bodytemperature(15 * REM * seconds_per_tick)
if(ishuman(affected_mob))
- var/mob/living/carbon/human/humi = affected_mob
- humi.adjust_coretemperature(15 * REM * seconds_per_tick)
- ..()
+ var/mob/living/carbon/human/affected_human = affected_mob
+ affected_human.adjust_coretemperature(15 * REM * seconds_per_tick)
+ return ..()
/datum/reagent/pyrosium/burn(datum/reagents/holder)
if(holder.has_reagent(/datum/reagent/oxygen))
@@ -306,12 +305,12 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/teslium/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
shock_timer++
if(shock_timer >= rand(5, 30)) //Random shocks are wildly unpredictable
shock_timer = 0
affected_mob.electrocute_act(rand(5, 20), "Teslium in their body", 1, SHOCK_NOGLOVES) //SHOCK_NOGLOVES because it's caused from INSIDE of you
playsound(affected_mob, SFX_SPARKS, 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
- ..()
/datum/reagent/teslium/on_mob_metabolize(mob/living/carbon/human/affected_mob)
. = ..()
@@ -334,15 +333,16 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/teslium/energized_jelly/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
if(isjellyperson(affected_mob))
shock_timer = 0 //immune to shocks
affected_mob.AdjustAllImmobility(-40 *REM * seconds_per_tick)
- affected_mob.adjustStaminaLoss(-2 * REM * seconds_per_tick, 0)
+ if(affected_mob.adjustStaminaLoss(-2 * REM * seconds_per_tick, updating_stamina = FALSE))
+ . = UPDATE_MOB_HEALTH
if(is_species(affected_mob, /datum/species/jelly/luminescent))
var/mob/living/carbon/human/affected_human = affected_mob
var/datum/species/jelly/luminescent/slime_species = affected_human.dna.species
slime_species.extract_cooldown = max(slime_species.extract_cooldown - (2 SECONDS * REM * seconds_per_tick), 0)
- ..()
/datum/reagent/firefighting_foam
name = "Firefighting Foam"
diff --git a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm
index d655698646c..7f4acabef6e 100644
--- a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm
@@ -23,10 +23,10 @@
mytray.adjust_toxic(round(volume * 2))
/datum/reagent/toxin/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
if(toxpwr && affected_mob.health > health_required)
- affected_mob.adjustToxLoss(toxpwr * REM * normalise_creation_purity() * seconds_per_tick, FALSE, required_biotype = affected_biotype)
- . = TRUE
- ..()
+ if(affected_mob.adjustToxLoss(toxpwr * REM * normalise_creation_purity() * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype))
+ return UPDATE_MOB_HEALTH
/datum/reagent/toxin/amatoxin
name = "Amatoxin"
@@ -64,8 +64,9 @@
exposed_mob.domutcheck()
/datum/reagent/toxin/mutagen/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
- . = affected_mob.adjustToxLoss(0.5 * seconds_per_tick * REM, required_biotype = affected_biotype)
- return ..() || .
+ . = ..()
+ if(affected_mob.adjustToxLoss(0.5 * seconds_per_tick * REM, required_biotype = affected_biotype))
+ return UPDATE_MOB_HEALTH
/datum/reagent/toxin/mutagen/on_hydroponics_apply(obj/machinery/hydroponics/mytray, mob/user)
mytray.mutation_roll(user)
@@ -100,14 +101,16 @@
/datum/reagent/toxin/plasma/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
if(holder.has_reagent(/datum/reagent/medicine/epinephrine))
holder.remove_reagent(/datum/reagent/medicine/epinephrine, 2 * REM * seconds_per_tick)
+ . = ..()
affected_mob.adjustPlasma(20 * REM * seconds_per_tick)
- return ..()
/datum/reagent/toxin/plasma/on_mob_metabolize(mob/living/carbon/affected_mob)
+ . = ..()
if(HAS_TRAIT(affected_mob, TRAIT_PLASMA_LOVER_METABOLISM)) // sometimes mobs can temporarily metabolize plasma (e.g. plasma fixation disease symptom)
toxpwr = 0
/datum/reagent/toxin/plasma/on_mob_end_metabolize(mob/living/carbon/affected_mob)
+ . = ..()
toxpwr = initial(toxpwr)
/// Handles plasma boiling.
@@ -154,18 +157,20 @@
/datum/reagent/toxin/hot_ice/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
if(holder.has_reagent(/datum/reagent/medicine/epinephrine))
holder.remove_reagent(/datum/reagent/medicine/epinephrine, 2 * REM * seconds_per_tick)
+ . = ..()
affected_mob.adjustPlasma(20 * REM * seconds_per_tick)
affected_mob.adjust_bodytemperature(-7 * TEMPERATURE_DAMAGE_COEFFICIENT * REM * seconds_per_tick, affected_mob.get_body_temp_normal())
if(ishuman(affected_mob))
var/mob/living/carbon/human/humi = affected_mob
humi.adjust_coretemperature(-7 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, affected_mob.get_body_temp_normal())
- return ..()
/datum/reagent/toxin/hot_ice/on_mob_metabolize(mob/living/carbon/affected_mob)
+ . = ..()
if(HAS_TRAIT(affected_mob, TRAIT_PLASMA_LOVER_METABOLISM))
toxpwr = 0
/datum/reagent/toxin/hot_ice/on_mob_end_metabolize(mob/living/carbon/affected_mob)
+ . = ..()
toxpwr = initial(toxpwr)
/datum/reagent/toxin/lexorin
@@ -180,22 +185,20 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/toxin/lexorin/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
- . = TRUE
-
- if(HAS_TRAIT(affected_mob, TRAIT_NOBREATH))
- . = FALSE
-
- if(.)
+ . = ..()
+ if(!HAS_TRAIT(affected_mob, TRAIT_NOBREATH))
affected_mob.adjustOxyLoss(5 * REM * normalise_creation_purity() * seconds_per_tick, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
affected_mob.losebreath += 2 * REM * normalise_creation_purity() * seconds_per_tick
+ . = UPDATE_MOB_HEALTH
if(SPT_PROB(10, seconds_per_tick))
affected_mob.emote("gasp")
- ..()
/datum/reagent/toxin/lexorin/on_mob_metabolize(mob/living/affected_mob)
+ . = ..()
RegisterSignal(affected_mob, COMSIG_CARBON_ATTEMPT_BREATHE, PROC_REF(block_breath))
/datum/reagent/toxin/lexorin/on_mob_end_metabolize(mob/living/affected_mob)
+ . = ..()
UnregisterSignal(affected_mob, COMSIG_CARBON_ATTEMPT_BREATHE, PROC_REF(block_breath))
/datum/reagent/toxin/lexorin/proc/block_breath(mob/living/source)
@@ -213,14 +216,14 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/toxin/slimejelly/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
if(SPT_PROB(5, seconds_per_tick))
to_chat(affected_mob, span_danger("Your insides are burning!"))
- affected_mob.adjustToxLoss(rand(20, 60), FALSE, required_biotype = affected_biotype)
- . = TRUE
+ if(affected_mob.adjustToxLoss(rand(20, 60), updating_health = FALSE, required_biotype = affected_biotype))
+ return UPDATE_MOB_HEALTH
else if(SPT_PROB(23, seconds_per_tick))
- affected_mob.heal_bodypart_damage(5)
- . = TRUE
- ..()
+ if(affected_mob.heal_bodypart_damage(5))
+ return UPDATE_MOB_HEALTH
/datum/reagent/toxin/carpotoxin
name = "Carpotoxin"
@@ -252,9 +255,9 @@
if((data?["method"] & INGEST) && holder_mob.stat != DEAD)
holder_mob.fakedeath(type)
-/datum/reagent/toxin/zombiepowder/on_mob_end_metabolize(mob/living/holder_mob)
- holder_mob.cure_fakedeath(type)
- return ..()
+/datum/reagent/toxin/zombiepowder/on_mob_end_metabolize(mob/living/affected_mob)
+ . = ..()
+ affected_mob.cure_fakedeath(type)
/datum/reagent/toxin/zombiepowder/on_transfer(atom/target_atom, methods, trans_volume)
. = ..()
@@ -265,21 +268,22 @@
zombiepowder.data["method"] |= INGEST
/datum/reagent/toxin/zombiepowder/on_mob_life(mob/living/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
if(HAS_TRAIT(affected_mob, TRAIT_FAKEDEATH) && HAS_TRAIT(affected_mob, TRAIT_DEATHCOMA))
- ..()
- return TRUE
+ return
+ var/need_mob_update
switch(current_cycle)
- if(1 to 5)
+ if(2 to 6)
affected_mob.adjust_confusion(1 SECONDS * REM * seconds_per_tick)
affected_mob.adjust_drowsiness(2 SECONDS * REM * seconds_per_tick)
affected_mob.adjust_slurring(6 SECONDS * REM * seconds_per_tick)
- if(5 to 8)
- affected_mob.adjustStaminaLoss(40 * REM * seconds_per_tick, 0)
- if(9 to INFINITY)
+ if(6 to 9)
+ need_mob_update = affected_mob.adjustStaminaLoss(40 * REM * seconds_per_tick, updating_stamina = FALSE)
+ if(10 to INFINITY)
if(affected_mob.stat != DEAD)
affected_mob.fakedeath(type)
- ..()
- return TRUE
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/toxin/ghoulpowder
name = "Ghoul Powder"
@@ -294,17 +298,17 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/toxin/ghoulpowder/on_mob_metabolize(mob/living/affected_mob)
- ..()
+ . = ..()
ADD_TRAIT(affected_mob, TRAIT_FAKEDEATH, type)
/datum/reagent/toxin/ghoulpowder/on_mob_end_metabolize(mob/living/affected_mob)
+ . = ..()
REMOVE_TRAIT(affected_mob, TRAIT_FAKEDEATH, type)
- ..()
/datum/reagent/toxin/ghoulpowder/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
- affected_mob.adjustOxyLoss(1 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
- ..()
- . = TRUE
+ . = ..()
+ if(affected_mob.adjustOxyLoss(1 * REM * seconds_per_tick, FALSE, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type))
+ return UPDATE_MOB_HEALTH
/datum/reagent/toxin/mindbreaker
name = "Mindbreaker Toxin"
@@ -319,25 +323,23 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
addiction_types = list(/datum/addiction/hallucinogens = 18) //7.2 per 2 seconds
-
-/datum/reagent/toxin/mindbreaker/on_mob_metabolize(mob/living/metabolizer)
+/datum/reagent/toxin/mindbreaker/on_mob_metabolize(mob/living/affected_mob)
. = ..()
- ADD_TRAIT(metabolizer, TRAIT_RDS_SUPPRESSED, type)
+ ADD_TRAIT(affected_mob, TRAIT_RDS_SUPPRESSED, type)
-/datum/reagent/toxin/mindbreaker/on_mob_end_metabolize(mob/living/metabolizer)
+/datum/reagent/toxin/mindbreaker/on_mob_end_metabolize(mob/living/affected_mob)
. = ..()
- REMOVE_TRAIT(metabolizer, TRAIT_RDS_SUPPRESSED, type)
+ REMOVE_TRAIT(affected_mob, TRAIT_RDS_SUPPRESSED, type)
-/datum/reagent/toxin/mindbreaker/on_mob_life(mob/living/carbon/metabolizer, seconds_per_tick, times_fired)
+/datum/reagent/toxin/mindbreaker/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
// mindbreaker toxin assuages hallucinations in those plagued with it, mentally
- if(metabolizer.has_trauma_type(/datum/brain_trauma/mild/hallucinations))
- metabolizer.remove_status_effect(/datum/status_effect/hallucination)
+ if(affected_mob.has_trauma_type(/datum/brain_trauma/mild/hallucinations))
+ affected_mob.remove_status_effect(/datum/status_effect/hallucination)
// otherwise it creates hallucinations. truly a miracle medicine.
else
- metabolizer.adjust_hallucinations(10 SECONDS * REM * seconds_per_tick)
-
- return ..()
+ affected_mob.adjust_hallucinations(10 SECONDS * REM * seconds_per_tick)
/datum/reagent/toxin/plantbgone
name = "Plant-B-Gone"
@@ -374,8 +376,8 @@
var/damage = min(round(0.4 * reac_volume, 0.1), 10)
if(exposed_mob.mob_biotypes & MOB_PLANT)
// spray bottle emits 5u so it's dealing ~15 dmg per spray
- exposed_mob.adjustToxLoss(damage * 20, required_biotype = affected_biotype)
- return
+ if(exposed_mob.adjustToxLoss(damage * 20, required_biotype = affected_biotype))
+ return
if(!(methods & VAPOR) || !iscarbon(exposed_mob))
return
@@ -409,8 +411,9 @@
AddElement(/datum/element/bugkiller_reagent)
/datum/reagent/toxin/pestkiller/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
- . = affected_mob.adjustToxLoss(2 * toxpwr * REM * seconds_per_tick, updating_health = FALSE, required_biotype = MOB_BUG)
- return ..() || .
+ . = ..()
+ if(affected_mob.adjustToxLoss(2 * toxpwr * REM * seconds_per_tick, updating_health = FALSE, required_biotype = MOB_BUG))
+ return UPDATE_MOB_HEALTH
//Pest Spray
/datum/reagent/toxin/pestkiller/on_hydroponics_apply(obj/machinery/hydroponics/mytray, mob/user)
@@ -438,10 +441,10 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_NO_RANDOM_RECIPE
/datum/reagent/toxin/spore/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
affected_mob.damageoverlaytemp = 60
affected_mob.update_damage_hud()
affected_mob.set_eye_blur_if_lower(6 SECONDS * REM * seconds_per_tick)
- return ..()
/datum/reagent/toxin/spore_burning
name = "Burning Spore Toxin"
@@ -453,9 +456,9 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_NO_RANDOM_RECIPE
/datum/reagent/toxin/spore_burning/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
affected_mob.adjust_fire_stacks(2 * REM * seconds_per_tick)
affected_mob.ignite_mob()
- return ..()
/datum/reagent/toxin/chloralhydrate
name = "Chloral Hydrate"
@@ -472,18 +475,17 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/toxin/chloralhydrate/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
switch(current_cycle)
- if(1 to 10)
+ if(2 to 11)
affected_mob.adjust_confusion(2 SECONDS * REM * normalise_creation_purity() * seconds_per_tick)
affected_mob.adjust_drowsiness(4 SECONDS * REM * normalise_creation_purity() * seconds_per_tick)
- if(10 to 50)
+ if(11 to 51)
affected_mob.Sleeping(40 * REM * normalise_creation_purity() * seconds_per_tick)
- . = TRUE
- if(51 to INFINITY)
+ if(52 to INFINITY)
affected_mob.Sleeping(40 * REM * normalise_creation_purity() * seconds_per_tick)
- affected_mob.adjustToxLoss(1 * (current_cycle - 50) * REM * normalise_creation_purity() * seconds_per_tick, FALSE, required_biotype = affected_biotype)
- . = TRUE
- ..()
+ if(affected_mob.adjustToxLoss(1 * (current_cycle - 51) * REM * normalise_creation_purity() * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype))
+ return UPDATE_MOB_HEALTH
/datum/reagent/toxin/fakebeer //disguised as normal beer for use by emagged brobots
name = "B33r"
@@ -507,14 +509,14 @@
icon_state = initial(copy_from.icon_state)
/datum/reagent/toxin/fakebeer/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
switch(current_cycle)
- if(1 to 50)
+ if(2 to 51)
affected_mob.Sleeping(40 * REM * seconds_per_tick)
- if(51 to INFINITY)
+ if(52 to INFINITY)
affected_mob.Sleeping(40 * REM * seconds_per_tick)
- affected_mob.adjustToxLoss(1 * (current_cycle - 50) * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
- . = TRUE
- return ..() || .
+ if(affected_mob.adjustToxLoss(1 * (current_cycle - 50) * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype))
+ return UPDATE_MOB_HEALTH
/datum/reagent/toxin/coffeepowder
name = "Coffee Grounds"
@@ -558,9 +560,9 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/toxin/mutetoxin/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
// Gain approximately 12 seconds * creation purity seconds of silence every metabolism tick.
affected_mob.set_silence_if_lower(6 SECONDS * REM * normalise_creation_purity() * seconds_per_tick)
- return ..()
/datum/reagent/toxin/staminatoxin
name = "Tirizene"
@@ -572,10 +574,10 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/toxin/staminatoxin/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
- affected_mob.adjustStaminaLoss(data * REM * seconds_per_tick, 0)
+ . = ..()
+ if(affected_mob.adjustStaminaLoss(data * REM * seconds_per_tick, updating_stamina = FALSE))
+ . = UPDATE_MOB_HEALTH
data = max(data - 1, 3)
- ..()
- . = TRUE
/datum/reagent/toxin/polonium
name = "Polonium"
@@ -587,12 +589,12 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_NO_RANDOM_RECIPE
/datum/reagent/toxin/polonium/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
if (!HAS_TRAIT(affected_mob, TRAIT_IRRADIATED) && SSradiation.can_irradiate_basic(affected_mob))
affected_mob.AddComponent(/datum/component/irradiated)
else
- affected_mob.adjustToxLoss(1 * REM * seconds_per_tick, required_biotype = affected_biotype)
- . = TRUE
- return ..() || .
+ if(affected_mob.adjustToxLoss(1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype))
+ return UPDATE_MOB_HEALTH
/datum/reagent/toxin/histamine
name = "Histamine"
@@ -606,6 +608,7 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_NO_RANDOM_RECIPE
/datum/reagent/toxin/histamine/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
if(SPT_PROB(30, seconds_per_tick))
switch(pick(1, 2, 3, 4))
if(1)
@@ -618,16 +621,17 @@
if(4)
if(prob(75))
to_chat(affected_mob, span_danger("You scratch at an itch."))
- affected_mob.adjustBruteLoss(2*REM, FALSE, required_bodytype = affected_bodytype)
- . = TRUE
- ..()
+ if(affected_mob.adjustBruteLoss(2* REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype))
+ return UPDATE_MOB_HEALTH
/datum/reagent/toxin/histamine/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired)
- affected_mob.adjustOxyLoss(2 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
- affected_mob.adjustBruteLoss(2 * REM * seconds_per_tick, FALSE, FALSE, BODYTYPE_ORGANIC)
- affected_mob.adjustToxLoss(2 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
- ..()
- . = TRUE
+ . = ..()
+ var/need_mob_update
+ need_mob_update = affected_mob.adjustOxyLoss(2 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
+ need_mob_update += affected_mob.adjustBruteLoss(2 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)
+ need_mob_update += affected_mob.adjustToxLoss(2 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/toxin/formaldehyde
name = "Formaldehyde"
@@ -646,14 +650,13 @@
/datum/reagent/toxin/formaldehyde/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
var/obj/item/organ/internal/liver/liver = affected_mob.get_organ_slot(ORGAN_SLOT_LIVER)
if(liver && HAS_TRAIT(liver, TRAIT_CORONER_METABOLISM)) //mmmm, the forbidden pickle juice
- affected_mob.adjustToxLoss(-1, FALSE, required_biotype = affected_biotype) //it counteracts its own toxin damage.
- . = TRUE
- return ..()
+ if(affected_mob.adjustToxLoss(-1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)) //it counteracts its own toxin damage.
+ return UPDATE_MOB_HEALTH
+ return
else if(SPT_PROB(2.5, seconds_per_tick))
holder.add_reagent(/datum/reagent/toxin/histamine, pick(5,15))
holder.remove_reagent(/datum/reagent/toxin/formaldehyde, 1.2)
- else
- return ..()
+ return ..()
/datum/reagent/toxin/venom
name = "Venom"
@@ -670,20 +673,23 @@
var/newsize = 1.1 * RESIZE_DEFAULT_SIZE
affected_mob.update_transform(newsize/current_size)
current_size = newsize
-
toxpwr = 0.1 * volume
- affected_mob.adjustBruteLoss((0.3 * volume) * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype)
- . = TRUE
+
+ if(affected_mob.adjustBruteLoss((0.3 * volume) * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype))
+ . = UPDATE_MOB_HEALTH
+
+ // chance to either decay into histamine or go the normal route of toxin metabolization
if(SPT_PROB(8, seconds_per_tick))
+ current_cycle++
holder.add_reagent(/datum/reagent/toxin/histamine, pick(5, 10))
holder.remove_reagent(/datum/reagent/toxin/venom, 1.1)
else
- ..()
+ return ..() || .
/datum/reagent/toxin/venom/on_mob_end_metabolize(mob/living/affected_mob)
+ . = ..()
affected_mob.update_transform(RESIZE_DEFAULT_SIZE/current_size)
current_size = RESIZE_DEFAULT_SIZE
- ..()
/datum/reagent/toxin/fentanyl
name = "Fentanyl"
@@ -699,15 +705,17 @@
addiction_types = list(/datum/addiction/opioids = 25)
/datum/reagent/toxin/fentanyl/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
- affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 3 * REM * normalise_creation_purity() * seconds_per_tick, 150)
+ . = ..()
+ var/need_mob_update
+ need_mob_update = affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 3 * REM * normalise_creation_purity() * seconds_per_tick, 150)
if(affected_mob.toxloss <= 60)
- affected_mob.adjustToxLoss(1 * REM * normalise_creation_purity() * seconds_per_tick, FALSE, required_biotype = affected_biotype)
- if(current_cycle >= 4)
+ need_mob_update += affected_mob.adjustToxLoss(1 * REM * normalise_creation_purity() * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)
+ if(current_cycle > 4)
affected_mob.add_mood_event("smacked out", /datum/mood_event/narcotic_heavy, name)
- if(current_cycle >= 18)
+ if(current_cycle > 18)
affected_mob.Sleeping(40 * REM * normalise_creation_purity() * seconds_per_tick)
- ..()
- return TRUE
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/toxin/cyanide
name = "Cyanide"
@@ -722,13 +730,17 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/toxin/cyanide/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
+ var/need_mob_update = FALSE
if(SPT_PROB(2.5, seconds_per_tick))
affected_mob.losebreath += 1
+ need_mob_update = TRUE
if(SPT_PROB(4, seconds_per_tick))
to_chat(affected_mob, span_danger("You feel horrendously weak!"))
affected_mob.Stun(40)
- affected_mob.adjustToxLoss(2*REM * normalise_creation_purity(), FALSE, required_biotype = affected_biotype)
- return ..()
+ need_mob_update += affected_mob.adjustToxLoss(2*REM * normalise_creation_purity(), updating_health = FALSE, required_biotype = affected_biotype)
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/toxin/bad_food
name = "Bad Food"
@@ -755,23 +767,26 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/toxin/itching_powder/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ var/need_mob_update = FALSE
if(SPT_PROB(8, seconds_per_tick))
to_chat(affected_mob, span_danger("You scratch at your head."))
- affected_mob.adjustBruteLoss(0.2*REM, FALSE, required_bodytype = affected_bodytype)
- . = TRUE
+ need_mob_update += affected_mob.adjustBruteLoss(0.2*REM, FALSE, required_bodytype = affected_bodytype)
if(SPT_PROB(8, seconds_per_tick))
to_chat(affected_mob, span_danger("You scratch at your leg."))
- affected_mob.adjustBruteLoss(0.2*REM, FALSE, required_bodytype = affected_bodytype)
- . = TRUE
+ need_mob_update += affected_mob.adjustBruteLoss(0.2*REM, FALSE, required_bodytype = affected_bodytype)
if(SPT_PROB(8, seconds_per_tick))
to_chat(affected_mob, span_danger("You scratch at your arm."))
- affected_mob.adjustBruteLoss(0.2*REM, FALSE, required_bodytype = affected_bodytype)
- . = TRUE
+ need_mob_update += affected_mob.adjustBruteLoss(0.2*REM, FALSE, required_bodytype = affected_bodytype)
+
+ if(need_mob_update)
+ . = UPDATE_MOB_HEALTH
+
if(SPT_PROB(1.5, seconds_per_tick))
holder.add_reagent(/datum/reagent/toxin/histamine,rand(1,3))
holder.remove_reagent(/datum/reagent/toxin/itching_powder,1.2)
return
- ..()
+ else
+ return ..() || .
/datum/reagent/toxin/initropidril
name = "Initropidril"
@@ -784,16 +799,17 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_NO_RANDOM_RECIPE
/datum/reagent/toxin/initropidril/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
if(SPT_PROB(13, seconds_per_tick))
var/picked_option = rand(1,3)
+ var/need_mob_update
switch(picked_option)
if(1)
affected_mob.Paralyze(60)
- . = TRUE
if(2)
affected_mob.losebreath += 10
- affected_mob.adjustOxyLoss(rand(5,25), FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
- . = TRUE
+ affected_mob.adjustOxyLoss(rand(5,25), updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
+ need_mob_update = TRUE
if(3)
if(!affected_mob.undergoing_cardiac_arrest() && affected_mob.can_heartattack())
affected_mob.set_heartattack(TRUE)
@@ -801,9 +817,9 @@
affected_mob.visible_message(span_userdanger("[affected_mob] clutches at [affected_mob.p_their()] chest as if [affected_mob.p_their()] heart stopped!"))
else
affected_mob.losebreath += 10
- affected_mob.adjustOxyLoss(rand(5,25), FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
- . = TRUE
- return ..() || .
+ need_mob_update = affected_mob.adjustOxyLoss(rand(5,25), updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/toxin/pancuronium
name = "Pancuronium"
@@ -817,12 +833,12 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_NO_RANDOM_RECIPE
/datum/reagent/toxin/pancuronium/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
- if(current_cycle >= 10)
+ . = ..()
+ if(current_cycle > 10)
affected_mob.Stun(40 * REM * seconds_per_tick)
- . = TRUE
if(SPT_PROB(10, seconds_per_tick))
affected_mob.losebreath += 4
- ..()
+ return UPDATE_MOB_HEALTH
/datum/reagent/toxin/sodium_thiopental
name = "Sodium Thiopental"
@@ -843,11 +859,11 @@
REMOVE_TRAIT(affected_mob, TRAIT_ANTICONVULSANT, name)
/datum/reagent/toxin/sodium_thiopental/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
- if(current_cycle >= 10)
+ . = ..()
+ if(current_cycle > 10)
affected_mob.Sleeping(40 * REM * seconds_per_tick)
- affected_mob.adjustStaminaLoss(10 * REM * seconds_per_tick, 0)
- ..()
- return TRUE
+ if(affected_mob.adjustStaminaLoss(10 * REM * seconds_per_tick, updating_stamina = FALSE))
+ return UPDATE_MOB_HEALTH
/datum/reagent/toxin/sulfonal
name = "Sulfonal"
@@ -863,9 +879,9 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/toxin/sulfonal/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
- if(current_cycle >= 22)
+ . = ..()
+ if(current_cycle > 22)
affected_mob.Sleeping(40 * REM * normalise_creation_purity() * seconds_per_tick)
- return ..()
/datum/reagent/toxin/amanitin
name = "Amanitin"
@@ -879,13 +895,13 @@
var/delayed_toxin_damage = 0
/datum/reagent/toxin/amanitin/on_mob_life(mob/living/affected_mob, seconds_per_tick, times_fired)
- delayed_toxin_damage += (seconds_per_tick * 3)
. = ..()
+ delayed_toxin_damage += (seconds_per_tick * 3)
/datum/reagent/toxin/amanitin/on_mob_delete(mob/living/affected_mob)
+ . = ..()
affected_mob.log_message("has taken [delayed_toxin_damage] toxin damage from amanitin toxin", LOG_ATTACK)
affected_mob.adjustToxLoss(delayed_toxin_damage, required_biotype = affected_biotype)
- . = ..()
/datum/reagent/toxin/lipolicide
name = "Lipolicide"
@@ -903,12 +919,12 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/toxin/lipolicide/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
if(affected_mob.nutrition <= NUTRITION_LEVEL_STARVING)
- affected_mob.adjustToxLoss(1 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
- . = TRUE
+ if(affected_mob.adjustToxLoss(1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype))
+ . = UPDATE_MOB_HEALTH
affected_mob.adjust_nutrition(-3 * REM * normalise_creation_purity() * seconds_per_tick) // making the chef more valuable, one meme trap at a time
affected_mob.overeatduration = 0
- return ..() || .
/datum/reagent/toxin/coniine
name = "Coniine"
@@ -920,9 +936,10 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/toxin/coniine/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
if(affected_mob.losebreath < 5)
affected_mob.losebreath = min(affected_mob.losebreath + 5 * REM * seconds_per_tick, 5)
- return ..()
+ return UPDATE_MOB_HEALTH
/datum/reagent/toxin/spewium
name = "Spewium"
@@ -936,8 +953,9 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_NO_RANDOM_RECIPE
/datum/reagent/toxin/spewium/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
- .=..()
- if(current_cycle >= 11 && SPT_PROB(min(30, current_cycle), seconds_per_tick))
+ . = ..()
+ if(current_cycle > 11 && SPT_PROB(min(31, current_cycle), seconds_per_tick))
+ affected_mob.vomit(10, prob(10), prob(50), rand(0,4), TRUE)
var/constructed_flags = (MOB_VOMIT_MESSAGE | MOB_VOMIT_HARM)
if(prob(10))
constructed_flags |= MOB_VOMIT_BLOOD
@@ -950,7 +968,7 @@
/datum/reagent/toxin/spewium/overdose_process(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
. = ..()
- if(current_cycle >= 33 && SPT_PROB(7.5, seconds_per_tick))
+ if(current_cycle > 33 && SPT_PROB(7.5, seconds_per_tick))
affected_mob.spew_organ()
affected_mob.vomit(VOMIT_CATEGORY_BLOOD, lost_nutrition = 0, distance = 4)
to_chat(affected_mob, span_userdanger("You feel something lumpy come up as you vomit."))
@@ -965,11 +983,11 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_NO_RANDOM_RECIPE
/datum/reagent/toxin/curare/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
- if(current_cycle >= 11)
+ . = ..()
+ if(current_cycle > 11)
affected_mob.Paralyze(60 * REM * seconds_per_tick)
- affected_mob.adjustOxyLoss(0.5*REM*seconds_per_tick, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)
- . = TRUE
- ..()
+ if(affected_mob.adjustOxyLoss(0.5*REM*seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type))
+ return UPDATE_MOB_HEALTH
/datum/reagent/toxin/heparin //Based on a real-life anticoagulant. I'm not a doctor, so this won't be realistic.
name = "Heparin"
@@ -990,12 +1008,12 @@
return ..()
/datum/reagent/toxin/heparin/on_mob_metabolize(mob/living/affected_mob)
+ . = ..()
ADD_TRAIT(affected_mob, TRAIT_BLOODY_MESS, /datum/reagent/toxin/heparin)
- return ..()
/datum/reagent/toxin/heparin/on_mob_end_metabolize(mob/living/affected_mob)
+ . = ..()
REMOVE_TRAIT(affected_mob, TRAIT_BLOODY_MESS, /datum/reagent/toxin/heparin)
- return ..()
/datum/reagent/toxin/rotatium //Rotatium. Fucks up your rotation and is hilarious
name = "Rotatium"
@@ -1012,6 +1030,7 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/toxin/rotatium/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
if(affected_mob.hud_used)
if(current_cycle >= 20 && (current_cycle % 20) == 0)
var/atom/movable/plane_master_controller/pm_controller = affected_mob.hud_used.plane_master_controllers[PLANE_MASTERS_GAME]
@@ -1020,14 +1039,13 @@
for(var/atom/movable/screen/plane_master/plane as anything in pm_controller.get_planes())
animate(plane, transform = matrix(rotation, MATRIX_ROTATE), time = 5, easing = QUAD_EASING, loop = -1)
animate(transform = matrix(-rotation, MATRIX_ROTATE), time = 5, easing = QUAD_EASING)
- return ..()
/datum/reagent/toxin/rotatium/on_mob_end_metabolize(mob/living/affected_mob)
+ . = ..()
if(affected_mob?.hud_used)
var/atom/movable/plane_master_controller/pm_controller = affected_mob.hud_used.plane_master_controllers[PLANE_MASTERS_GAME]
for(var/atom/movable/screen/plane_master/plane as anything in pm_controller.get_planes())
animate(plane, transform = matrix(), time = 5, easing = QUAD_EASING)
- ..()
/datum/reagent/toxin/anacea
name = "Anacea"
@@ -1045,13 +1063,12 @@
var/remove_amt = 5
if(holder.has_reagent(/datum/reagent/medicine/calomel) || holder.has_reagent(/datum/reagent/medicine/pen_acid))
remove_amt = 0.5
+ . = ..()
for(var/datum/reagent/medicine/R in affected_mob.reagents.reagent_list)
affected_mob.reagents.remove_reagent(R.type, remove_amt * REM * normalise_creation_purity() * seconds_per_tick)
- return ..()
//ACID
-
/datum/reagent/toxin/acid
name = "Sulfuric Acid"
description = "A strong mineral acid with the molecular formula H2SO4."
@@ -1115,9 +1132,9 @@
mytray.adjust_weedlevel(-rand(1,4))
/datum/reagent/toxin/acid/fluacid/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
- affected_mob.adjustFireLoss((current_cycle/15) * REM * normalise_creation_purity() * seconds_per_tick, FALSE, required_bodytype = affected_bodytype)
- . = TRUE
- ..()
+ . = ..()
+ if(affected_mob.adjustFireLoss(((current_cycle-1)/15) * REM * normalise_creation_purity() * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype))
+ return UPDATE_MOB_HEALTH
/datum/reagent/toxin/acid/nitracid
name = "Nitric Acid"
@@ -1131,9 +1148,9 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/toxin/acid/nitracid/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
- affected_mob.adjustFireLoss((volume/10) * REM * normalise_creation_purity() * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) //here you go nervar
- . = TRUE
- ..()
+ . = ..()
+ if(affected_mob.adjustFireLoss((volume/10) * REM * normalise_creation_purity() * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)) //here you go nervar
+ return UPDATE_MOB_HEALTH
/datum/reagent/toxin/delayed
name = "Toxin Microcapsules"
@@ -1143,17 +1160,18 @@
var/actual_metaboliztion_rate = REAGENTS_METABOLISM
toxpwr = 0
var/actual_toxpwr = 5
- var/delay = 30
+ var/delay = 31
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_NO_RANDOM_RECIPE
/datum/reagent/toxin/delayed/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
if(current_cycle > delay)
- holder.remove_reagent(type, actual_metaboliztion_rate * affected_mob.metabolism_efficiency * seconds_per_tick)
- affected_mob.adjustToxLoss(actual_toxpwr * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype)
+ if(holder)
+ holder.remove_reagent(type, actual_metaboliztion_rate * affected_mob.metabolism_efficiency * seconds_per_tick)
+ if(affected_mob.adjustToxLoss(actual_toxpwr * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype))
+ . = UPDATE_MOB_HEALTH
if(SPT_PROB(5, seconds_per_tick))
affected_mob.Paralyze(20)
- . = TRUE
- ..()
/datum/reagent/toxin/mimesbane
name = "Mime's Bane"
@@ -1168,9 +1186,11 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/toxin/mimesbane/on_mob_metabolize(mob/living/affected_mob)
+ . = ..()
ADD_TRAIT(affected_mob, TRAIT_EMOTEMUTE, type)
/datum/reagent/toxin/mimesbane/on_mob_end_metabolize(mob/living/affected_mob)
+ . = ..()
REMOVE_TRAIT(affected_mob, TRAIT_EMOTEMUTE, type)
/datum/reagent/toxin/bonehurtingjuice //oof ouch
@@ -1187,11 +1207,13 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/toxin/bonehurtingjuice/on_mob_add(mob/living/carbon/affected_mob)
+ . = ..()
affected_mob.say("oof ouch my bones", forced = /datum/reagent/toxin/bonehurtingjuice)
- return ..()
/datum/reagent/toxin/bonehurtingjuice/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
- affected_mob.adjustStaminaLoss(7.5 * REM * seconds_per_tick, 0)
+ . = ..()
+ if(affected_mob.adjustStaminaLoss(7.5 * REM * seconds_per_tick, updating_stamina = FALSE))
+ . = UPDATE_MOB_HEALTH
if(SPT_PROB(10, seconds_per_tick))
switch(rand(1, 3))
if(1)
@@ -1200,9 +1222,9 @@
affected_mob.manual_emote(pick("oofs silently.", "looks like [affected_mob.p_their()] bones hurt.", "grimaces, as though [affected_mob.p_their()] bones hurt."))
if(3)
to_chat(affected_mob, span_warning("Your bones hurt!"))
- return ..() || TRUE
/datum/reagent/toxin/bonehurtingjuice/overdose_process(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
if(SPT_PROB(2, seconds_per_tick) && iscarbon(affected_mob)) //big oof
var/selected_part = pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG) //God help you if the same limb gets picked twice quickly.
var/obj/item/bodypart/BP = affected_mob.get_bodypart(selected_part)
@@ -1210,11 +1232,11 @@
playsound(affected_mob, get_sfx(SFX_DESECRATION), 50, TRUE, -1)
affected_mob.visible_message(span_warning("[affected_mob]'s bones hurt too much!!"), span_danger("Your bones hurt too much!!"))
affected_mob.say("OOF!!", forced = /datum/reagent/toxin/bonehurtingjuice)
- BP.receive_damage(20, 0, 200, wound_bonus = rand(30, 130))
+ if(BP.receive_damage(brute = 20 * REM * seconds_per_tick, burn = 0, blocked = 200, updating_health = FALSE, wound_bonus = rand(30, 130)))
+ . = UPDATE_MOB_HEALTH
else //SUCH A LUST FOR REVENGE!!!
to_chat(affected_mob, span_warning("A phantom limb hurts!"))
affected_mob.say("Why are we still here, just to suffer?", forced = /datum/reagent/toxin/bonehurtingjuice)
- return ..()
/datum/reagent/toxin/bungotoxin
name = "Bungotoxin"
@@ -1227,7 +1249,9 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/toxin/bungotoxin/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
- affected_mob.adjustOrganLoss(ORGAN_SLOT_HEART, 3 * REM * seconds_per_tick)
+ . = ..()
+ if(affected_mob.adjustOrganLoss(ORGAN_SLOT_HEART, 3 * REM * seconds_per_tick))
+ . = UPDATE_MOB_HEALTH
// If our mob's currently dizzy from anything else, we will also gain confusion
var/mob_dizziness = affected_mob.get_timed_status_effect_duration(/datum/status_effect/confusion)
@@ -1235,11 +1259,9 @@
// Gain confusion equal to about half the duration of our current dizziness
affected_mob.set_confusion(mob_dizziness / 2)
- if(current_cycle >= 12 && SPT_PROB(4, seconds_per_tick))
+ if(current_cycle >= 13 && SPT_PROB(4, seconds_per_tick))
var/tox_message = pick("You feel your heart spasm in your chest.", "You feel faint.","You feel you need to catch your breath.","You feel a prickle of pain in your chest.")
to_chat(affected_mob, span_notice("[tox_message]"))
- . = TRUE
- ..()
/datum/reagent/toxin/leadacetate
name = "Lead Acetate"
@@ -1252,13 +1274,16 @@
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
/datum/reagent/toxin/leadacetate/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
- affected_mob.adjustOrganLoss(ORGAN_SLOT_EARS, 1 * REM * seconds_per_tick)
- affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 1 * REM * seconds_per_tick)
- . = TRUE
+ . = ..()
+ var/need_mob_update
+ need_mob_update = affected_mob.adjustOrganLoss(ORGAN_SLOT_EARS, 1 * REM * seconds_per_tick)
+ need_mob_update += affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 1 * REM * seconds_per_tick)
+ if(need_mob_update)
+ . = UPDATE_MOB_HEALTH
if(SPT_PROB(0.5, seconds_per_tick))
to_chat(affected_mob, span_notice("Ah, what was that? You thought you heard something..."))
affected_mob.adjust_confusion(5 SECONDS)
- return ..() || .
+
/datum/reagent/toxin/hunterspider
name = "Spider Toxin"
description = "A toxic chemical produced by spiders to weaken prey."
@@ -1273,8 +1298,8 @@
liver_damage_multiplier = 0
/datum/reagent/toxin/viperspider/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
affected_mob.adjust_hallucinations(10 SECONDS * REM * seconds_per_tick)
- return ..()
/datum/reagent/toxin/tetrodotoxin
name = "Tetrodotoxin"
@@ -1294,10 +1319,12 @@
)
/datum/reagent/toxin/tetrodotoxin/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
+ . = ..()
//be ready for a cocktail of symptoms, including:
//numbness, nausea, vomit, breath loss, weakness, paralysis and nerve damage/impairment and eventually a heart attack if enough time passes.
+ var/need_mob_update
switch(current_cycle)
- if(6 to 12)
+ if(7 to 13)
if(SPT_PROB(20, seconds_per_tick))
affected_mob.set_jitter_if_lower(rand(2 SECONDS, 3 SECONDS) * REM * seconds_per_tick)
if(SPT_PROB(5, seconds_per_tick))
@@ -1306,51 +1333,57 @@
to_chat(affected_mob, span_warning("your [tongue.name] feels numb..."))
affected_mob.set_slurring_if_lower(5 SECONDS * REM * seconds_per_tick)
affected_mob.adjust_disgust(3.5 * REM * seconds_per_tick)
- if(12 to 20)
+ if(13 to 21)
silent_toxin = FALSE
toxpwr = 0.5
- affected_mob.adjustStaminaLoss(2.5 * REM * seconds_per_tick, 0)
+ need_mob_update = affected_mob.adjustStaminaLoss(2.5 * REM * seconds_per_tick, updating_stamina = FALSE)
if(SPT_PROB(20, seconds_per_tick))
affected_mob.losebreath += 1 * REM * seconds_per_tick
+ need_mob_update = TRUE
if(SPT_PROB(40, seconds_per_tick))
affected_mob.set_jitter_if_lower(rand(2 SECONDS, 3 SECONDS) * REM * seconds_per_tick)
affected_mob.adjust_disgust(3 * REM * seconds_per_tick)
affected_mob.set_slurring_if_lower(1 SECONDS * REM * seconds_per_tick)
- affected_mob.adjustStaminaLoss(2 * REM * seconds_per_tick, 0)
+ affected_mob.adjustStaminaLoss(2 * REM * seconds_per_tick, updating_stamina = FALSE)
if(SPT_PROB(4, seconds_per_tick))
paralyze_limb(affected_mob)
+ need_mob_update = TRUE
if(SPT_PROB(10, seconds_per_tick))
affected_mob.adjust_confusion(rand(6 SECONDS, 8 SECONDS))
- if(20 to 28)
+ if(21 to 29)
toxpwr = 1
- affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.5)
+ need_mob_update = affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.5)
if(SPT_PROB(40, seconds_per_tick))
affected_mob.losebreath += 2 * REM * seconds_per_tick
+ need_mob_update = TRUE
affected_mob.adjust_disgust(3 * REM * seconds_per_tick)
affected_mob.set_slurring_if_lower(3 SECONDS * REM * seconds_per_tick)
if(SPT_PROB(5, seconds_per_tick))
to_chat(affected_mob, span_danger("you feel horribly weak."))
- affected_mob.adjustStaminaLoss(5 * REM * seconds_per_tick, 0)
+ need_mob_update += affected_mob.adjustStaminaLoss(5 * REM * seconds_per_tick, updating_stamina = FALSE)
if(SPT_PROB(8, seconds_per_tick))
paralyze_limb(affected_mob)
+ need_mob_update = TRUE
if(SPT_PROB(10, seconds_per_tick))
affected_mob.adjust_confusion(rand(6 SECONDS, 8 SECONDS))
- if(28 to INFINITY)
+ if(29 to INFINITY)
toxpwr = 1.5
- affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 1, BRAIN_DAMAGE_DEATH)
+ need_mob_update = affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 1, BRAIN_DAMAGE_DEATH)
affected_mob.set_silence_if_lower(3 SECONDS * REM * seconds_per_tick)
- affected_mob.adjustStaminaLoss(5 * REM * seconds_per_tick, 0)
+ need_mob_update += affected_mob.adjustStaminaLoss(5 * REM * seconds_per_tick, updating_stamina = FALSE)
affected_mob.adjust_disgust(2 * REM * seconds_per_tick)
if(SPT_PROB(15, seconds_per_tick))
paralyze_limb(affected_mob)
+ need_mob_update = TRUE
if(SPT_PROB(10, seconds_per_tick))
affected_mob.adjust_confusion(rand(6 SECONDS, 8 SECONDS))
- if(current_cycle >= 38 && !length(traits_not_applied) && SPT_PROB(5, seconds_per_tick) && !affected_mob.undergoing_cardiac_arrest())
+ if(current_cycle > 38 && !length(traits_not_applied) && SPT_PROB(5, seconds_per_tick) && !affected_mob.undergoing_cardiac_arrest())
affected_mob.set_heartattack(TRUE)
to_chat(affected_mob, span_danger("you feel a burning pain spread throughout your chest, oh no..."))
- return ..()
+ if(need_mob_update)
+ return UPDATE_MOB_HEALTH
/datum/reagent/toxin/tetrodotoxin/proc/paralyze_limb(mob/living/affected_mob)
if(!length(traits_not_applied))
@@ -1360,9 +1393,11 @@
traits_not_applied -= added_trait
/datum/reagent/toxin/tetrodotoxin/on_mob_metabolize(mob/living/affected_mob)
+ . = ..()
RegisterSignal(affected_mob, COMSIG_CARBON_ATTEMPT_BREATHE, PROC_REF(block_breath))
/datum/reagent/toxin/tetrodotoxin/on_mob_end_metabolize(mob/living/affected_mob)
+ . = ..()
UnregisterSignal(affected_mob, COMSIG_CARBON_ATTEMPT_BREATHE, PROC_REF(block_breath))
// the initial() proc doesn't work for lists.
var/list/initial_list = list(
@@ -1376,5 +1411,5 @@
/datum/reagent/toxin/tetrodotoxin/proc/block_breath(mob/living/source)
SIGNAL_HANDLER
- if(current_cycle >= 28)
+ if(current_cycle > 28)
return COMSIG_CARBON_BLOCK_BREATH
diff --git a/code/modules/reagents/chemistry/reagents/unique/eigenstasium.dm b/code/modules/reagents/chemistry/reagents/unique/eigenstasium.dm
index 70db3446060..73dcf8aa60b 100644
--- a/code/modules/reagents/chemistry/reagents/unique/eigenstasium.dm
+++ b/code/modules/reagents/chemistry/reagents/unique/eigenstasium.dm
@@ -77,21 +77,21 @@
return ..()
/datum/reagent/eigenstate/on_mob_life(mob/living/carbon/living_mob)
+ . = ..()
if(prob(20))
do_sparks(5,FALSE,living_mob)
- return ..()
-
/datum/reagent/eigenstate/on_mob_delete(mob/living/living_mob) //returns back to original location
+ . = ..()
do_sparks(5,FALSE,living_mob)
to_chat(living_mob, span_userdanger("You feel strangely whole again."))
if(!living_mob.reagents.has_reagent(/datum/reagent/stabilizing_agent))
do_teleport(living_mob, location_return, 0, asoundin = 'sound/effects/phasein.ogg') //Teleports home
do_sparks(5,FALSE,living_mob)
qdel(eigenstate)
- return ..()
/datum/reagent/eigenstate/overdose_start(mob/living/living_mob) //Overdose, makes you teleport randomly
+ . = ..()
to_chat(living_mob, span_userdanger("You feel like your perspective is being ripped apart as you begin flitting in and out of reality!"))
living_mob.set_jitter_if_lower(40 SECONDS)
metabolization_rate += 0.5 //So you're not stuck forever teleporting.
@@ -101,10 +101,10 @@
return ..()
/datum/reagent/eigenstate/overdose_process(mob/living/living_mob) //Overdose, makes you teleport randomly
+ . = ..()
do_sparks(5, FALSE, living_mob)
do_teleport(living_mob, get_turf(living_mob), 10, asoundin = 'sound/effects/phasein.ogg')
do_sparks(5, FALSE, living_mob)
- return ..()
//FOR ADDICTION-LIKE EFFECTS, SEE datum/status_effect/eigenstasium
diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm
index 49ef6980142..5234018bbd9 100644
--- a/code/modules/reagents/reagent_containers.dm
+++ b/code/modules/reagents/reagent_containers.dm
@@ -144,7 +144,7 @@
span_danger("You splash the contents of [src] onto [target][punctuation]"),
ignored_mobs = target,
)
-
+ SEND_SIGNAL(target, COMSIG_ATOM_SPLASHED)
if (ismob(target))
var/mob/target_mob = target
target_mob.show_message(
diff --git a/code/modules/religion/religion_sects.dm b/code/modules/religion/religion_sects.dm
index 9075a656ae9..ebd90388fda 100644
--- a/code/modules/religion/religion_sects.dm
+++ b/code/modules/religion/religion_sects.dm
@@ -115,7 +115,7 @@
if(hurt_limbs.len)
for(var/X in hurt_limbs)
var/obj/item/bodypart/affecting = X
- if(affecting.heal_damage(heal_amt, heal_amt, BODYTYPE_ORGANIC))
+ if(affecting.heal_damage(heal_amt, heal_amt, required_bodytype = BODYTYPE_ORGANIC))
blessed.update_damage_overlays()
blessed.visible_message(span_notice("[chap] heals [blessed] with the power of [GLOB.deity]!"))
to_chat(blessed, span_boldnotice("May the power of [GLOB.deity] compel you to be healed!"))
@@ -272,7 +272,7 @@
var/list/hurt_limbs = blessed.get_damaged_bodyparts(1, 1, BODYTYPE_ORGANIC)
if(hurt_limbs.len)
for(var/obj/item/bodypart/affecting as anything in hurt_limbs)
- if(affecting.heal_damage(heal_amt, heal_amt, BODYTYPE_ORGANIC))
+ if(affecting.heal_damage(heal_amt, heal_amt, required_bodytype = BODYTYPE_ORGANIC))
blessed.update_damage_overlays()
blessed.visible_message(span_notice("[chap] barters a heal for [blessed] from [GLOB.deity]!"))
to_chat(blessed, span_boldnotice("May the power of [GLOB.deity] compel you to be healed! Thank you for choosing [GLOB.deity]!"))
diff --git a/code/modules/research/designs/autolathe/service_designs.dm b/code/modules/research/designs/autolathe/service_designs.dm
index ea65fe3ef38..687e85d6436 100644
--- a/code/modules/research/designs/autolathe/service_designs.dm
+++ b/code/modules/research/designs/autolathe/service_designs.dm
@@ -142,6 +142,18 @@
)
departmental_flags = DEPARTMENT_BITFLAG_SERVICE
+/datum/design/tongs
+ name = "Tongs"
+ id = "tongs"
+ build_type = AUTOLATHE | PROTOLATHE | AWAY_LATHE
+ materials = list(/datum/material/iron = SMALL_MATERIAL_AMOUNT * 2)
+ build_path = /obj/item/kitchen/tongs
+ category = list(
+ RND_CATEGORY_INITIAL,
+ RND_CATEGORY_EQUIPMENT + RND_SUBCATEGORY_EQUIPMENT_KITCHEN,
+ )
+ departmental_flags = DEPARTMENT_BITFLAG_SERVICE
+
/datum/design/tray
name = "Serving Tray"
id = "servingtray"
diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm
index 507199164b8..7852bdb367e 100644
--- a/code/modules/research/techweb/all_nodes.dm
+++ b/code/modules/research/techweb/all_nodes.dm
@@ -115,6 +115,7 @@
"titaniumglass",
"toner_large",
"toner",
+ "tongs",
"toy_armblade",
"toy_balloon",
"toygun",
diff --git a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm
index 5c6ff3c811a..6d4d6a7b272 100644
--- a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm
+++ b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm
@@ -173,10 +173,13 @@
alert_type = /atom/movable/screen/alert/status_effect/clone_decay
/datum/status_effect/slime_clone_decay/tick(seconds_between_ticks)
- owner.adjustToxLoss(1, 0)
- owner.adjustOxyLoss(1, 0)
- owner.adjustBruteLoss(1, 0)
- owner.adjustFireLoss(1, 0)
+ var/need_mob_update
+ need_mob_update = owner.adjustToxLoss(1, updating_health = FALSE)
+ need_mob_update += owner.adjustOxyLoss(1, updating_health = FALSE)
+ need_mob_update += owner.adjustBruteLoss(1, updating_health = FALSE)
+ need_mob_update += owner.adjustFireLoss(1, updating_health = FALSE)
+ if(need_mob_update)
+ owner.updatehealth()
owner.color = "#007BA7"
/atom/movable/screen/alert/status_effect/bloodchill
@@ -505,20 +508,24 @@
/datum/status_effect/stabilized/purple/tick(seconds_between_ticks)
healed_last_tick = FALSE
+ var/need_mob_update = FALSE
if(owner.getBruteLoss() > 0)
- owner.adjustBruteLoss(-0.2)
+ need_mob_update += owner.adjustBruteLoss(-0.2, updating_health = FALSE)
healed_last_tick = TRUE
if(owner.getFireLoss() > 0)
- owner.adjustFireLoss(-0.2)
+ need_mob_update += owner.adjustFireLoss(-0.2, updating_health = FALSE)
healed_last_tick = TRUE
if(owner.getToxLoss() > 0)
// Forced, so slimepeople are healed as well.
- owner.adjustToxLoss(-0.2, forced = TRUE)
+ need_mob_update += owner.adjustToxLoss(-0.2, updating_health = FALSE, forced = TRUE)
healed_last_tick = TRUE
+ if(need_mob_update)
+ owner.updatehealth()
+
// Technically, "healed this tick" by now.
if(healed_last_tick)
new /obj/effect/temp_visual/heal(get_turf(owner), "#FF0000")
diff --git a/code/modules/research/xenobiology/crossbreeding/consuming.dm b/code/modules/research/xenobiology/crossbreeding/consuming.dm
index 007bacf8bb7..ec90edd6550 100644
--- a/code/modules/research/xenobiology/crossbreeding/consuming.dm
+++ b/code/modules/research/xenobiology/crossbreeding/consuming.dm
@@ -120,12 +120,15 @@ Consuming extracts:
taste = "fruit jam and cough medicine"
/obj/item/slime_cookie/purple/do_effect(mob/living/M, mob/user)
- M.adjustBruteLoss(-5)
- M.adjustFireLoss(-5)
- M.adjustToxLoss(-5, forced=1) //To heal slimepeople.
- M.adjustOxyLoss(-5)
- M.adjustCloneLoss(-5)
- M.adjustOrganLoss(ORGAN_SLOT_BRAIN, -5)
+ var/need_mob_update = FALSE
+ need_mob_update += M.adjustBruteLoss(-5, updating_health = FALSE)
+ need_mob_update += M.adjustFireLoss(-5, updating_health = FALSE)
+ need_mob_update += M.adjustToxLoss(-5, updating_health = FALSE, forced = TRUE) //To heal slimepeople.
+ need_mob_update += M.adjustOxyLoss(-5, updating_health = FALSE)
+ need_mob_update += M.adjustCloneLoss(-5, updating_health = FALSE)
+ need_mob_update += M.adjustOrganLoss(ORGAN_SLOT_BRAIN, -5)
+ if(need_mob_update)
+ M.updatehealth()
/obj/item/slimecross/consuming/blue
colour = SLIME_TYPE_BLUE
diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm
index 4ae1c241d06..e11e6bf9156 100644
--- a/code/modules/shuttle/shuttle.dm
+++ b/code/modules/shuttle/shuttle.dm
@@ -239,6 +239,9 @@
for(var/turf/T in return_turfs())
T.turf_flags |= NO_RUINS
+ if(SSshuttle.initialized)
+ INVOKE_ASYNC(SSshuttle, TYPE_PROC_REF(/datum/controller/subsystem/shuttle, setup_shuttles), list(src))
+
#ifdef DOCKING_PORT_HIGHLIGHT
highlight("#f00")
#endif
diff --git a/code/modules/spells/spell_types/self/basic_heal.dm b/code/modules/spells/spell_types/self/basic_heal.dm
index 135b8094206..f68403ddeeb 100644
--- a/code/modules/spells/spell_types/self/basic_heal.dm
+++ b/code/modules/spells/spell_types/self/basic_heal.dm
@@ -26,5 +26,8 @@
span_warning("A wreath of gentle light passes over [cast_on]!"),
span_notice("You wreath yourself in healing light!"),
)
- cast_on.adjustBruteLoss(-brute_to_heal, FALSE)
- cast_on.adjustFireLoss(-burn_to_heal)
+ var/need_mob_update = FALSE
+ need_mob_update += cast_on.adjustBruteLoss(-brute_to_heal, updating_health = FALSE)
+ need_mob_update += cast_on.adjustFireLoss(-burn_to_heal, updating_health = FALSE)
+ if(need_mob_update)
+ cast_on.updatehealth()
diff --git a/code/modules/surgery/bodyparts/_bodyparts.dm b/code/modules/surgery/bodyparts/_bodyparts.dm
index c6d0f25cb4c..61a23a81a41 100644
--- a/code/modules/surgery/bodyparts/_bodyparts.dm
+++ b/code/modules/surgery/bodyparts/_bodyparts.dm
@@ -215,7 +215,6 @@
wound_resistance = reset_fantasy_variable("wound_resistance", wound_resistance)
return ..()
-
/obj/item/bodypart/Initialize(mapload)
. = ..()
if(can_be_disabled)
@@ -349,7 +348,6 @@
var/stuck_word = embedded_thing.isEmbedHarmless() ? "stuck" : "embedded"
check_list += "\t There is \a [embedded_thing] [stuck_word] in your [name]!"
-
/obj/item/bodypart/blob_act()
receive_damage(max_damage, wound_bonus = CANT_WOUND)
@@ -456,15 +454,15 @@
* attack_direction - The direction the bodypart is attacked from, used to send blood flying in the opposite direction.
* damage_source - The source of damage, typically a weapon.
*/
-/obj/item/bodypart/proc/receive_damage(brute = 0, burn = 0, blocked = 0, updating_health = TRUE, required_bodytype = null, wound_bonus = 0, bare_wound_bonus = 0, sharpness = NONE, attack_direction = null, damage_source)
+/obj/item/bodypart/proc/receive_damage(brute = 0, burn = 0, blocked = 0, updating_health = TRUE, forced = FALSE, required_bodytype = null, wound_bonus = 0, bare_wound_bonus = 0, sharpness = NONE, attack_direction = null, damage_source)
SHOULD_CALL_PARENT(TRUE)
var/hit_percent = (100-blocked)/100
if((!brute && !burn) || hit_percent <= 0)
return FALSE
- if(owner && (owner.status_flags & GODMODE))
+ if(!forced && owner && (owner.status_flags & GODMODE))
return FALSE //godmode
- if(required_bodytype && !(bodytype & required_bodytype))
+ if(!forced && required_bodytype && !(bodytype & required_bodytype))
return FALSE
var/dmg_multi = CONFIG_GET(number/damage_multiplier) * hit_percent
@@ -649,10 +647,10 @@
//Heals brute and burn damage for the organ. Returns 1 if the damage-icon states changed at all.
//Damage cannot go below zero.
//Cannot remove negative damage (i.e. apply damage)
-/obj/item/bodypart/proc/heal_damage(brute, burn, required_bodytype, updating_health = TRUE)
+/obj/item/bodypart/proc/heal_damage(brute, burn, updating_health = TRUE, forced = FALSE, required_bodytype)
SHOULD_CALL_PARENT(TRUE)
- if(required_bodytype && !(bodytype & required_bodytype)) //So we can only heal certain kinds of limbs, ie robotic vs organic.
+ if(!forced && required_bodytype && !(bodytype & required_bodytype)) //So we can only heal certain kinds of limbs, ie robotic vs organic.
return
if(brute)
@@ -674,7 +672,6 @@
cremation_progress = min(0, cremation_progress - ((brute_dam + burn_dam)*(100/max_damage)))
return update_bodypart_damage_state()
-
///Sets the damage of a bodypart when it is created.
/obj/item/bodypart/proc/set_initial_damage(brute_damage, burn_damage)
set_brute_dam(brute_damage)
@@ -689,7 +686,6 @@
. = brute_dam
brute_dam = new_value
-
///Proc to hook behavior associated to the change of the burn_dam variable's value.
/obj/item/bodypart/proc/set_burn_dam(new_value)
PROTECTED_PROC(TRUE)
@@ -701,8 +697,7 @@
//Returns total damage.
/obj/item/bodypart/proc/get_damage()
- var/total = brute_dam + burn_dam
- return total
+ return brute_dam + burn_dam
//Checks disabled status thresholds
/obj/item/bodypart/proc/update_disabled()
@@ -745,7 +740,6 @@
last_maxed = FALSE
set_disabled(FALSE)
-
///Proc to change the value of the `disabled` variable and react to the event of its change.
/obj/item/bodypart/proc/set_disabled(new_disabled)
SHOULD_CALL_PARENT(TRUE)
@@ -761,7 +755,6 @@
owner.update_health_hud() //update the healthdoll
owner.update_body()
-
///Proc to change the value of the `owner` variable and react to the event of its change.
/obj/item/bodypart/proc/set_owner(new_owner)
SHOULD_CALL_PARENT(TRUE)
@@ -855,7 +848,6 @@
))
set_disabled(FALSE)
-
///Called when TRAIT_PARALYSIS is added to the limb.
/obj/item/bodypart/proc/on_paralysis_trait_gain(obj/item/bodypart/source)
PROTECTED_PROC(TRUE)
@@ -864,7 +856,6 @@
if(can_be_disabled)
set_disabled(TRUE)
-
///Called when TRAIT_PARALYSIS is removed from the limb.
/obj/item/bodypart/proc/on_paralysis_trait_loss(obj/item/bodypart/source)
PROTECTED_PROC(TRUE)
@@ -873,7 +864,6 @@
if(can_be_disabled)
update_disabled()
-
///Called when TRAIT_NOLIMBDISABLE is added to the owner.
/obj/item/bodypart/proc/on_owner_nolimbdisable_trait_gain(mob/living/carbon/source)
PROTECTED_PROC(TRUE)
@@ -881,7 +871,6 @@
set_can_be_disabled(FALSE)
-
///Called when TRAIT_NOLIMBDISABLE is removed from the owner.
/obj/item/bodypart/proc/on_owner_nolimbdisable_trait_loss(mob/living/carbon/source)
PROTECTED_PROC(TRUE)
diff --git a/code/modules/surgery/organs/_organ.dm b/code/modules/surgery/organs/_organ.dm
index 632e4c8b511..5b78cb30796 100644
--- a/code/modules/surgery/organs/_organ.dm
+++ b/code/modules/surgery/organs/_organ.dm
@@ -6,6 +6,8 @@
throwforce = 0
/// The mob that owns this organ.
var/mob/living/carbon/owner = null
+ /// The cached info about the blood this organ belongs to
+ var/list/blood_dna_info = list("Synthetic DNA" = "O+") // not every organ spawns inside a person
/// The body zone this organ is supposed to inhabit.
var/zone = BODY_ZONE_CHEST
/**
@@ -14,7 +16,7 @@
*/
var/slot
/// Random flags that describe this organ
- var/organ_flags = ORGAN_ORGANIC | ORGAN_EDIBLE
+ var/organ_flags = ORGAN_ORGANIC | ORGAN_EDIBLE | ORGAN_VIRGIN
/// Maximum damage the organ can take, ever.
var/maxHealth = STANDARD_ORGAN_THRESHOLD
/**
@@ -75,6 +77,9 @@ INITIALIZE_IMMEDIATE(/obj/item/organ)
volume = reagent_vol,\
after_eat = CALLBACK(src, PROC_REF(OnEatFrom)))
+ if(!IS_ROBOTIC_ORGAN(src))
+ add_blood_DNA(blood_dna_info)
+
/*
* Insert the organ into the select mob.
*
@@ -100,6 +105,14 @@ INITIALIZE_IMMEDIATE(/obj/item/organ)
receiver.organs_slot[slot] = src
owner = receiver
+ if(!IS_ROBOTIC_ORGAN(src) && (organ_flags & ORGAN_VIRGIN))
+ blood_dna_info = receiver.get_blood_dna_list()
+ // need to remove the synethic blood DNA that is initialized
+ // wash also adds the blood dna again
+ wash(CLEAN_TYPE_BLOOD)
+ organ_flags &= ~ORGAN_VIRGIN
+
+
// Apply unique side-effects. Return value does not matter.
on_insert(receiver, special)
@@ -168,6 +181,9 @@ INITIALIZE_IMMEDIATE(/obj/item/organ)
SEND_SIGNAL(src, COMSIG_ORGAN_REMOVED, organ_owner)
SEND_SIGNAL(organ_owner, COMSIG_CARBON_LOSE_ORGAN, src, special)
+ if(!IS_ROBOTIC_ORGAN(src) && !(item_flags & NO_BLOOD_ON_ITEM) && !QDELING(src))
+ AddElement(/datum/element/decal/blood)
+
var/list/diseases = organ_owner.get_static_viruses()
if(!LAZYLEN(diseases))
return
@@ -228,6 +244,14 @@ INITIALIZE_IMMEDIATE(/obj/item/organ)
/obj/item/organ/proc/on_surgical_removal(mob/living/user, mob/living/carbon/old_owner, target_zone, obj/item/tool)
SHOULD_CALL_PARENT(TRUE)
SEND_SIGNAL(src, COMSIG_ORGAN_SURGICALLY_REMOVED, user, old_owner, target_zone, tool)
+ RemoveElement(/datum/element/decal/blood)
+
+/obj/item/organ/wash(clean_types)
+ . = ..()
+
+ // always add the original dna to the organ after it's washed
+ if(!IS_ROBOTIC_ORGAN(src) && (clean_types & CLEAN_TYPE_BLOOD))
+ add_blood_DNA(blood_dna_info)
/obj/item/organ/process(seconds_per_tick, times_fired)
return
@@ -267,17 +291,18 @@ INITIALIZE_IMMEDIATE(/obj/item/organ)
/obj/item/organ/item_action_slot_check(slot,mob/user)
return //so we don't grant the organ's action to mobs who pick up the organ.
-///Adjusts an organ's damage by the amount "damage_amount", up to a maximum amount, which is by default max damage
+///Adjusts an organ's damage by the amount "damage_amount", up to a maximum amount, which is by default max damage. Returns the net change in organ damage.
/obj/item/organ/proc/apply_organ_damage(damage_amount, maximum = maxHealth, required_organ_flag = NONE) //use for damaging effects
if(!damage_amount) //Micro-optimization.
- return
+ return FALSE
maximum = clamp(maximum, 0, maxHealth) // the logical max is, our max
if(maximum < damage)
- return
+ return FALSE
if(required_organ_flag && !(organ_flags & required_organ_flag))
- return
+ return FALSE
damage = clamp(damage + damage_amount, 0, maximum)
- var/mess = check_damage_thresholds(owner)
+ . = (prev_damage - damage) // return net damage
+ var/message = check_damage_thresholds(owner)
prev_damage = damage
if(damage >= maxHealth)
@@ -285,8 +310,8 @@ INITIALIZE_IMMEDIATE(/obj/item/organ)
else
organ_flags &= ~ORGAN_FAILING
- if(mess && owner && owner.stat <= SOFT_CRIT)
- to_chat(owner, mess)
+ if(message && owner && owner.stat <= SOFT_CRIT)
+ to_chat(owner, message)
///SETS an organ's damage to the amount "damage_amount", and in doing so clears or sets the failing flag, good for when you have an effect that should fix an organ if broken
/obj/item/organ/proc/set_organ_damage(damage_amount, required_organ_flag = NONE) //use mostly for admin heals
diff --git a/code/modules/surgery/organs/internal/appendix/_appendix.dm b/code/modules/surgery/organs/internal/appendix/_appendix.dm
index a52479c10a7..bb02c8b9ef9 100644
--- a/code/modules/surgery/organs/internal/appendix/_appendix.dm
+++ b/code/modules/surgery/organs/internal/appendix/_appendix.dm
@@ -34,7 +34,7 @@
if(organ_flags & ORGAN_FAILING)
// forced to ensure people don't use it to gain tox as slime person
- owner.adjustToxLoss(2 * seconds_per_tick, updating_health = TRUE, forced = TRUE)
+ owner.adjustToxLoss(2 * seconds_per_tick, forced = TRUE)
else if(inflamation_stage)
inflamation(seconds_per_tick)
else if(SPT_PROB(APPENDICITIS_PROB, seconds_per_tick))
@@ -62,7 +62,7 @@
to_chat(organ_owner, span_warning("You feel a stabbing pain in your abdomen!"))
organ_owner.adjustOrganLoss(ORGAN_SLOT_APPENDIX, 5)
organ_owner.Stun(rand(40, 60))
- organ_owner.adjustToxLoss(1, updating_health = TRUE, forced = TRUE)
+ organ_owner.adjustToxLoss(1, forced = TRUE)
if(3)
if(SPT_PROB(0.5, seconds_per_tick))
organ_owner.vomit(VOMIT_CATEGORY_DEFAULT, lost_nutrition = 95)
diff --git a/code/modules/surgery/organs/internal/cyberimp/augments_chest.dm b/code/modules/surgery/organs/internal/cyberimp/augments_chest.dm
index 60322a7f8d6..86dacdd98ff 100644
--- a/code/modules/surgery/organs/internal/cyberimp/augments_chest.dm
+++ b/code/modules/surgery/organs/internal/cyberimp/augments_chest.dm
@@ -77,18 +77,21 @@
/obj/item/organ/internal/cyberimp/chest/reviver/proc/heal()
+ var/need_mob_update = FALSE
if(owner.getOxyLoss())
- owner.adjustOxyLoss(-5)
+ need_mob_update += owner.adjustOxyLoss(-5, updating_health = FALSE)
revive_cost += 5
if(owner.getBruteLoss())
- owner.adjustBruteLoss(-2)
+ need_mob_update += owner.adjustBruteLoss(-2, updating_health = FALSE)
revive_cost += 40
if(owner.getFireLoss())
- owner.adjustFireLoss(-2)
+ need_mob_update += owner.adjustFireLoss(-2, updating_health = FALSE)
revive_cost += 40
if(owner.getToxLoss())
- owner.adjustToxLoss(-1)
+ need_mob_update += owner.adjustToxLoss(-1, updating_health = FALSE)
revive_cost += 40
+ if(need_mob_update)
+ owner.updatehealth()
/obj/item/organ/internal/cyberimp/chest/reviver/emp_act(severity)
. = ..()
diff --git a/code/modules/surgery/organs/internal/eyes/_eyes.dm b/code/modules/surgery/organs/internal/eyes/_eyes.dm
index aca812a6186..05f532ae444 100644
--- a/code/modules/surgery/organs/internal/eyes/_eyes.dm
+++ b/code/modules/surgery/organs/internal/eyes/_eyes.dm
@@ -187,7 +187,7 @@
/obj/item/organ/internal/eyes/apply_organ_damage(damage_amount, maximum = maxHealth, required_organ_flag)
. = ..()
if(!owner)
- return
+ return FALSE
apply_damaged_eye_effects()
/// Applies effects to our owner based on how damaged our eyes are
diff --git a/code/modules/surgery/organs/internal/heart/_heart.dm b/code/modules/surgery/organs/internal/heart/_heart.dm
index e553f8f1307..fb97ca7eda0 100644
--- a/code/modules/surgery/organs/internal/heart/_heart.dm
+++ b/code/modules/surgery/organs/internal/heart/_heart.dm
@@ -6,7 +6,7 @@
visual = FALSE
zone = BODY_ZONE_CHEST
slot = ORGAN_SLOT_HEART
-
+ item_flags = NO_BLOOD_ON_ITEM
healing_factor = STANDARD_ORGAN_HEALING
decay_factor = 2.5 * STANDARD_ORGAN_DECAY //designed to fail around 6 minutes after death
@@ -104,20 +104,12 @@
icon_state = "cursedheart-off"
base_icon_state = "cursedheart"
decay_factor = 0
- actions_types = list(/datum/action/item_action/organ_action/cursed_heart)
- var/last_pump = 0
- var/add_colour = TRUE //So we're not constantly recreating colour datums
- /// How long between needed pumps; you can pump one second early
var/pump_delay = 3 SECONDS
- /// How much blood volume you lose every missed pump, this is a flat amount not a percentage!
- var/blood_loss = (BLOOD_VOLUME_NORMAL / 5) // 20% of normal volume, missing five pumps is instant death
-
- //How much to heal per pump, negative numbers would HURT the player
+ var/blood_loss = BLOOD_VOLUME_NORMAL * 0.2
var/heal_brute = 0
var/heal_burn = 0
var/heal_oxy = 0
-
/obj/item/organ/internal/heart/cursed/attack(mob/living/carbon/human/accursed, mob/living/carbon/human/user, obj/target)
if(accursed == user && istype(accursed))
playsound(user,'sound/effects/singlebeat.ogg',40,TRUE)
@@ -126,75 +118,13 @@
else
return ..()
-/// Worker proc that checks logic for if a pump can happen, and applies effects/notifications from doing so
-/obj/item/organ/internal/heart/cursed/proc/on_pump(mob/owner)
- var/next_pump = last_pump + pump_delay - (1 SECONDS) // pump a second early
- if(world.time < next_pump)
- to_chat(owner, span_userdanger("Too soon!"))
- return
-
- last_pump = world.time
- playsound(owner,'sound/effects/singlebeat.ogg', 40, TRUE)
- to_chat(owner, span_notice("Your heart beats."))
-
- if(!ishuman(owner))
- return
- var/mob/living/carbon/human/accursed = owner
-
- if(HAS_TRAIT(accursed, TRAIT_NOBLOOD) || !accursed.dna)
- return
- accursed.blood_volume = min(accursed.blood_volume + (blood_loss * 0.5), BLOOD_VOLUME_MAXIMUM)
- accursed.remove_client_colour(/datum/client_colour/cursed_heart_blood)
- add_colour = TRUE
- accursed.adjustBruteLoss(-heal_brute)
- accursed.adjustFireLoss(-heal_burn)
- accursed.adjustOxyLoss(-heal_oxy)
-
-/obj/item/organ/internal/heart/cursed/on_life(seconds_per_tick, times_fired)
- if(!owner.client || !ishuman(owner)) // Let's be fair, if you're not here to pump, you're not here to suffer.
- last_pump = world.time
- return
-
- if(world.time <= (last_pump + pump_delay))
- return
-
- var/mob/living/carbon/human/accursed = owner
- if(HAS_TRAIT(accursed, TRAIT_NOBLOOD) || !accursed.dna)
- return
-
- accursed.blood_volume = max(accursed.blood_volume - blood_loss, 0)
- to_chat(accursed, span_userdanger("You have to keep pumping your blood!"))
- if(add_colour)
- accursed.add_client_colour(/datum/client_colour/cursed_heart_blood) //bloody screen so real
- add_colour = FALSE
-
/obj/item/organ/internal/heart/cursed/on_insert(mob/living/carbon/accursed)
. = ..()
- last_pump = world.time // give them time to react
- to_chat(accursed, span_userdanger("Your heart has been replaced with a cursed one, you have to pump this one manually otherwise you'll die!"))
+ accursed.AddComponent(/datum/component/manual_heart, pump_delay = pump_delay, blood_loss = blood_loss, heal_brute = heal_brute, heal_burn = heal_burn, heal_oxy = heal_oxy)
/obj/item/organ/internal/heart/cursed/Remove(mob/living/carbon/accursed, special = FALSE)
. = ..()
- accursed.remove_client_colour(/datum/client_colour/cursed_heart_blood)
-
-/datum/action/item_action/organ_action/cursed_heart
- name = "Pump your blood"
- check_flags = NONE
-
-//You are now brea- pumping blood manually
-/datum/action/item_action/organ_action/cursed_heart/Trigger(trigger_flags)
- . = ..()
- if(!.)
- return
-
- var/obj/item/organ/internal/heart/cursed/cursed_heart = target
- if(!istype(cursed_heart))
- CRASH("Cursed heart pump action created on non-cursed heart!")
- cursed_heart.on_pump(owner)
-
-/datum/client_colour/cursed_heart_blood
- priority = 100 //it's an indicator you're dying, so it's very high priority
- colour = "#FF0000"
+ qdel(accursed.GetComponent(/datum/component/manual_heart))
/obj/item/organ/internal/heart/cybernetic
name = "basic cybernetic heart"
diff --git a/code/modules/surgery/organs/internal/liver/liver_skeleton.dm b/code/modules/surgery/organs/internal/liver/liver_skeleton.dm
index f9b41741b4a..b57afd245f5 100644
--- a/code/modules/surgery/organs/internal/liver/liver_skeleton.dm
+++ b/code/modules/surgery/organs/internal/liver/liver_skeleton.dm
@@ -19,8 +19,8 @@
if((. & COMSIG_MOB_STOP_REAGENT_CHECK) || (organ_flags & ORGAN_FAILING))
return
if(istype(chem, /datum/reagent/toxin/bonehurtingjuice))
- organ_owner.adjustStaminaLoss(7.5 * REM * seconds_per_tick, 0)
- organ_owner.adjustBruteLoss(0.5 * REM * seconds_per_tick, 0)
+ organ_owner.adjustStaminaLoss(7.5 * REM * seconds_per_tick, updating_stamina = FALSE)
+ organ_owner.adjustBruteLoss(0.5 * REM * seconds_per_tick, updating_health = FALSE)
if(SPT_PROB(10, seconds_per_tick))
switch(rand(1, 3))
if(1)
diff --git a/code/modules/surgery/organs/internal/tongue/_tongue.dm b/code/modules/surgery/organs/internal/tongue/_tongue.dm
index 08ee3d20faf..03b223b4298 100644
--- a/code/modules/surgery/organs/internal/tongue/_tongue.dm
+++ b/code/modules/surgery/organs/internal/tongue/_tongue.dm
@@ -154,7 +154,7 @@
/obj/item/organ/internal/tongue/apply_organ_damage(damage_amount, maximum = maxHealth, required_organ_flag)
. = ..()
if(!owner)
- return
+ return FALSE
apply_tongue_effects()
/// Applies effects to our owner based on how damaged our tongue is
diff --git a/code/modules/unit_tests/_unit_tests.dm b/code/modules/unit_tests/_unit_tests.dm
index 20ca34d5259..e05c2516045 100644
--- a/code/modules/unit_tests/_unit_tests.dm
+++ b/code/modules/unit_tests/_unit_tests.dm
@@ -175,6 +175,7 @@
#include "metabolizing.dm"
#include "mindbound_actions.dm"
#include "missing_icons.dm"
+#include "mob_damage.dm"
#include "mob_faction.dm"
#include "mob_spawn.dm"
#include "modify_fantasy_variable.dm"
diff --git a/code/modules/unit_tests/mob_damage.dm b/code/modules/unit_tests/mob_damage.dm
new file mode 100644
index 00000000000..3d257e0f775
--- /dev/null
+++ b/code/modules/unit_tests/mob_damage.dm
@@ -0,0 +1,539 @@
+/// Tests to make sure mob damage procs are working correctly
+/datum/unit_test/mob_damage
+ priority = TEST_LONGER
+
+/datum/unit_test/mob_damage/Destroy()
+ SSmobs.ignite()
+ return ..()
+
+/datum/unit_test/mob_damage/Run()
+ SSmobs.pause()
+ var/mob/living/carbon/human/dummy = allocate(/mob/living/carbon/human/consistent)
+ dummy.maxHealth = 200 // tank mode
+
+ /* The sanity tests: here we make sure that:
+ 1) That damage procs are returning the expected values. They should be returning the actual amount of damage taken/healed.
+ (Negative values mean damage was taken, positive mean healing)
+ 2) Verifying that the damage has been accurately applied to the mob afterwards. */
+
+ test_sanity_simple(dummy)
+ test_sanity_complex(dummy)
+
+ // Testing if biotypes are working as intended
+ test_biotypes(dummy)
+
+ // Testing whether or not TRAIT_NOBREATH is working as intended
+ test_nobreath(dummy)
+
+ // Testing whether or not TRAIT_TOXINLOVER and TRAIT_TOXIMMUNE are working as intended
+ test_toxintraits(dummy)
+
+ // Testing whether or not TRAIT_NOCLONELOSS is working as intended
+ test_nocloneloss(dummy)
+
+ // Testing the proc ordered_healing()
+ test_ordered_healing(dummy)
+
+ // testing with godmode enabled
+ test_godmode(dummy)
+
+/**
+ * Check that the mob has a specific amount of damage
+ *
+ * By default this checks that the mob has of every type of damage.
+ * Arguments:
+ * * testing_mob - the mob to check the damage of
+ * * amount - the amount of damage to verify that the mob has
+ * * included_types - Bitflag of damage types to check.
+ */
+/datum/unit_test/mob_damage/proc/verify_damage(mob/living/testing_mob, amount, included_types = ALL)
+ if(included_types & TOXLOSS)
+ TEST_ASSERT_EQUAL(testing_mob.getToxLoss(), amount, \
+ "[testing_mob] should have [amount] toxin damage, instead they have [testing_mob.getToxLoss()]!")
+ if(included_types & CLONELOSS)
+ TEST_ASSERT_EQUAL(testing_mob.getCloneLoss(), amount, \
+ "[testing_mob] should have [amount] clone damage, instead they have [testing_mob.getCloneLoss()]!")
+ if(included_types & BRUTELOSS)
+ TEST_ASSERT_EQUAL(round(testing_mob.getBruteLoss(), 1), amount, \
+ "[testing_mob] should have [amount] brute damage, instead they have [testing_mob.getBruteLoss()]!")
+ if(included_types & FIRELOSS)
+ TEST_ASSERT_EQUAL(round(testing_mob.getFireLoss(), 1), amount, \
+ "[testing_mob] should have [amount] burn damage, instead they have [testing_mob.getFireLoss()]!")
+ if(included_types & OXYLOSS)
+ TEST_ASSERT_EQUAL(testing_mob.getOxyLoss(), amount, \
+ "[testing_mob] should have [amount] oxy damage, instead they have [testing_mob.getOxyLoss()]!")
+ if(included_types & STAMINALOSS)
+ TEST_ASSERT_EQUAL(testing_mob.getStaminaLoss(), amount, \
+ "[testing_mob] should have [amount] stamina damage, instead they have [testing_mob.getStaminaLoss()]!")
+
+/**
+ * Apply a specific amount of damage to the mob using adjustBruteLoss(), adjustToxLoss(), etc.
+ *
+ * By default this applies damage of every type to the mob, and checks that the damage procs return the value
+ * Arguments:
+ * * testing_mob - the mob to apply the damage to
+ * * amount - the amount of damage to apply to the mob
+ * * expected - what the expected return value of the damage proc is
+ * * included_types - Bitflag of damage types to apply
+ * * biotypes - the biotypes of damage to apply
+ * * bodytypes - the bodytypes of damage to apply
+ * * forced - whether or not this is forced damage
+ */
+/datum/unit_test/mob_damage/proc/apply_damage(mob/living/testing_mob, amount, expected = -amount, included_types = ALL, biotypes = ALL, bodytypes = ALL, forced = FALSE)
+ var/damage_returned
+ if(included_types & TOXLOSS)
+ damage_returned = testing_mob.adjustToxLoss(amount, updating_health = FALSE, forced = forced, required_biotype = biotypes)
+ TEST_ASSERT_EQUAL(damage_returned, expected, \
+ "adjustToxLoss() should have returned [expected], but returned [damage_returned] instead!")
+ if(included_types & CLONELOSS)
+ damage_returned = testing_mob.adjustCloneLoss(amount, updating_health = FALSE, forced = forced, required_biotype = biotypes)
+ TEST_ASSERT_EQUAL(damage_returned, expected, \
+ "adjustCloneLoss() should have returned [expected], but returned [damage_returned] instead!")
+ if(included_types & BRUTELOSS)
+ damage_returned = round(testing_mob.adjustBruteLoss(amount, updating_health = FALSE, forced = forced, required_bodytype = bodytypes), 1)
+ TEST_ASSERT_EQUAL(damage_returned, expected, \
+ "adjustBruteLoss() should have returned [expected], but returned [damage_returned] instead!")
+ if(included_types & FIRELOSS)
+ damage_returned = round(testing_mob.adjustFireLoss(amount, updating_health = FALSE, forced = forced, required_bodytype = bodytypes), 1)
+ TEST_ASSERT_EQUAL(damage_returned, expected, \
+ "adjustFireLoss() should have returned [expected], but returned [damage_returned] instead!")
+ if(included_types & OXYLOSS)
+ damage_returned = testing_mob.adjustOxyLoss(amount, updating_health = FALSE, forced = forced, required_biotype = biotypes)
+ TEST_ASSERT_EQUAL(damage_returned, expected, \
+ "adjustOxyLoss() should have returned [expected], but returned [damage_returned] instead!")
+ if(included_types & STAMINALOSS)
+ damage_returned = testing_mob.adjustStaminaLoss(amount, updating_stamina = FALSE, forced = forced, required_biotype = biotypes)
+ TEST_ASSERT_EQUAL(damage_returned, expected, \
+ "adjustStaminaLoss() should have returned [expected], but returned [damage_returned] instead!")
+
+/**
+ * Set a specific amount of damage for the mob using setBruteLoss(), setToxLoss(), etc.
+ *
+ * By default this sets every type of damage to for the mob, and checks that the damage procs return the value
+ * Arguments:
+ * * testing_mob - the mob to apply the damage to
+ * * amount - the amount of damage to apply to the mob
+ * * expected - what the expected return value of the damage proc is
+ * * included_types - Bitflag of damage types to apply
+ * * biotypes - the biotypes of damage to apply
+ * * bodytypes - the bodytypes of damage to apply
+ * * forced - whether or not this is forced damage
+ */
+/datum/unit_test/mob_damage/proc/set_damage(mob/living/testing_mob, amount, expected = -amount, included_types = ALL, biotypes = ALL, bodytypes = ALL, forced = FALSE)
+ var/damage_returned
+ if(included_types & TOXLOSS)
+ damage_returned = testing_mob.setToxLoss(amount, updating_health = FALSE, forced = forced, required_biotype = biotypes)
+ TEST_ASSERT_EQUAL(damage_returned, expected, \
+ "setToxLoss() should have returned [expected], but returned [damage_returned] instead!")
+ if(included_types & CLONELOSS)
+ damage_returned = testing_mob.setCloneLoss(amount, updating_health = FALSE, forced = forced, required_biotype = biotypes)
+ TEST_ASSERT_EQUAL(damage_returned, expected, \
+ "setCloneLoss() should have returned [expected], but returned [damage_returned] instead!")
+ if(included_types & BRUTELOSS)
+ damage_returned = round(testing_mob.setBruteLoss(amount, updating_health = FALSE, forced = forced), 1)
+ TEST_ASSERT_EQUAL(damage_returned, expected, \
+ "setBruteLoss() should have returned [expected], but returned [damage_returned] instead!")
+ if(included_types & FIRELOSS)
+ damage_returned = round(testing_mob.setFireLoss(amount, updating_health = FALSE, forced = forced), 1)
+ TEST_ASSERT_EQUAL(damage_returned, expected, \
+ "setFireLoss() should have returned [expected], but returned [damage_returned] instead!")
+ if(included_types & OXYLOSS)
+ damage_returned = testing_mob.setOxyLoss(amount, updating_health = FALSE, forced = forced, required_biotype = biotypes)
+ TEST_ASSERT_EQUAL(damage_returned, expected, \
+ "setOxyLoss() should have returned [expected], but returned [damage_returned] instead!")
+ if(included_types & STAMINALOSS)
+ damage_returned = testing_mob.setStaminaLoss(amount, updating_stamina = FALSE, forced = forced, required_biotype = biotypes)
+ TEST_ASSERT_EQUAL(damage_returned, expected, \
+ "setStaminaLoss() should have returned [expected], but returned [damage_returned] instead!")
+
+/// Sanity tests damage and healing using adjustToxLoss, adjustBruteLoss, etc
+/datum/unit_test/mob_damage/proc/test_sanity_simple(mob/living/carbon/human/consistent/dummy)
+
+ // Apply 5 damage and then heal it
+ apply_damage(dummy, 5)
+ verify_damage(dummy, 5)
+
+ apply_damage(dummy, -5)
+ verify_damage(dummy, 0)
+
+ // Apply 15 damage and heal 3
+ apply_damage(dummy, 15)
+ verify_damage(dummy, 15)
+
+ apply_damage(dummy, -3)
+ verify_damage(dummy, 12)
+
+ // Now overheal by 666. It should heal for 12.
+
+ apply_damage(dummy, -666, expected = 12)
+ verify_damage(dummy, 0)
+
+ // Now test the damage setter procs
+
+ // set all types of damage to 5
+ set_damage(dummy, 5, expected = -5)
+ verify_damage(dummy, 5)
+ // now try healing 5
+ set_damage(dummy, 0, expected = 5)
+ verify_damage(dummy, 0)
+
+/// Sanity tests damage and healing using the more complex procs like take_overall_damage(), heal_overall_damage(), etc
+/datum/unit_test/mob_damage/proc/test_sanity_complex(mob/living/carbon/human/consistent/dummy)
+ var/damage_returned
+ // take 5 brute, 2 burn
+ damage_returned = round(dummy.take_bodypart_damage(5, 2, updating_health = FALSE), 1)
+ TEST_ASSERT_EQUAL(damage_returned, -7, \
+ "take_bodypart_damage() should have returned -7, but returned [damage_returned] instead!")
+
+ TEST_ASSERT_EQUAL(round(dummy.getBruteLoss(), 1), 5, \
+ "Dummy should have 5 brute damage, instead they have [dummy.getBruteLoss()]!")
+ TEST_ASSERT_EQUAL(round(dummy.getFireLoss(), 1), 2, \
+ "Dummy should have 2 burn damage, instead they have [dummy.getFireLoss()]!")
+
+ // heal 4 brute, 1 burn
+ damage_returned = round(dummy.heal_bodypart_damage(4, 1, updating_health = FALSE), 1)
+ TEST_ASSERT_EQUAL(damage_returned, 5, \
+ "heal_bodypart_damage() should have returned 5, but returned [damage_returned] instead!")
+
+ verify_damage(dummy, 1, included_types = BRUTELOSS|FIRELOSS)
+
+ // heal 1 brute, 1 burn
+ damage_returned = round(dummy.heal_overall_damage(1, 1, updating_health = FALSE), 1)
+ TEST_ASSERT_EQUAL(damage_returned, 2, \
+ "heal_overall_damage() should have returned 2, but returned [damage_returned] instead!")
+
+ verify_damage(dummy, 0, included_types = BRUTELOSS|FIRELOSS)
+
+ // take 50 brute, 50 burn
+ damage_returned = round(dummy.take_overall_damage(50, 50, updating_health = FALSE), 1)
+ TEST_ASSERT_EQUAL(damage_returned, -100, \
+ "take_overall_damage() should have returned -100, but returned [damage_returned] instead!")
+
+ verify_damage(dummy, 50, included_types = BRUTELOSS|FIRELOSS)
+
+ // testing negative damage amount args with the overall damage procs - the sign should be ignored for these procs
+
+ damage_returned = round(dummy.take_bodypart_damage(-5, -5, updating_health = FALSE), 1)
+ TEST_ASSERT_EQUAL(damage_returned, -10, \
+ "take_bodypart_damage() should have returned -10, but returned [damage_returned] instead!")
+
+ damage_returned = round(dummy.heal_bodypart_damage(-5, -5, updating_health = FALSE), 1)
+ TEST_ASSERT_EQUAL(damage_returned, 10, \
+ "heal_bodypart_damage() should have returned 10, but returned [damage_returned] instead!")
+
+ damage_returned = round(dummy.take_overall_damage(-5, -5, updating_health = FALSE), 1)
+ TEST_ASSERT_EQUAL(damage_returned, -10, \
+ "take_overall_damage() should have returned -10, but returned [damage_returned] instead!")
+
+ damage_returned = round(dummy.heal_overall_damage(-5, -5, updating_health = FALSE), 1)
+ TEST_ASSERT_EQUAL(damage_returned, 10, \
+ "heal_overall_damage() should have returned 10, but returned [damage_returned] instead!")
+
+ verify_damage(dummy, 50, included_types = BRUTELOSS|FIRELOSS)
+
+ // testing overhealing
+
+ damage_returned = round(dummy.heal_overall_damage(75, 99, updating_health = FALSE), 1)
+ TEST_ASSERT_EQUAL(damage_returned, 100, \
+ "heal_overall_damage() should have returned 100, but returned [damage_returned] instead!")
+
+ verify_damage(dummy, 0, included_types = BRUTELOSS|FIRELOSS)
+
+/// Tests damage procs with godmode on
+/datum/unit_test/mob_damage/proc/test_godmode(mob/living/carbon/human/consistent/dummy)
+ // flip godmode bit to 1
+ dummy.status_flags ^= GODMODE
+
+ // Apply 9 damage and then heal it
+ apply_damage(dummy, 9, expected = 0)
+ verify_damage(dummy, 0)
+
+ apply_damage(dummy, -9, expected = 0)
+ verify_damage(dummy, 0)
+
+ // Apply 11 damage and then heal it, this time with forced enabled. The damage should go through regardless of godmode.
+ apply_damage(dummy, 11, forced = TRUE)
+ verify_damage(dummy, 11)
+
+ apply_damage(dummy, -11, forced = TRUE)
+ verify_damage(dummy, 0)
+
+ // flip godmode bit back to 0
+ dummy.status_flags ^= GODMODE
+
+/// Testing biotypes
+/datum/unit_test/mob_damage/proc/test_biotypes(mob/living/carbon/human/consistent/dummy)
+ // Testing biotypes using a plasmaman, who is MOB_MINERAL and MOB_HUMANOID
+ dummy.set_species(/datum/species/plasmaman)
+
+ // argumentless default: should default to required_biotype = ALL. The damage should be applied in that case.
+ apply_damage(dummy, 1, included_types = TOXLOSS|CLONELOSS|STAMINALOSS)
+ verify_damage(dummy, 1, included_types = TOXLOSS|CLONELOSS|STAMINALOSS)
+
+ // If we specify MOB_ORGANIC, the damage should not get applied because plasmamen lack that biotype.
+ apply_damage(dummy, 1, expected = 0, included_types = TOXLOSS|CLONELOSS|STAMINALOSS, biotypes = MOB_ORGANIC)
+ verify_damage(dummy, 1, included_types = TOXLOSS|CLONELOSS|STAMINALOSS)
+
+ // Now if we specify MOB_MINERAL the damage should get applied.
+ apply_damage(dummy, 1, included_types = TOXLOSS|CLONELOSS|STAMINALOSS, biotypes = MOB_MINERAL)
+ verify_damage(dummy, 2, included_types = TOXLOSS|CLONELOSS|STAMINALOSS)
+
+ // Transform back to human
+ dummy.set_species(/datum/species/human)
+
+ // We have 2 damage presently.
+ // Try to heal it; let's specify MOB_MINERAL, which should no longer work because we have changed back to a human.
+ apply_damage(dummy, -2, expected = 0, included_types = TOXLOSS|CLONELOSS|STAMINALOSS, biotypes = MOB_MINERAL)
+ verify_damage(dummy, 2, included_types = TOXLOSS|CLONELOSS|STAMINALOSS)
+
+ // Force heal some of the damage. When forced = TRUE the damage/healing gets applied no matter what.
+ apply_damage(dummy, -1, included_types = TOXLOSS|CLONELOSS|STAMINALOSS, biotypes = MOB_MINERAL, forced = TRUE)
+ verify_damage(dummy, 1, included_types = TOXLOSS|CLONELOSS|STAMINALOSS)
+
+ // Now heal the rest of it with the correct biotype. Make sure that this works. We should have 0 damage afterwards.
+ apply_damage(dummy, -1, included_types = TOXLOSS|CLONELOSS|STAMINALOSS, biotypes = MOB_ORGANIC)
+ verify_damage(dummy, 0, included_types = TOXLOSS|CLONELOSS|STAMINALOSS)
+
+/// Testing oxyloss with the TRAIT_NOBREATH
+/datum/unit_test/mob_damage/proc/test_nobreath(mob/living/carbon/human/consistent/dummy)
+ // TRAIT_NOBREATH is supposed to prevent oxyloss damage (but not healing). Let's make sure that's the case.
+ ADD_TRAIT(dummy, TRAIT_NOBREATH, TRAIT_SOURCE_UNIT_TESTS)
+ // force some oxyloss here
+ dummy.setOxyLoss(2, updating_health = FALSE, forced = TRUE)
+
+ // Try to take more oxyloss damage with TRAIT_NOBREATH. It should not work.
+ apply_damage(dummy, 2, expected = 0, included_types = OXYLOSS)
+ verify_damage(dummy, 2, included_types = OXYLOSS)
+
+ // Make sure we are still be able to heal the oxyloss. This should work.
+ apply_damage(dummy, -2, included_types = OXYLOSS)
+ verify_damage(dummy, 0, included_types = OXYLOSS)
+
+ REMOVE_TRAIT(dummy, TRAIT_NOBREATH, TRAIT_SOURCE_UNIT_TESTS)
+
+/// Testing toxloss with TRAIT_TOXINLOVER and TRAIT_TOXIMMUNE
+/datum/unit_test/mob_damage/proc/test_toxintraits(mob/living/carbon/human/consistent/dummy)
+ // TRAIT_TOXINLOVER is supposed to invert toxin damage and healing. Things that would normally cause toxloss now heal it, and vice versa.
+ ADD_TRAIT(dummy, TRAIT_TOXINLOVER, TRAIT_SOURCE_UNIT_TESTS)
+ // force some toxloss here
+ dummy.setToxLoss(2, updating_health = FALSE, forced = TRUE)
+
+ // Try to take more toxloss damage with TRAIT_TOXINLOVER. It should heal instead.
+ apply_damage(dummy, 2, expected = 2, included_types = TOXLOSS)
+ verify_damage(dummy, 0, included_types = TOXLOSS)
+
+ // If we try to heal the toxloss we should take damage instead
+ apply_damage(dummy, -2, expected = -2, included_types = TOXLOSS)
+ verify_damage(dummy, 2, included_types = TOXLOSS)
+
+ // TOXIMMUNE trait should prevent the damage you get from being healed by toxins medicines while having TRAIT_TOXINLOVER
+ ADD_TRAIT(dummy, TRAIT_TOXIMMUNE, TRAIT_SOURCE_UNIT_TESTS)
+
+ // need to force apply some toxin damage since the TOXIMUNNE trait sets toxloss to 0 upon being added
+ apply_damage(dummy, 2, included_types = TOXLOSS, forced = TRUE)
+
+ // try to 'heal' again - this time it should just do nothing because we should be immune to any sort of toxin damage - including from inverted healing
+ apply_damage(dummy, -2, expected = 0, included_types = TOXLOSS)
+ verify_damage(dummy, 2, included_types = TOXLOSS)
+
+ // ok, let's try taking 'damage'. The inverted damage should still heal mobs with the TOXIMMUNE trait.
+ apply_damage(dummy, 2, expected = 2, included_types = TOXLOSS)
+ verify_damage(dummy, 0, included_types = TOXLOSS)
+
+ REMOVE_TRAIT(dummy, TRAIT_TOXINLOVER, TRAIT_SOURCE_UNIT_TESTS)
+ REMOVE_TRAIT(dummy, TRAIT_TOXIMMUNE, TRAIT_SOURCE_UNIT_TESTS)
+
+/// Testing cloneloss with TRAIT_NOCLONELOSS
+/datum/unit_test/mob_damage/proc/test_nocloneloss(mob/living/carbon/human/consistent/dummy)
+ // TRAIT_NOBREATH is supposed to prevent cloneloss damage and healing. Let's make sure that's the case.
+ ADD_TRAIT(dummy, TRAIT_NOCLONELOSS, TRAIT_SOURCE_UNIT_TESTS)
+ // force some cloneloss here
+ dummy.setCloneLoss(2, updating_health = FALSE, forced = TRUE)
+
+ // Try to take more cloneloss damage with TRAIT_NOCLONELOSS. It should not work.
+ apply_damage(dummy, 2, expected = 0, included_types = CLONELOSS)
+ verify_damage(dummy, 2, included_types = CLONELOSS)
+
+ // Healing the cloneloss should not work either, unless we force it
+ apply_damage(dummy, -2, expected = 0, included_types = CLONELOSS)
+ verify_damage(dummy, 2, included_types = CLONELOSS)
+ // so let's force it
+ apply_damage(dummy, -2, expected = 2, included_types = CLONELOSS, forced = TRUE)
+ verify_damage(dummy, 0, included_types = CLONELOSS)
+
+ REMOVE_TRAIT(dummy, TRAIT_NOCLONELOSS, TRAIT_SOURCE_UNIT_TESTS)
+
+/// Testing heal_ordered_damage()
+/datum/unit_test/mob_damage/proc/test_ordered_healing(mob/living/carbon/human/consistent/dummy)
+ var/damage_returned
+
+ // We apply 20 brute, 20 burn, and 20 toxin damage. 60 damage total
+ apply_damage(dummy, 20, included_types = TOXLOSS|BRUTELOSS|FIRELOSS)
+
+ // Heal 30 damage of that, starting from brute
+ damage_returned = round(dummy.heal_ordered_damage(30, list(BRUTE, BURN, TOX)), 1)
+ TEST_ASSERT_EQUAL(damage_returned, 30, \
+ "heal_ordered_damage() should have returned 30, but returned [damage_returned] instead!")
+
+ // Should have 10 burn damage and 20 toxins damage remaining, let's check
+ TEST_ASSERT_EQUAL(dummy.getBruteLoss(), 0, \
+ "[src] should have 0 brute damage, but has [dummy.getBruteLoss()] instead!")
+ TEST_ASSERT_EQUAL(dummy.getFireLoss(), 10, \
+ "[src] should have 10 burn damage, but has [dummy.getFireLoss()] instead!")
+ TEST_ASSERT_EQUAL(dummy.getToxLoss(), 20, \
+ "[src] should have 2 toxin damage, but has [dummy.getToxLoss()] instead!")
+
+ // Now heal the remaining 30, overhealing by 5.
+ damage_returned = round(dummy.heal_ordered_damage(35, list(BRUTE, BURN, TOX)), 1)
+ TEST_ASSERT_EQUAL(damage_returned, 30, \
+ "heal_ordered_damage() should have returned 0, but returned [damage_returned] instead!")
+
+ // Should have no damage remaining
+ TEST_ASSERT_EQUAL(dummy.getBruteLoss(), 0, \
+ "[src] should have 0 brute damage, but has [dummy.getBruteLoss()] instead!")
+ TEST_ASSERT_EQUAL(dummy.getFireLoss(), 0, \
+ "[src] should have 0 burn damage, but has [dummy.getFireLoss()] instead!")
+ TEST_ASSERT_EQUAL(dummy.getToxLoss(), 0, \
+ "[src] should have 0 toxin damage, but has [dummy.getToxLoss()] instead!")
+
+/// Tests that mob damage procs are working as intended for basic mobs
+/datum/unit_test/mob_damage/basic
+
+/datum/unit_test/mob_damage/basic/Run()
+ SSmobs.pause()
+ var/mob/living/basic/mouse/gray/gusgus = allocate(/mob/living/basic/mouse/gray)
+ // give gusgus a damage_coeff of 1 for this test
+ gusgus.damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, CLONE = 1, STAMINA = 1, OXY = 1)
+ // tank mouse
+ gusgus.maxHealth = 200
+
+ test_sanity_simple(gusgus)
+ test_sanity_complex(gusgus)
+
+/**
+ * Check that the mob has a specific amount of damage. Note: basic mobs have all incoming damage types besides stam converted into brute damage.
+ *
+ * By default this checks that the mob has of every type of damage.
+ * Arguments:
+ * * testing_mob - the mob to check the damage of
+ * * amount - the amount of damage to verify that the mob has
+ * * expected - the expected return value of the damage procs, if it differs from the default of (amount * 5)
+ * * included_types - Bitflag of damage types to check.
+ */
+/datum/unit_test/mob_damage/basic/verify_damage(mob/living/testing_mob, amount, expected, included_types = ALL)
+ if(included_types & TOXLOSS)
+ TEST_ASSERT_EQUAL(testing_mob.getToxLoss(), 0, \
+ "[testing_mob] should have [0] toxin damage, instead they have [testing_mob.getToxLoss()]!")
+ if(included_types & CLONELOSS)
+ TEST_ASSERT_EQUAL(testing_mob.getCloneLoss(), 0, \
+ "[testing_mob] should have [0] clone damage, instead they have [testing_mob.getCloneLoss()]!")
+ if(included_types & BRUTELOSS)
+ TEST_ASSERT_EQUAL(round(testing_mob.getBruteLoss(), 1), expected || amount * 5, \
+ "[testing_mob] should have [expected || amount * 5] brute damage, instead they have [testing_mob.getBruteLoss()]!")
+ if(included_types & FIRELOSS)
+ TEST_ASSERT_EQUAL(round(testing_mob.getFireLoss(), 1), 0, \
+ "[testing_mob] should have [0] burn damage, instead they have [testing_mob.getFireLoss()]!")
+ if(included_types & OXYLOSS)
+ TEST_ASSERT_EQUAL(testing_mob.getOxyLoss(), 0, \
+ "[testing_mob] should have [0] oxy damage, instead they have [testing_mob.getOxyLoss()]!")
+ if(included_types & STAMINALOSS)
+ TEST_ASSERT_EQUAL(testing_mob.getStaminaLoss(), amount, \
+ "[testing_mob] should have [amount] stamina damage, instead they have [testing_mob.getStaminaLoss()]!")
+
+/datum/unit_test/mob_damage/basic/test_sanity_simple(mob/living/basic/mouse/gray/gusgus)
+ // check to see if basic mob damage works
+
+ // Simple damage and healing
+ // Take 1 damage, heal for 1
+ apply_damage(gusgus, 1)
+ verify_damage(gusgus, 1)
+
+ apply_damage(gusgus, -1)
+ verify_damage(gusgus, 0)
+
+ // Give 2 damage of every time (translates to 10 brute, 2 staminaloss)
+ apply_damage(gusgus, 2)
+ verify_damage(gusgus, 2)
+
+ // underhealing: heal 1 damage of every type (translates to 5 brute, 1 staminaloss)
+ apply_damage(gusgus, -1)
+ verify_damage(gusgus, 1)
+
+ // overhealing
+
+ // heal 11 points of toxloss (should take care of all 5 brute damage remaining)
+ apply_damage(gusgus, -11, expected = 5, included_types = TOXLOSS)
+ // heal the remaining point of staminaloss
+ apply_damage(gusgus, -11, expected = 1, included_types = STAMINALOSS)
+ // heal 35 points of each type, we should already be at full health so nothing should happen
+ apply_damage(gusgus, -35, expected = 0)
+ verify_damage(gusgus, 0)
+
+/datum/unit_test/mob_damage/basic/test_sanity_complex(mob/living/basic/mouse/gray/gusgus)
+ var/damage_returned
+ // overall damage procs
+
+ // take 5 brute, 2 burn
+ damage_returned = gusgus.take_bodypart_damage(5, 2, updating_health = FALSE)
+ TEST_ASSERT_EQUAL(damage_returned, -7, \
+ "take_bodypart_damage() should have returned -7, but returned [damage_returned] instead!")
+
+ TEST_ASSERT_EQUAL(gusgus.bruteloss, 7, \
+ "Mouse should have 7 brute damage, instead they have [gusgus.bruteloss]!")
+ TEST_ASSERT_EQUAL(gusgus.fireloss, 0, \
+ "Mouse should have 0 burn damage, instead they have [gusgus.fireloss]!")
+
+ // heal 4 brute, 1 burn
+ damage_returned = gusgus.heal_bodypart_damage(4, 1, updating_health = FALSE)
+ TEST_ASSERT_EQUAL(damage_returned, 5, \
+ "heal_bodypart_damage() should have returned 5, but returned [damage_returned] instead!")
+
+ TEST_ASSERT_EQUAL(gusgus.bruteloss, 2, \
+ "Mouse should have 2 brute damage, instead they have [gusgus.bruteloss]!")
+ TEST_ASSERT_EQUAL(gusgus.fireloss, 0, \
+ "Mouse should have 0 burn damage, instead they have [gusgus.fireloss]!")
+
+ // heal 1 brute, 1 burn
+ damage_returned = gusgus.heal_overall_damage(1, 1, updating_health = FALSE)
+ TEST_ASSERT_EQUAL(damage_returned, 2, \
+ "heal_overall_damage() should have returned 2, but returned [damage_returned] instead!")
+
+ TEST_ASSERT_EQUAL(gusgus.bruteloss, 0, \
+ "Mouse should have 0 brute damage, instead they have [gusgus.bruteloss]!")
+ TEST_ASSERT_EQUAL(gusgus.fireloss, 0, \
+ "Mouse should have 0 burn damage, instead they have [gusgus.fireloss]!")
+
+ // take 50 brute, 50 burn
+ damage_returned = gusgus.take_overall_damage(3, 3, updating_health = FALSE)
+ TEST_ASSERT_EQUAL(damage_returned, -6, \
+ "take_overall_damage() should have returned -6, but returned [damage_returned] instead!")
+
+ verify_damage(gusgus, 1, expected = 6, included_types = BRUTELOSS)
+
+ // testing negative args with the overall damage procs
+
+ damage_returned = gusgus.take_bodypart_damage(-1, -1, updating_health = FALSE)
+ TEST_ASSERT_EQUAL(damage_returned, -2, \
+ "take_bodypart_damage() should have returned -2, but returned [damage_returned] instead!")
+
+ damage_returned = gusgus.heal_bodypart_damage(-1, -1, updating_health = FALSE)
+ TEST_ASSERT_EQUAL(damage_returned, 2, \
+ "heal_bodypart_damage() should have returned 2, but returned [damage_returned] instead!")
+
+ damage_returned = gusgus.take_overall_damage(-1, -1, updating_health = FALSE)
+ TEST_ASSERT_EQUAL(damage_returned, -2, \
+ "take_overall_damage() should have returned -2, but returned [damage_returned] instead!")
+
+ damage_returned = gusgus.heal_overall_damage(-1, -1, updating_health = FALSE)
+ TEST_ASSERT_EQUAL(damage_returned, 2, \
+ "heal_overall_damage() should have returned 2, but returned [damage_returned] instead!")
+
+ verify_damage(gusgus, 1, expected = 6, included_types = BRUTELOSS)
+
+ // testing overhealing
+
+ damage_returned = gusgus.heal_overall_damage(75, 99, updating_health = FALSE)
+ TEST_ASSERT_EQUAL(damage_returned, 6, \
+ "heal_overall_damage() should have returned 6, but returned [damage_returned] instead!")
+
+ verify_damage(gusgus, 0, included_types = BRUTELOSS)
diff --git a/code/modules/unit_tests/organs.dm b/code/modules/unit_tests/organs.dm
index 4c99bfaa339..4ba51e0870c 100644
--- a/code/modules/unit_tests/organs.dm
+++ b/code/modules/unit_tests/organs.dm
@@ -96,19 +96,22 @@
var/slot_to_use = test_organ.slot
// Tests [mob/living/proc/adjustOrganLoss]
- dummy.adjustOrganLoss(slot_to_use, test_organ.maxHealth * 10)
+ TEST_ASSERT_EQUAL(dummy.adjustOrganLoss(slot_to_use, test_organ.maxHealth * 10), -test_organ.maxHealth, \
+ "Mob level \"apply organ damage\" returned the wrong value for [slot_to_use] organ with default arguments.")
TEST_ASSERT_EQUAL(dummy.get_organ_loss(slot_to_use), test_organ.maxHealth, \
"Mob level \"apply organ damage\" can exceed the [slot_to_use] organ's damage cap with default arguments.")
dummy.fully_heal(HEAL_ORGANS)
// Tests [mob/living/proc/set_organ_damage]
- dummy.setOrganLoss(slot_to_use, test_organ.maxHealth * 10)
+ TEST_ASSERT_EQUAL(dummy.setOrganLoss(slot_to_use, test_organ.maxHealth * 10), -test_organ.maxHealth, \
+ "Mob level \"set organ damage\" returned the wrong value for [slot_to_use] organ with default arguments.")
TEST_ASSERT_EQUAL(dummy.get_organ_loss(slot_to_use), test_organ.maxHealth, \
"Mob level \"set organ damage\" can exceed the [slot_to_use] organ's damage cap with default arguments.")
dummy.fully_heal(HEAL_ORGANS)
// Tests [mob/living/proc/adjustOrganLoss] with a large max supplied
- dummy.adjustOrganLoss(slot_to_use, test_organ.maxHealth * 10, INFINITY)
+ TEST_ASSERT_EQUAL(dummy.adjustOrganLoss(slot_to_use, test_organ.maxHealth * 10, INFINITY), -test_organ.maxHealth, \
+ "Mob level \"apply organ damage\" returned the wrong value for [slot_to_use] organ with a large maximum supplied.")
TEST_ASSERT_EQUAL(dummy.get_organ_loss(slot_to_use), test_organ.maxHealth, \
"Mob level \"apply organ damage\" can exceed the [slot_to_use] organ's damage cap with a large maximum supplied.")
dummy.fully_heal(HEAL_ORGANS)
diff --git a/code/modules/unit_tests/simple_animal_freeze.dm b/code/modules/unit_tests/simple_animal_freeze.dm
index 181eeee72dc..312405d7382 100644
--- a/code/modules/unit_tests/simple_animal_freeze.dm
+++ b/code/modules/unit_tests/simple_animal_freeze.dm
@@ -108,7 +108,6 @@
/mob/living/simple_animal/hostile/heretic_summon/armsy/prime,
/mob/living/simple_animal/hostile/heretic_summon/ash_spirit,
/mob/living/simple_animal/hostile/heretic_summon/maid_in_the_mirror,
- /mob/living/simple_animal/hostile/heretic_summon/raw_prophet,
/mob/living/simple_animal/hostile/heretic_summon/rust_spirit,
/mob/living/simple_animal/hostile/heretic_summon/stalker,
/mob/living/simple_animal/hostile/illusion,
diff --git a/code/modules/vending/drinnerware.dm b/code/modules/vending/drinnerware.dm
index 2e00d9d2a01..c37750a2d3d 100644
--- a/code/modules/vending/drinnerware.dm
+++ b/code/modules/vending/drinnerware.dm
@@ -14,6 +14,7 @@
/obj/item/kitchen/spoon/soup_ladle = 3,
/obj/item/clothing/suit/apron/chef = 2,
/obj/item/kitchen/rollingpin = 2,
+ /obj/item/kitchen/tongs = 2,
/obj/item/knife/kitchen = 2,
),
),
diff --git a/code/modules/zombie/items.dm b/code/modules/zombie/items.dm
index 4258dc5a304..65716c0dbfa 100644
--- a/code/modules/zombie/items.dm
+++ b/code/modules/zombie/items.dm
@@ -75,11 +75,12 @@
var/hp_gained = target.maxHealth
target.investigate_log("has been devoured by a zombie.", INVESTIGATE_DEATHS)
target.gib()
- // zero as argument for no instant health update
- user.adjustBruteLoss(-hp_gained, 0)
- user.adjustToxLoss(-hp_gained, 0)
- user.adjustFireLoss(-hp_gained, 0)
- user.adjustCloneLoss(-hp_gained, 0)
- user.updatehealth()
- user.adjustOrganLoss(ORGAN_SLOT_BRAIN, -hp_gained) // Zom Bee gibbers "BRAAAAISNSs!1!"
+ var/need_mob_update
+ need_mob_update = user.adjustBruteLoss(-hp_gained, updating_health = FALSE)
+ need_mob_update += user.adjustToxLoss(-hp_gained, updating_health = FALSE)
+ need_mob_update += user.adjustFireLoss(-hp_gained, updating_health = FALSE)
+ need_mob_update += user.adjustCloneLoss(-hp_gained, updating_health = FALSE)
+ need_mob_update += user.adjustOrganLoss(ORGAN_SLOT_BRAIN, -hp_gained) // Zom Bee gibbers "BRAAAAISNSs!1!"
user.set_nutrition(min(user.nutrition + hp_gained, NUTRITION_LEVEL_FULL))
+ if(need_mob_update)
+ user.updatehealth()
diff --git a/config/lavaruinblacklist.txt b/config/lavaruinblacklist.txt
index 4332260d6be..a42196bf9d5 100644
--- a/config/lavaruinblacklist.txt
+++ b/config/lavaruinblacklist.txt
@@ -11,8 +11,9 @@
##RESPAWN
#_maps/RandomRuins/LavaRuins/lavaland_surface_seed_vault.dmm
-#_maps/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm
+_maps/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm
#modular_skyrat/modules/mapping/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1_skyrat.dmm
+#_maps/RandomRuins/LavaRuins/skyrat/lavaland_surface_ash_walker1_skyrat.dmm
#_maps/RandomRuins/AnywhereRuins/golem_ship.dmm
##SIN
@@ -39,4 +40,4 @@
#_maps/RandomRuins/LavaRuins/lavaland_surface_elephant_graveyard.dmm
#_maps/RandomRuins/LavaRuins/lavaland_surface_library.dmm
#_maps/RandomRuins/AnywhereRuins/fountain_hall.dmm
-#_maps/RandomRuins/LavaRuins/lavaland_surface_phonebooth.dmm
\ No newline at end of file
+#_maps/RandomRuins/LavaRuins/lavaland_surface_phonebooth.dmm
diff --git a/html/changelogs/archive/2023-10.yml b/html/changelogs/archive/2023-10.yml
index ccff91affb0..4acbbb235a8 100644
--- a/html/changelogs/archive/2023-10.yml
+++ b/html/changelogs/archive/2023-10.yml
@@ -120,3 +120,135 @@
that died within a round and were scanned, to be transferred to a new brain.
- rscadd: Adds in the NIFSoft Scryer, a NIFSoft that gives the user a Scryer they
can use to communicate with other Scryer users.
+2023-10-03:
+ SkyratBot:
+ - bugfix: fixed misplaced door on syndicate listening post
+ - rscadd: adds boxes of bandages, a quick healing item
+ - bugfix: Spiders, Morphs, Fire Sharks, and Regal Rats no longer have a reduced
+ click speed.
+ - image: Railings have had a visual update.
+ projectkepler-ru:
+ - balance: reverted the nerf on the X-01
+ softcerv:
+ - rscadd: Adds in Purpura Eye, a NIFSoft that allows for the user to hypnotize others.
+ vinylspiders:
+ - bugfix: the pollution system will no longer try (and fail) to pollute a turf from
+ nullspace
+2023-10-04:
+ Coded by Jacquerel, Sprited by Dalmationer:
+ - rscadd: Added tongs to the kitchen, which you can use to manipulate food from
+ further away
+ Fazzie:
+ - rscadd: Added a budget solar crate to the derelict teleporter room
+ - rscadd: Added a solar panel control to the north derelict solar
+ - qol: The derelict's AI coridoor is now shorter and prettier
+ - rscadd: A lot of new content has been added to the beach away mission
+ - qol: It also looks substantially better, too!
+ Motho:
+ - bugfix: An anonymous visitor to the NSV Void Raptor has turned in security's biosuit
+ to the lost and found. Security officers everywhere rejoice.
+ Paxilmaniac:
+ - rscadd: A significantly smaller selection of new SolFed weapons has taken the
+ place of the now missing Armadyne selection.
+ - rscdel: So basically, all of Armadyne is gone.
+ - qol: A large number of weapons now use singular interchangeable magazine types,
+ rather than having seven different 9mm magazines to do the same thing
+ - balance: Any weapon that was replaced is going to have different stats from what
+ they used to be, numbers subject to change
+ - sound: Several new firing sounds from TGMC for the new weapons
+ - image: Whole collection of new ammo, gun, case, and so on sprites by myself
+ - image: Gun case worn on the back sprites done by Zydras
+ - code_imp: Where applicable, containers spawning gun stuff use generate_items_inside,
+ which is much neater than spamming new x(src)
+ SkyratBot:
+ - bugfix: The Syndicate have fired their previous construction company after poor
+ results in recent outposts.
+ - qol: Departmental order consoles now alert their department via radio when their
+ cooldown expires
+ - bugfix: Fix butchered monkeys to transfer reagents and diseases to meat
+ - bugfix: Fix organs having no DNA and become bloody when violently removed.
+ - refactor: Raw Prophets now use the basic mob framework. Please report any unusual
+ behaviour.
+ - bugfix: Cutting open a hand-pressed paper bundle no longer deletes all of the
+ paper.
+ - balance: Kudzu will now be destroyed by adverse weather.
+ - balance: Kudzu will no longer spread over holes.
+ - refactor: fixed many instances of updatehealth() either being called needlessly
+ or not at all within on_mob_life() and in various other parts of the code
+ - refactor: damage procs now return useful information--the actual net change in
+ damage on the mob. added a unit test for this
+ - bugfix: Some icons for selecting character preferences are no longer scaled incorrectly.
+ ninjanomnom:
+ - admin: Appearance vars in VV now display instead of being left blank
+2023-10-05:
+ FIoppie:
+ - sound: '*flap now makes a fluttering noise for moth wings'
+ - sound: Moths now have a death sound
+ - qol: '*tremble emote now is just "trembles!" instead of "trembles in fear!"'
+ LT3:
+ - image: Added colourable arm and leg wraps
+ Melbert:
+ - qol: Moved a lot of maintenance spawnpoints out of non-maintenance rooms. Some
+ antags (paradox clone, fugitives, nightmares, spiders) are now less likely to
+ spawn in obvious places like the morgue, tech storage, or dorms rooms.
+ Motho:
+ - image: Sector 13's station air alarms and fire alarms have been updated to be
+ more in line with other frontier station models.
+ SkyratBot:
+ - admin: Admins can turn off dynamic rulesets (or force them on despite not meeting
+ the qualification criteria) on a per-round basis.
+ - rscadd: The funds the syndicate have been saving by restricting galley access
+ has been suddenly funneled into a singular mosaic pattern in the experiments
+ wing.
+ - balance: CQC legsweeps now cause knockdown instead of paralysis.
+ - balance: CQC kicks now knockout a target on the floor for ten seconds if they
+ reach stam crit. Helmet protection shortens the knockout length.
+ - bugfix: Your heart will no longer be deleted if an admin heals you while you have
+ corazargh in your system.
+ - refactor: The cursed heart has been streamlined a bit, and now gives you a visual
+ cooldown for when you can beat your heart again.
+ Wallem:
+ - rscadd: Adds The Hand of Midas, an ancient Egyptian matchlock pistol.
+ honkpocket:
+ - bugfix: Extra magazines for all the Foam Force guns are now purchasable from cargo
+ imports
+ - rscadd: The Foam Force dart collector MOD modules are now purchasable from cargo
+ imports
+ - sound: added a unique racking sfx for the sol 'Renoster' shotgun
+ softcerv:
+ - qol: NIFSofts now use the same TGUI as their parent NIF.
+ tf-4:
+ - bugfix: Fixed some weirdness with mould mob attacks.
+ - qol: Mold mobs delete themselves on death.
+2023-10-06:
+ LT3:
+ - image: Job icon for departmental guards, DS2 and other SR specific jobs are properly
+ aligned
+ Majkl-J:
+ - bugfix: Table to the cafe food processor
+ RatFromTheJungle:
+ - balance: Interdyne now spawns with Sidano SMG's, instead of .50 snipers
+ - bugfix: you can now actually wear the 'LIZARED' top, yippie!
+ SkyratBot:
+ - bugfix: The Galactic Materials Market now offers things for sale as it should.
+ - rscadd: Added blackout, happens when you drink...ALOT
+ - bugfix: plumbing reaction chamber now balances the ph of it's solution correctly
+ to the best of it's ability so no guarantees
+ - code_imp: converted plumbing reaction chamber & mixing chamber UI files to Typescript
+ - refactor: plumbing mixing chamber now also accepts an TGUI input list to input
+ it's chemicals
+ - image: We have received a new shipment of IDs, as the old ones were found out
+ to be haunted.
+ - image: Laser tag red team ID has received a massive nerf
+ - image: Station budget cards have gotten a facelift
+ - image: Emags and Doorjacks
+ - bugfix: Numbered prisoner IDs will now be legible
+ Wallem:
+ - rscadd: Buffs the Active Sonar module with a radial scan, and makes the power
+ costs more in-line with other modules.
+ softcerv:
+ - bugfix: the ghost role NIF boxes now contain the Purpura Eye NIFSoft
+ vinylspiders:
+ - bugfix: fixes gender shaping and height offsets on underwear
+ - bugfix: female gender shaping now works with digi jumpsuits
+ - bugfix: fixed rainbow jumpsuit digi sprite
diff --git a/icons/effects/beam.dmi b/icons/effects/beam.dmi
index ae695c3227f..12e3ce9f7d5 100644
Binary files a/icons/effects/beam.dmi and b/icons/effects/beam.dmi differ
diff --git a/icons/effects/effects.dmi b/icons/effects/effects.dmi
index d59f065da28..b01986a9522 100644
Binary files a/icons/effects/effects.dmi and b/icons/effects/effects.dmi differ
diff --git a/icons/hud/screen_alert.dmi b/icons/hud/screen_alert.dmi
index 1edd4d29cb5..0fa8ec21850 100755
Binary files a/icons/hud/screen_alert.dmi and b/icons/hud/screen_alert.dmi differ
diff --git a/icons/mob/effects/debuff_overlays.dmi b/icons/mob/effects/debuff_overlays.dmi
new file mode 100644
index 00000000000..383ce22aabe
Binary files /dev/null and b/icons/mob/effects/debuff_overlays.dmi differ
diff --git a/icons/obj/card.dmi b/icons/obj/card.dmi
index 2bbec93eed2..4172a0a3641 100644
Binary files a/icons/obj/card.dmi and b/icons/obj/card.dmi differ
diff --git a/icons/obj/service/kitchen.dmi b/icons/obj/service/kitchen.dmi
index cb47ddf35a2..aeafe2591e9 100644
Binary files a/icons/obj/service/kitchen.dmi and b/icons/obj/service/kitchen.dmi differ
diff --git a/icons/obj/storage/storage.dmi b/icons/obj/storage/storage.dmi
index cdaf8cae339..a55606fa3b3 100644
Binary files a/icons/obj/storage/storage.dmi and b/icons/obj/storage/storage.dmi differ
diff --git a/icons/obj/weapons/guns/magic.dmi b/icons/obj/weapons/guns/magic.dmi
index fe3eb6ae895..7cab0cdfc25 100644
Binary files a/icons/obj/weapons/guns/magic.dmi and b/icons/obj/weapons/guns/magic.dmi differ
diff --git a/modular_skyrat/master_files/code/datums/id_trim/jobs.dm b/modular_skyrat/master_files/code/datums/id_trim/jobs.dm
index b26e823b0e0..9968bd4ee0e 100644
--- a/modular_skyrat/master_files/code/datums/id_trim/jobs.dm
+++ b/modular_skyrat/master_files/code/datums/id_trim/jobs.dm
@@ -1,21 +1,17 @@
// MODULAR ID TRIM ACCESS OVERRIDES GO HERE!!
/datum/id_trim/job/head_of_security
- trim_icon = 'modular_skyrat/master_files/icons/obj/card.dmi'
subdepartment_color = COLOR_ASSEMBLY_BLACK // This actually is the shade of grey formerly used by the static icons! Didn't have to add anything extra! Just thought that was neat.
/datum/id_trim/job/warden
- trim_icon = 'modular_skyrat/master_files/icons/obj/card.dmi'
department_color = COLOR_ASSEMBLY_BLACK
subdepartment_color = COLOR_ASSEMBLY_BLACK
/datum/id_trim/job/security_officer
- trim_icon = 'modular_skyrat/master_files/icons/obj/card.dmi'
department_color = COLOR_ASSEMBLY_BLACK
subdepartment_color = COLOR_ASSEMBLY_BLACK
/datum/id_trim/job/detective
- trim_icon = 'modular_skyrat/master_files/icons/obj/card.dmi'
department_color = COLOR_ASSEMBLY_BLACK
subdepartment_color = COLOR_ASSEMBLY_BLACK
diff --git a/modular_skyrat/master_files/code/datums/storage/subtypes/pockets.dm b/modular_skyrat/master_files/code/datums/storage/subtypes/pockets.dm
index 491eb74443a..75a2f01aa99 100644
--- a/modular_skyrat/master_files/code/datums/storage/subtypes/pockets.dm
+++ b/modular_skyrat/master_files/code/datums/storage/subtypes/pockets.dm
@@ -4,18 +4,8 @@
. = ..()
add_holdable(list(
- // Adds pistol magazines from guncargo companies in their respective order
- /obj/item/ammo_box/magazine/multi_sprite/pdh,
- /obj/item/ammo_box/magazine/multi_sprite/ladon,
- /obj/item/ammo_box/magazine/multi_sprite/firefly,
- /obj/item/ammo_box/magazine/multi_sprite/pdh_peacekeeper,
- /obj/item/ammo_box/magazine/multi_sprite/mk58,
- /obj/item/ammo_box/magazine/m45,
- /obj/item/ammo_box/magazine/pepperball, // boot pepper
- /obj/item/ammo_box/magazine/multi_sprite/g17,
- /obj/item/ammo_box/magazine/multi_sprite/cfa_ruby,
- /obj/item/ammo_box/magazine/multi_sprite/cfa_snub,
- /obj/item/ammo_box/magazine/multi_sprite/makarov,
+ /obj/item/ammo_box/magazine/c35sol_pistol,
+ /obj/item/ammo_box/magazine/c585trappiste_pistol,
/obj/item/ammo_box/magazine/m9mm_aps,
/obj/item/ammo_box/magazine/toy/pistol,
))
diff --git a/modular_skyrat/master_files/code/game/objects/items/cards_ids.dm b/modular_skyrat/master_files/code/game/objects/items/cards_ids.dm
index 64f40cb5f86..b28befb741e 100644
--- a/modular_skyrat/master_files/code/game/objects/items/cards_ids.dm
+++ b/modular_skyrat/master_files/code/game/objects/items/cards_ids.dm
@@ -3,13 +3,13 @@
name = "generic silver identification card"
icon = 'modular_skyrat/master_files/icons/obj/card.dmi'
icon_state = "card_silvergen"
- assigned_icon_state = "assigned_silver"
+ assigned_icon_state = null
/obj/item/card/id/advanced/gold/generic
name = "generic gold identification card"
icon = 'modular_skyrat/master_files/icons/obj/card.dmi'
icon_state = "card_goldgen"
- assigned_icon_state = "assigned_gold"
+ assigned_icon_state = null
// COLOURABLE
/obj/item/card/id/advanced/colourable
diff --git a/modular_skyrat/master_files/code/modules/client/preferences_savefile.dm b/modular_skyrat/master_files/code/modules/client/preferences_savefile.dm
index f7ffc6fddd6..be228d89f10 100644
--- a/modular_skyrat/master_files/code/modules/client/preferences_savefile.dm
+++ b/modular_skyrat/master_files/code/modules/client/preferences_savefile.dm
@@ -213,7 +213,6 @@
var/static/list/undershirt_to_bra = list(
"Bra, Sports" = "Bra, Sports",
"Sports Bra (Alt)" = "Sports Bra (Alt)",
- "LIZARED Top" = "LIZARED Top",
"Bra" = "Bra",
"Bra - Alt" = "Bra - Alt",
"Bra - Thin" = "Bra - Thin",
diff --git a/modular_skyrat/master_files/code/modules/clothing/under/color.dm b/modular_skyrat/master_files/code/modules/clothing/under/color.dm
index 07327d062b8..094dddaabd3 100644
--- a/modular_skyrat/master_files/code/modules/clothing/under/color.dm
+++ b/modular_skyrat/master_files/code/modules/clothing/under/color.dm
@@ -1,6 +1,9 @@
/obj/item/clothing/under/color
greyscale_config_worn_monkey = /datum/greyscale_config/jumpsuit/worn/monkey
+/obj/item/clothing/under/color/rainbow
+ worn_icon_digi = 'modular_skyrat/master_files/icons/mob/clothing/under/color_digi.dmi'
+
/**
* Random jumpsuit is the preferred style of the wearer if loaded as an outfit.
* This is cleaner than creating a ../skirt variant as skirts are precached into SSwardrobe
diff --git a/modular_skyrat/master_files/code/modules/clothing/under/jobs/centcom.dm b/modular_skyrat/master_files/code/modules/clothing/under/jobs/centcom.dm
index 9c48b5a2736..05aa24276d8 100644
--- a/modular_skyrat/master_files/code/modules/clothing/under/jobs/centcom.dm
+++ b/modular_skyrat/master_files/code/modules/clothing/under/jobs/centcom.dm
@@ -13,12 +13,6 @@
*/
//Check modular_skyrat\modules\nanotrasen_naval_command\code\clothing.dm for more of these! (Or, currently, ALL of these.)
-/*
-* ARMADYNE
-*/
-//Check modular_skyrat\modules\sec_haul\code\peacekeeper\armadyne_clothing.dm for these (ORION TODO: debate moving them all into this one file - uniforms, at least)
-//(TODO applies to NT as well)
-
/*
* LOPLAND
*/
diff --git a/modular_skyrat/master_files/icons/donator/mob/clothing/hands.dmi b/modular_skyrat/master_files/icons/donator/mob/clothing/hands.dmi
index 44e58131a33..93cadcbdbdb 100644
Binary files a/modular_skyrat/master_files/icons/donator/mob/clothing/hands.dmi and b/modular_skyrat/master_files/icons/donator/mob/clothing/hands.dmi differ
diff --git a/modular_skyrat/master_files/icons/donator/obj/clothing/gloves.dmi b/modular_skyrat/master_files/icons/donator/obj/clothing/gloves.dmi
index 9c82af8e8b3..62bfc6d5433 100644
Binary files a/modular_skyrat/master_files/icons/donator/obj/clothing/gloves.dmi and b/modular_skyrat/master_files/icons/donator/obj/clothing/gloves.dmi differ
diff --git a/modular_skyrat/master_files/icons/mob/clothing/under/color_digi.dmi b/modular_skyrat/master_files/icons/mob/clothing/under/color_digi.dmi
index 1d7d6c0e933..1366a6ba1ad 100644
Binary files a/modular_skyrat/master_files/icons/mob/clothing/under/color_digi.dmi and b/modular_skyrat/master_files/icons/mob/clothing/under/color_digi.dmi differ
diff --git a/modular_skyrat/master_files/icons/obj/card.dmi b/modular_skyrat/master_files/icons/obj/card.dmi
index cc5b4eb3a0a..a0d282967d0 100644
Binary files a/modular_skyrat/master_files/icons/obj/card.dmi and b/modular_skyrat/master_files/icons/obj/card.dmi differ
diff --git a/modular_skyrat/modules/GAGS/greyscale_configs.dm b/modular_skyrat/modules/GAGS/greyscale_configs.dm
index 36870626d5d..9ee547d060e 100644
--- a/modular_skyrat/modules/GAGS/greyscale_configs.dm
+++ b/modular_skyrat/modules/GAGS/greyscale_configs.dm
@@ -1056,18 +1056,41 @@ digi
// WRAPS
-/datum/greyscale_config/wraps
+/datum/greyscale_config/clothwraps
name = "Cloth Wraps"
icon_file = 'modular_skyrat/modules/GAGS/icons/shoes.dmi'
json_config = 'modular_skyrat/modules/GAGS/json_configs/wraps/wraps.json'
-/datum/greyscale_config/wraps/worn
+/datum/greyscale_config/clothwraps/worn
name = "Cloth Wraps (Worn)"
json_config = 'modular_skyrat/modules/GAGS/json_configs/wraps/wraps_worn.json'
-/datum/greyscale_config/wraps/worn/digi
+/datum/greyscale_config/clothwraps/worn/digi
name = "Cloth Wraps (Worn, Digi)"
+/datum/greyscale_config/legwraps
+ name = "Leg Wraps"
+ icon_file = 'modular_skyrat/modules/GAGS/icons/shoes.dmi'
+ json_config = 'modular_skyrat/modules/GAGS/json_configs/wraps/legwraps.json'
+
+/datum/greyscale_config/legwraps/worn
+ name = "Leg Wraps (Worn)"
+ json_config = 'modular_skyrat/modules/GAGS/json_configs/wraps/legwraps_worn.json'
+
+/datum/greyscale_config/legwraps/worn/digi
+ name = "Leg Wraps (Worn, Digi)"
+ json_config = 'modular_skyrat/modules/GAGS/json_configs/wraps/legwraps_worn_digi.json'
+
+/datum/greyscale_config/armwraps
+ name = "Cloth Arm Wraps"
+ icon_file = 'modular_skyrat/master_files/icons/donator/obj/clothing/gloves.dmi'
+ json_config = 'modular_skyrat/modules/GAGS/json_configs/arm_wraps/arm_wraps.json'
+
+/datum/greyscale_config/armwraps/worn
+ name = "Cloth Arm Wraps (Worn)"
+ icon_file = 'modular_skyrat/master_files/icons/donator/mob/clothing/hands.dmi'
+ json_config = 'modular_skyrat/modules/GAGS/json_configs/arm_wraps/arm_wraps_worn.json'
+
// MISC SHOES
/datum/greyscale_config/heels
diff --git a/modular_skyrat/modules/GAGS/icons/shoes.dmi b/modular_skyrat/modules/GAGS/icons/shoes.dmi
index 154b6f312ba..243f4ff5ec4 100644
Binary files a/modular_skyrat/modules/GAGS/icons/shoes.dmi and b/modular_skyrat/modules/GAGS/icons/shoes.dmi differ
diff --git a/modular_skyrat/modules/GAGS/json_configs/arm_wraps/arm_wraps.json b/modular_skyrat/modules/GAGS/json_configs/arm_wraps/arm_wraps.json
new file mode 100644
index 00000000000..cfe620714a3
--- /dev/null
+++ b/modular_skyrat/modules/GAGS/json_configs/arm_wraps/arm_wraps.json
@@ -0,0 +1,10 @@
+{
+ "arm_wraps": [
+ {
+ "type": "icon_state",
+ "icon_state": "arm_wraps",
+ "blend_mode": "overlay",
+ "color_ids": [ 1 ]
+ }
+ ]
+}
diff --git a/modular_skyrat/modules/GAGS/json_configs/arm_wraps/arm_wraps_worn.json b/modular_skyrat/modules/GAGS/json_configs/arm_wraps/arm_wraps_worn.json
new file mode 100644
index 00000000000..cfe620714a3
--- /dev/null
+++ b/modular_skyrat/modules/GAGS/json_configs/arm_wraps/arm_wraps_worn.json
@@ -0,0 +1,10 @@
+{
+ "arm_wraps": [
+ {
+ "type": "icon_state",
+ "icon_state": "arm_wraps",
+ "blend_mode": "overlay",
+ "color_ids": [ 1 ]
+ }
+ ]
+}
diff --git a/modular_skyrat/modules/GAGS/json_configs/wraps/legwraps.json b/modular_skyrat/modules/GAGS/json_configs/wraps/legwraps.json
new file mode 100644
index 00000000000..0e605054f90
--- /dev/null
+++ b/modular_skyrat/modules/GAGS/json_configs/wraps/legwraps.json
@@ -0,0 +1,10 @@
+{
+ "legwrap": [
+ {
+ "type": "icon_state",
+ "icon_state": "legwrap_obj",
+ "blend_mode": "overlay",
+ "color_ids": [ 1 ]
+ }
+ ]
+}
diff --git a/modular_skyrat/modules/GAGS/json_configs/wraps/legwraps_worn.json b/modular_skyrat/modules/GAGS/json_configs/wraps/legwraps_worn.json
new file mode 100644
index 00000000000..8ddd9e1dc3b
--- /dev/null
+++ b/modular_skyrat/modules/GAGS/json_configs/wraps/legwraps_worn.json
@@ -0,0 +1,10 @@
+{
+ "legwrap": [
+ {
+ "type": "icon_state",
+ "icon_state": "legwrap_mob",
+ "blend_mode": "overlay",
+ "color_ids": [ 1 ]
+ }
+ ]
+}
diff --git a/modular_skyrat/modules/GAGS/json_configs/wraps/legwraps_worn_digi.json b/modular_skyrat/modules/GAGS/json_configs/wraps/legwraps_worn_digi.json
new file mode 100644
index 00000000000..833a458c853
--- /dev/null
+++ b/modular_skyrat/modules/GAGS/json_configs/wraps/legwraps_worn_digi.json
@@ -0,0 +1,10 @@
+{
+ "legwrap": [
+ {
+ "type": "icon_state",
+ "icon_state": "legwrap_mob_digi",
+ "blend_mode": "overlay",
+ "color_ids": [ 1 ]
+ }
+ ]
+}
diff --git a/modular_skyrat/modules/aesthetics/airalarm/code/airalarm.dm b/modular_skyrat/modules/aesthetics/airalarm/code/airalarm.dm
index f3675f8e226..6792118bbaa 100644
--- a/modular_skyrat/modules/aesthetics/airalarm/code/airalarm.dm
+++ b/modular_skyrat/modules/aesthetics/airalarm/code/airalarm.dm
@@ -1,6 +1,5 @@
/obj/machinery/airalarm
- icon = 'modular_skyrat/modules/aesthetics/airalarm/icons/airalarm.dmi'
- var/light_mask = "alarm-light-mask"
+ icon = 'icons/obj/machines/wallmounts.dmi'
/obj/machinery/airalarm/update_appearance(updates)
. = ..()
diff --git a/modular_skyrat/modules/aesthetics/firealarm/icons/firealarm.dmi b/modular_skyrat/modules/aesthetics/firealarm/icons/firealarm.dmi
index 20adc064d32..ce8c37b6004 100644
Binary files a/modular_skyrat/modules/aesthetics/firealarm/icons/firealarm.dmi and b/modular_skyrat/modules/aesthetics/firealarm/icons/firealarm.dmi differ
diff --git a/modular_skyrat/modules/aesthetics/guns/code/guns.dm b/modular_skyrat/modules/aesthetics/guns/code/guns.dm
index 767ca1608c1..4bb8e23dbe2 100644
--- a/modular_skyrat/modules/aesthetics/guns/code/guns.dm
+++ b/modular_skyrat/modules/aesthetics/guns/code/guns.dm
@@ -75,33 +75,6 @@
lefthand_file = 'icons/mob/inhands/weapons/guns_lefthand.dmi'
righthand_file = 'icons/mob/inhands/weapons/guns_righthand.dmi'
-/obj/item/gun/ballistic/shotgun/riot
- name = "\improper Peacekeeper shotgun"
- desc = "A Nanotrasen-made riot control shotgun fitted with an extended tube and a fixed tactical stock."
- icon = 'modular_skyrat/modules/aesthetics/guns/icons/guns.dmi'
- worn_icon = 'modular_skyrat/modules/aesthetics/guns/icons/guns_back.dmi'
- lefthand_file = 'modular_skyrat/modules/aesthetics/guns/icons/guns_lefthand.dmi'
- righthand_file = 'modular_skyrat/modules/aesthetics/guns/icons/guns_righthand.dmi'
- inhand_icon_state = "riot_shotgun"
- inhand_x_dimension = 32
- inhand_y_dimension = 32
- can_suppress = TRUE
- suppressed_sound = 'modular_skyrat/modules/aesthetics/guns/sound/suppressed_shotgun.ogg'
- suppressed_volume = 100
- vary_fire_sound = TRUE
- fire_sound = 'modular_skyrat/modules/aesthetics/guns/sound/shotgun_light.ogg'
-
-/obj/item/gun/ballistic/shotgun/riot/syndicate
- name = "\improper Peacebreaker shotgun"
- desc = "A Scarborough riot control shotgun fitted with a crimson furnishing and a wooden tactical stock. You swear you've seen this model elsewhere before..."
- icon_state = "riotshotgun_syndie"
- inhand_icon_state = "riot_shotgun_syndie"
- can_be_sawn_off = FALSE
- can_suppress = FALSE
-
-/obj/item/gun/ballistic/shotgun/riot/syndicate/give_manufacturer_examine()
- AddElement(/datum/element/manufacturer_examine, COMPANY_SCARBOROUGH)
-
/obj/item/gun/ballistic/shotgun/automatic/combat
name = "\improper Peacekeeper combat shotgun"
desc = "A semi-automatic Nanotrasen Peacekeeper shotgun with tactical furnishing and heavier internals meant for sustained fire. Lacks a threaded barrel."
@@ -327,28 +300,6 @@
desc = "One of countless obsolete ballistic rifles that still sees use as a cheap deterrent. Uses 10mm ammo and its bulky frame prevents one-hand firing."
icon = 'modular_skyrat/modules/aesthetics/guns/icons/guns.dmi'
-/obj/item/gun/ballistic/automatic/ar/modular/model75
- name = "\improper NT ARG-75"
- desc = "A contemporary rifle manufactured by NT chambered for .310 Strilka. It's equipped with a heavy duty integrally suppressed barrel, CQB scope and a topmounted laser sight."
- icon_state = "arg75"
- icon = 'modular_skyrat/modules/aesthetics/guns/icons/guns.dmi'
- fire_sound = 'sound/weapons/gun/pistol/shot_suppressed.ogg'
- fire_delay = 5
- fire_sound_volume = 90
- accepted_magazine_type = /obj/item/ammo_box/magazine/multi_sprite/ostwind/arg75
-
-/obj/item/gun/ballistic/automatic/ar/modular/model75/give_manufacturer_examine()
- AddElement(/datum/element/manufacturer_examine, COMPANY_NANOTRASEN)
-
-/obj/item/ammo_box/magazine/multi_sprite/ostwind/arg75
- name = "\improper ARG-75 magazine"
- desc = "A twenty round double-stack magazine for the NT ARG-75 rifle. Chambered in .310 Strilka."
- icon = 'modular_skyrat/modules/sec_haul/icons/guns/mags.dmi'
- icon_state = "pcr"
- ammo_type = /obj/item/ammo_casing/strilka310
- caliber = CALIBER_STRILKA310
- max_ammo = 20
-
// GUBMAN3 - FULL BULLET RENAME
// i loathe the above
diff --git a/modular_skyrat/modules/aesthetics/guns/icons/guns.dmi b/modular_skyrat/modules/aesthetics/guns/icons/guns.dmi
index 3933f899038..deb9cd5931e 100644
Binary files a/modular_skyrat/modules/aesthetics/guns/icons/guns.dmi and b/modular_skyrat/modules/aesthetics/guns/icons/guns.dmi differ
diff --git a/modular_skyrat/modules/aesthetics/guns/icons/guns_back.dmi b/modular_skyrat/modules/aesthetics/guns/icons/guns_back.dmi
index bc77592a879..471407b916e 100644
Binary files a/modular_skyrat/modules/aesthetics/guns/icons/guns_back.dmi and b/modular_skyrat/modules/aesthetics/guns/icons/guns_back.dmi differ
diff --git a/modular_skyrat/modules/aesthetics/guns/icons/guns_lefthand.dmi b/modular_skyrat/modules/aesthetics/guns/icons/guns_lefthand.dmi
index 0b1ab1864f4..131c63fca3b 100644
Binary files a/modular_skyrat/modules/aesthetics/guns/icons/guns_lefthand.dmi and b/modular_skyrat/modules/aesthetics/guns/icons/guns_lefthand.dmi differ
diff --git a/modular_skyrat/modules/aesthetics/guns/icons/guns_righthand.dmi b/modular_skyrat/modules/aesthetics/guns/icons/guns_righthand.dmi
index 76ae0487b9f..7907e543b89 100644
Binary files a/modular_skyrat/modules/aesthetics/guns/icons/guns_righthand.dmi and b/modular_skyrat/modules/aesthetics/guns/icons/guns_righthand.dmi differ
diff --git a/modular_skyrat/modules/ammo_workbench/code/design_disks.dm b/modular_skyrat/modules/ammo_workbench/code/design_disks.dm
index f7955d053e0..26e6302c6da 100644
--- a/modular_skyrat/modules/ammo_workbench/code/design_disks.dm
+++ b/modular_skyrat/modules/ammo_workbench/code/design_disks.dm
@@ -1,5 +1,5 @@
/obj/item/disk/ammo_workbench
- name = "Armadyne Munitions blueprint datadisk"
+ name = "munitions blueprint datadisk"
desc = "You shouldn't be seeing this!"
/// For doing things when installed/downloaded onto an ammo bench.
@@ -9,8 +9,8 @@
/obj/item/disk/ammo_workbench/advanced
name = "advanced munitions datadisk"
- desc = "An Armadyne datadisk filled with advanced munition fabrication data for the ammunition workbench, including lethal ammotypes if not previously enabled. \
- Armadyne's munitions division does not take responsibility for any incidents that occur if safeties were circumvented beforehand."
+ desc = "An datadisk filled with advanced munition fabrication data for the ammunition workbench, including lethal ammotypes if not previously enabled. \
+ No parties are liable for any incidents that occur if safeties were circumvented beforehand."
/obj/item/disk/ammo_workbench/advanced/on_bench_install(obj/machinery/ammo_workbench/ammobench)
ammobench.allowed_harmful = TRUE
diff --git a/modular_skyrat/modules/assault_operatives/code/armaments/_armament_primary.dm b/modular_skyrat/modules/assault_operatives/code/armaments/_armament_primary.dm
index ff55e715b0e..e2ef34a2972 100644
--- a/modular_skyrat/modules/assault_operatives/code/armaments/_armament_primary.dm
+++ b/modular_skyrat/modules/assault_operatives/code/armaments/_armament_primary.dm
@@ -7,8 +7,8 @@
#define OPS_SUBCATEGORY_SHOTGUN "Shotguns"
#define OPS_SUBCATEGORY_SHOTGUN_AMMO "Speciality Shotgun Ammo"
-#define OPS_SUBCATEGORY_SNIPER "Marksman Rifles"
-#define OPS_SUBCATEGORY_SNIPER_AMMO "Speciality Marksman Rifle Ammo"
+#define OPS_SUBCATEGORY_SNIPER "Grenade Launchers"
+#define OPS_SUBCATEGORY_SNIPER_AMMO "Speciality Grenade Launcher Ammo"
/datum/armament_entry/assault_operatives/primary
category = "Long Arms"
@@ -20,50 +20,67 @@
subcategory = OPS_SUBCATEGORY_RIFLE
/datum/armament_entry/assault_operatives/primary/rifle/assault_ops_rifle
- item_type = /obj/item/gun/ballistic/automatic/assault_ops_rifle
+ item_type = /obj/item/gun/ballistic/automatic/sol_rifle/evil
/datum/armament_entry/assault_operatives/primary/rifle_ammo
subcategory = OPS_SUBCATEGORY_RIFLE_AMMO
max_purchase = 10
cost = 1
-/datum/armament_entry/assault_operatives/primary/rifle_ammo/rubber
- name = "\improper IGE-110 rubber magazine"
- description = "Rifle ammo that is more likely to exhaust whoever its shot at, rather than killing them."
- item_type = /obj/item/ammo_box/magazine/multi_sprite/assault_ops_rifle/rubber
+/datum/armament_entry/assault_operatives/primary/rifle_ammo/standard
+ item_type = /obj/item/ammo_box/magazine/c40sol_rifle/starts_empty
+ cost = 0
-/datum/armament_entry/assault_operatives/primary/rifle_ammo/ap
- name = "\improper IGE-110 armor piercing magazine"
- description = "Rifle ammo built specifically to penetrate through armor."
- item_type = /obj/item/ammo_box/magazine/multi_sprite/assault_ops_rifle/ap
+/datum/armament_entry/assault_operatives/primary/rifle_ammo/drum
+ item_type = /obj/item/ammo_box/magazine/c40sol_rifle/drum/starts_empty
+ cost = 0
+
+/datum/armament_entry/assault_operatives/primary/rifle_ammo/c40sol
+ item_type = /obj/item/ammo_box/c40sol
+
+/datum/armament_entry/assault_operatives/primary/rifle_ammo/c40sol_disabler
+ item_type = /obj/item/ammo_box/c40sol/fragmentation
+
+/datum/armament_entry/assault_operatives/primary/rifle_ammo/c40sol_pierce
+ item_type = /obj/item/ammo_box/c40sol/pierce
+
+/datum/armament_entry/assault_operatives/primary/rifle_ammo/c40sol_incendiary
+ item_type = /obj/item/ammo_box/c40sol/incendiary
/datum/armament_entry/assault_operatives/primary/submachinegun
subcategory = OPS_SUBCATEGORY_SMG
/datum/armament_entry/assault_operatives/primary/submachinegun/assault_ops_smg
- item_type = /obj/item/gun/ballistic/automatic/assault_ops_smg
+ item_type = /obj/item/gun/ballistic/automatic/sol_smg/evil
/datum/armament_entry/assault_operatives/primary/submachinegun_ammo
subcategory = OPS_SUBCATEGORY_SMG_AMMO
max_purchase = 10
cost = 1
-/datum/armament_entry/assault_operatives/primary/submachinegun_ammo/rubber
- name = "\improper IGE-260 rubber magazine"
- description = "Submachine gun ammo that is more likely to exhaust whoever its shot at, rather than killing them."
- item_type = /obj/item/ammo_box/magazine/multi_sprite/assault_ops_smg/rubber
+/datum/armament_entry/assault_operatives/primary/submachinegun_ammo/standard
+ item_type = /obj/item/ammo_box/magazine/c35sol_pistol/starts_empty
+ cost = 0
+
+/datum/armament_entry/assault_operatives/primary/submachinegun_ammo/extended
+ item_type = /obj/item/ammo_box/magazine/c35sol_pistol/stendo/starts_empty
+ cost = 0
+
+/datum/armament_entry/assault_operatives/primary/submachinegun_ammo/c35sol
+ item_type = /obj/item/ammo_box/c35sol
-/datum/armament_entry/assault_operatives/primary/submachinegun_ammo/hp
- name = "\improper IGE-260 hollowpoint magazine"
- description = "Submachine gun ammo that hurts unarmored targets more, in exchange for worse performance against armor."
- item_type = /obj/item/ammo_box/magazine/multi_sprite/assault_ops_smg/hp
+/datum/armament_entry/assault_operatives/primary/submachinegun_ammo/c35sol_disabler
+ item_type = /obj/item/ammo_box/c35sol/incapacitator
+
+/datum/armament_entry/assault_operatives/primary/submachinegun_ammo/c35sol_pierce
+ item_type = /obj/item/ammo_box/c35sol/ripper
/datum/armament_entry/assault_operatives/primary/shotgun
subcategory = OPS_SUBCATEGORY_SHOTGUN
/datum/armament_entry/assault_operatives/primary/shotgun/assault_ops_shotgun
- item_type = /obj/item/gun/ballistic/automatic/assault_ops_shotgun
+ item_type = /obj/item/gun/ballistic/shotgun/riot/sol/evil
/datum/armament_entry/assault_operatives/primary/shotgun_ammo
subcategory = OPS_SUBCATEGORY_SHOTGUN_AMMO
@@ -71,50 +88,53 @@
cost = 1
/datum/armament_entry/assault_operatives/primary/shotgun_ammo/rubber
- name = "\improper IGE-340 rubbershot magazine"
- description = "Shotgun ammo that's much like buckshot, but more likely to exhaust whoever its shot at rather than killing them."
- item_type = /obj/item/ammo_box/magazine/multi_sprite/assault_ops_shotgun/rubbershot
+ item_type = /obj/item/ammo_box/advanced/s12gauge/rubber
/datum/armament_entry/assault_operatives/primary/shotgun_ammo/flechette
- name = "\improper IGE-340 flechette magazine"
- description = "Shotgun ammo that fires armor piercing flechettes that can cause some nasty wounds."
- item_type = /obj/item/ammo_box/magazine/multi_sprite/assault_ops_shotgun/flechette
+ item_type = /obj/item/ammo_box/advanced/s12gauge/flechette
/datum/armament_entry/assault_operatives/primary/shotgun_ammo/hollowpoint
- name = "\improper IGE-340 hollowpoint slug magazine"
- description = "Shotgun ammo that fires a large hollowpoint slug that hurts unarmored targets a lot more, in exchange for worse performance against armor."
- item_type = /obj/item/ammo_box/magazine/multi_sprite/assault_ops_shotgun/hollowpoint
+ item_type = /obj/item/ammo_box/advanced/s12gauge/hp
/datum/armament_entry/assault_operatives/primary/shotgun_ammo/beehive
- name = "\improper IGE-340 'beehive' magazine"
- description = "Shotgun ammo that fires a spread of smart-bouncing pellets, that are more likely to exhaust whoever its shot at rather than killing them."
- item_type = /obj/item/ammo_box/magazine/multi_sprite/assault_ops_shotgun/beehive
+ item_type = /obj/item/ammo_box/advanced/s12gauge/beehive
-/datum/armament_entry/assault_operatives/primary/shotgun_ammo/dragonsbreath
- name = "\improper IGE-340 dragonsbreath magazine"
- description = "Shotgun ammo that fires a spread of incendiary projectiles, creating a wall of fire whichever direction they are shot in."
- item_type = /obj/item/ammo_box/magazine/multi_sprite/assault_ops_shotgun/dragonsbreath
+/datum/armament_entry/assault_operatives/primary/shotgun_ammo/incendiary
+ item_type = /obj/item/ammo_box/advanced/s12gauge/incendiary
/datum/armament_entry/assault_operatives/primary/sniper
subcategory = OPS_SUBCATEGORY_SNIPER
-/datum/armament_entry/assault_operatives/primary/sniper/assault_ops_sniper
- item_type = /obj/item/gun/ballistic/rifle/boltaction/assault_ops_sniper
+/datum/armament_entry/assault_operatives/primary/sniper/assault_ops_gl
+ item_type = /obj/item/gun/ballistic/automatic/sol_grenade_launcher/evil
/datum/armament_entry/assault_operatives/primary/sniper_ammo
subcategory = OPS_SUBCATEGORY_SNIPER_AMMO
max_purchase = 10
cost = 1
-/datum/armament_entry/assault_operatives/primary/sniper_ammo/eepy
- name = "\improper IGE-410 soporific magazine"
- description = "Sniper ammo that will put whoever it hits right to sleep, rather than killing them."
- item_type = /obj/item/ammo_box/magazine/multi_sprite/assault_ops_sniper/sleepytime
+/datum/armament_entry/assault_operatives/primary/sniper_ammo/standard
+ item_type = /obj/item/ammo_box/magazine/c980_grenade/starts_empty
+ cost = 0
+
+/datum/armament_entry/assault_operatives/primary/sniper_ammo/drum
+ item_type = /obj/item/ammo_box/magazine/c980_grenade/drum/starts_empty
+ cost = 0
+
+/datum/armament_entry/assault_operatives/primary/sniper_ammo/practice
+ item_type = /obj/item/ammo_box/c980grenade
+
+/datum/armament_entry/assault_operatives/primary/sniper_ammo/smoke
+ item_type = /obj/item/ammo_box/c980grenade/smoke
+
+/datum/armament_entry/assault_operatives/primary/sniper_ammo/shrapnel
+ item_type = /obj/item/ammo_box/c980grenade/shrapnel
+
+/datum/armament_entry/assault_operatives/primary/sniper_ammo/phosphor
+ item_type = /obj/item/ammo_box/c980grenade/shrapnel/phosphor
-/datum/armament_entry/assault_operatives/primary/sniper_ammo/penetrator
- name = "\improper IGE-410 penetrator magazine"
- description = "Sniper ammo that is capable of penetrating through multiple walls and people at once."
- item_type = /obj/item/ammo_box/magazine/multi_sprite/assault_ops_sniper/penetrator
+/datum/armament_entry/assault_operatives/primary/sniper_ammo/riot
+ item_type = /obj/item/ammo_box/c980grenade/riot
#undef OPS_SUBCATEGORY_RIFLE
#undef OPS_SUBCATEGORY_RIFLE_AMMO
diff --git a/modular_skyrat/modules/assault_operatives/code/armaments/_armament_secondary.dm b/modular_skyrat/modules/assault_operatives/code/armaments/_armament_secondary.dm
index 0022abd9868..36460f04d63 100644
--- a/modular_skyrat/modules/assault_operatives/code/armaments/_armament_secondary.dm
+++ b/modular_skyrat/modules/assault_operatives/code/armaments/_armament_secondary.dm
@@ -11,8 +11,8 @@
/datum/armament_entry/assault_operatives/secondary/lethal
subcategory = OPS_SUBCATEGORY_LETHAL_SIDE
-/datum/armament_entry/assault_operatives/secondary/lethal/ansem
- item_type = /obj/item/gun/ballistic/automatic/pistol/clandestine/assault_ops
+/datum/armament_entry/assault_operatives/secondary/lethal/pistol
+ item_type = /obj/item/gun/ballistic/automatic/pistol/sol/evil
/datum/armament_entry/assault_operatives/secondary/lethal/energy_sword
item_type = /obj/item/melee/energy/sword/saber
@@ -21,7 +21,7 @@
subcategory = OPS_SUBCATEGORY_NONLETHAL_SIDE
/datum/armament_entry/assault_operatives/secondary/nonlethal/taze_me_bro
- item_type = /obj/item/gun/energy/e_gun/advtaser/assault_ops
+ item_type = /obj/item/gun/energy/e_gun/advtaser
/datum/armament_entry/assault_operatives/secondary/nonlethal/baton
item_type = /obj/item/melee/baton/telescopic
diff --git a/modular_skyrat/modules/assault_operatives/code/equipment_items/guns.dm b/modular_skyrat/modules/assault_operatives/code/equipment_items/guns.dm
deleted file mode 100644
index 430d627d526..00000000000
--- a/modular_skyrat/modules/assault_operatives/code/equipment_items/guns.dm
+++ /dev/null
@@ -1,246 +0,0 @@
-// La Pistola
-
-/obj/item/gun/ballistic/automatic/pistol/clandestine/assault_ops
- name = "\improper IGE-040 pistol"
- desc = "A pistol chambered in 10mm magnum and painted in an ominous matte black. Strangely, the gun also seems to lack any form of manufacturer markings."
-
-/obj/item/gun/ballistic/automatic/pistol/clandestine/assault_ops/give_manufacturer_examine()
- AddElement(/datum/element/manufacturer_examine, COMPANY_REMOVED)
-
-/obj/item/gun/energy/e_gun/advtaser/assault_ops
- w_class = WEIGHT_CLASS_NORMAL
-
-/obj/item/gun/energy/e_gun/advtaser/assault_ops/give_manufacturer_examine()
- AddElement(/datum/element/manufacturer_examine, COMPANY_REMOVED)
-
-// Rifle
-
-/obj/item/gun/ballistic/automatic/assault_ops_rifle
- name = "\improper IGE-110 rifle"
- desc = "A bullpup rifle chambered in 5.6x40mm and painted in an ominous matte black. Strangely, the gun also seems to lack any form of manufacturer markings."
-
- icon_state = "ige_assault"
- icon = 'modular_skyrat/modules/assault_operatives/icons/guns/guns.dmi'
- inhand_icon_state = "ige_assault"
- righthand_file = 'modular_skyrat/modules/assault_operatives/icons/guns/guns_righthand.dmi'
- lefthand_file = 'modular_skyrat/modules/assault_operatives/icons/guns/guns_lefthand.dmi'
- worn_icon_state = "ige_assault"
- worn_icon = 'modular_skyrat/modules/assault_operatives/icons/guns/guns_worn.dmi'
-
- base_pixel_x = -8
- pixel_x = -8
-
- w_class = WEIGHT_CLASS_BULKY
- slot_flags = ITEM_SLOT_BACK | ITEM_SLOT_OCLOTHING
- accepted_magazine_type = /obj/item/ammo_box/magazine/multi_sprite/assault_ops_rifle
- fire_sound = 'modular_skyrat/modules/sec_haul/sound/sfrifle_fire.ogg'
- can_suppress = TRUE
- suppressor_x_offset = 4
- suppressed_sound = 'sound/weapons/gun/general/heavy_shot_suppressed.ogg'
- burst_size = 2
- fire_delay = 3
- pin = /obj/item/firing_pin/implant/pindicate
-
-/obj/item/gun/ballistic/automatic/assault_ops_rifle/Initialize(mapload)
- . = ..()
-
- AddComponent(/datum/component/scope, range_modifier = 1.5)
-
-/obj/item/gun/ballistic/automatic/assault_ops_rifle/give_manufacturer_examine()
- AddElement(/datum/element/manufacturer_examine, COMPANY_REMOVED)
-
-/obj/item/ammo_box/magazine/multi_sprite/assault_ops_rifle
- name = "\improper IGE-110 magazine"
- desc = "A twenty round magazine built for 5.6x40mm, intended for use in the IGE-110 rifle."
- icon = 'modular_skyrat/modules/assault_operatives/icons/guns/magazines.dmi'
- icon_state = "ige_assault_mag"
- ammo_type = /obj/item/ammo_casing/realistic/a762x39
- caliber = "a762x39"
- max_ammo = 20
- multiple_sprites = AMMO_BOX_FULL_EMPTY
- possible_types = list(AMMO_TYPE_LETHAL, AMMO_TYPE_RUBBER, AMMO_TYPE_AP)
-
-/obj/item/ammo_box/magazine/multi_sprite/assault_ops_rifle/rubber
- ammo_type = /obj/item/ammo_casing/realistic/a762x39/civilian/rubber
- round_type = AMMO_TYPE_RUBBER
-
-/obj/item/ammo_box/magazine/multi_sprite/assault_ops_rifle/ap
- ammo_type = /obj/item/ammo_casing/realistic/a762x39/ap
- round_type = AMMO_TYPE_AP
-
-// SMG
-
-/obj/item/gun/ballistic/automatic/assault_ops_smg
- name = "\improper IGE-260 submachine gun"
- desc = "A toploader submachine gun chambered in 9x25mm and painted in an ominous matte black. Strangely, the gun also seems to lack any form of manufacturer markings."
-
- icon_state = "ige_smg"
- icon = 'modular_skyrat/modules/assault_operatives/icons/guns/guns.dmi'
- inhand_icon_state = "ige_smg"
- righthand_file = 'modular_skyrat/modules/assault_operatives/icons/guns/guns_righthand.dmi'
- lefthand_file = 'modular_skyrat/modules/assault_operatives/icons/guns/guns_lefthand.dmi'
- worn_icon_state = "ige_smg"
- worn_icon = 'modular_skyrat/modules/assault_operatives/icons/guns/guns_worn.dmi'
-
- base_pixel_x = -8
- pixel_x = -8
-
- w_class = WEIGHT_CLASS_NORMAL
- slot_flags = ITEM_SLOT_BACK | ITEM_SLOT_OCLOTHING
- accepted_magazine_type = /obj/item/ammo_box/magazine/multi_sprite/assault_ops_smg
- fire_sound = 'modular_skyrat/modules/sec_haul/sound/smg_fire.ogg'
- can_suppress = TRUE
- burst_size = 1
- fire_delay = 0.8
- projectile_damage_multiplier = 0.6
- actions_types = list()
- pin = /obj/item/firing_pin/implant/pindicate
-
-/obj/item/gun/ballistic/automatic/assault_ops_smg/Initialize(mapload)
- . = ..()
-
- AddComponent(/datum/component/automatic_fire, fire_delay)
-
-/obj/item/gun/ballistic/automatic/assault_ops_smg/give_manufacturer_examine()
- AddElement(/datum/element/manufacturer_examine, COMPANY_REMOVED)
-
-/obj/item/ammo_box/magazine/multi_sprite/assault_ops_smg
- name = "\improper IGE-260 magazine"
- desc = "A forty round magazine built for 9x25mm, intended for use in the IGE-260 submachine gun."
- icon = 'modular_skyrat/modules/assault_operatives/icons/guns/magazines.dmi'
- icon_state = "ige_smg_mag"
- ammo_type = /obj/item/ammo_casing/c9mm
- caliber = CALIBER_9MM
- max_ammo = 40
- multiple_sprites = AMMO_BOX_FULL_EMPTY
- possible_types = list(AMMO_TYPE_LETHAL, AMMO_TYPE_RUBBER, AMMO_TYPE_HOLLOWPOINT)
-
-/obj/item/ammo_box/magazine/multi_sprite/assault_ops_smg/rubber
- ammo_type = /obj/item/ammo_casing/c9mm/rubber
- round_type = AMMO_TYPE_RUBBER
-
-/obj/item/ammo_box/magazine/multi_sprite/assault_ops_smg/hp
- ammo_type = /obj/item/ammo_casing/c9mm/hp
- round_type = AMMO_TYPE_HOLLOWPOINT
-
-// Shotgun
-
-/obj/item/gun/ballistic/automatic/assault_ops_shotgun
- name = "\improper IGE-340 semi-automatic shotgun"
- desc = "A magazine fed semi-automatic shotgun chambered in 12 GA and painted in an ominous matte black. Strangely, the gun also seems to lack any form of manufacturer markings."
-
- icon_state = "ige_shotgun"
- icon = 'modular_skyrat/modules/assault_operatives/icons/guns/guns.dmi'
- inhand_icon_state = "ige_shotgun"
- righthand_file = 'modular_skyrat/modules/assault_operatives/icons/guns/guns_righthand.dmi'
- lefthand_file = 'modular_skyrat/modules/assault_operatives/icons/guns/guns_lefthand.dmi'
- worn_icon_state = "ige_shotgun"
- worn_icon = 'modular_skyrat/modules/assault_operatives/icons/guns/guns_worn.dmi'
-
- base_pixel_x = -8
- pixel_x = -8
-
- w_class = WEIGHT_CLASS_BULKY
- slot_flags = ITEM_SLOT_BACK | ITEM_SLOT_OCLOTHING
- accepted_magazine_type = /obj/item/ammo_box/magazine/multi_sprite/assault_ops_shotgun
- fire_sound = 'modular_skyrat/modules/sec_haul/sound/shotgun_bm.ogg'
- can_suppress = TRUE
- suppressor_x_offset = 4
- suppressed_sound = 'sound/weapons/gun/general/heavy_shot_suppressed.ogg'
- burst_size = 1
- fire_delay = 1.5
- actions_types = list()
- pin = /obj/item/firing_pin/implant/pindicate
-
-/obj/item/gun/ballistic/automatic/assault_ops_shotgun/give_manufacturer_examine()
- AddElement(/datum/element/manufacturer_examine, COMPANY_REMOVED)
-
-/obj/item/ammo_box/magazine/multi_sprite/assault_ops_shotgun
- name = "\improper IGE-340 magazine"
- desc = "A seven round magazine built for 12 GA, intended for use in the IGE-340 shotgun."
- icon = 'modular_skyrat/modules/assault_operatives/icons/guns/magazines.dmi'
- icon_state = "ige_shotgun_mag"
- ammo_type = /obj/item/ammo_casing/shotgun
- caliber = CALIBER_SHOTGUN
- max_ammo = 7
- multiple_sprites = AMMO_BOX_FULL_EMPTY
- possible_types = list(AMMO_TYPE_LETHAL, AMMO_TYPE_RUBBER, AMMO_TYPE_AP, AMMO_TYPE_HOLLOWPOINT, AMMO_TYPE_IHDF, AMMO_TYPE_INCENDIARY)
-
-/obj/item/ammo_box/magazine/multi_sprite/assault_ops_shotgun/rubbershot
- ammo_type = /obj/item/ammo_casing/shotgun/rubbershot
- round_type = AMMO_TYPE_RUBBER
-
-/obj/item/ammo_box/magazine/multi_sprite/assault_ops_shotgun/flechette
- ammo_type = /obj/item/ammo_casing/shotgun/flechette
- round_type = AMMO_TYPE_AP
-
-/obj/item/ammo_box/magazine/multi_sprite/assault_ops_shotgun/hollowpoint
- ammo_type = /obj/item/ammo_casing/shotgun/hp
- round_type = AMMO_TYPE_HOLLOWPOINT
-
-/obj/item/ammo_box/magazine/multi_sprite/assault_ops_shotgun/beehive
- ammo_type = /obj/item/ammo_casing/shotgun/beehive
- round_type = AMMO_TYPE_IHDF
-
-/obj/item/ammo_box/magazine/multi_sprite/assault_ops_shotgun/dragonsbreath
- ammo_type = /obj/item/ammo_casing/shotgun/dragonsbreath
- round_type = AMMO_TYPE_INCENDIARY
-
-// Sniper
-
-/obj/item/gun/ballistic/rifle/boltaction/assault_ops_sniper
- name = "\improper IGE-410-S marksman rifle"
- desc = "A magazine fed bolt-action rifle with a short enough barrel that your shoulder hurts just looking at it. Chambered in .416 Stabilis, it is painted in an ominous matte black and seems to lack any form of manufacturer markings."
-
- icon_state = "ige_sniper"
- icon = 'modular_skyrat/modules/assault_operatives/icons/guns/guns.dmi'
- inhand_icon_state = "ige_sniper"
- righthand_file = 'modular_skyrat/modules/assault_operatives/icons/guns/guns_righthand.dmi'
- lefthand_file = 'modular_skyrat/modules/assault_operatives/icons/guns/guns_lefthand.dmi'
- worn_icon_state = "ige_sniper"
- worn_icon = 'modular_skyrat/modules/assault_operatives/icons/guns/guns_worn.dmi'
-
- base_pixel_x = -8
- pixel_x = -8
-
- w_class = WEIGHT_CLASS_BULKY
- slot_flags = ITEM_SLOT_BACK | ITEM_SLOT_OCLOTHING
- internal_magazine = FALSE
- accepted_magazine_type = /obj/item/ammo_box/magazine/multi_sprite/assault_ops_sniper
- fire_sound = 'modular_skyrat/modules/sec_haul/sound/sniper_fire.ogg'
- can_suppress = TRUE
- suppressor_x_offset = 6
- suppressed_sound = 'sound/weapons/gun/general/heavy_shot_suppressed.ogg'
- burst_size = 1
- fire_delay = 10
- recoil = 3
- can_be_sawn_off = FALSE
- can_jam = FALSE
- pin = /obj/item/firing_pin/implant/pindicate
-
-/obj/item/gun/ballistic/rifle/boltaction/assault_ops_sniper/Initialize(mapload)
- . = ..()
-
- AddComponent(/datum/component/scope, range_modifier = 2.5)
-
-/obj/item/gun/ballistic/rifle/boltaction/assault_ops_sniper/give_manufacturer_examine()
- AddElement(/datum/element/manufacturer_examine, COMPANY_REMOVED)
-
-/obj/item/ammo_box/magazine/multi_sprite/assault_ops_sniper
- name = "\improper IGE-410 magazine"
- desc = "A five round magazine built for .416 Stabilis, intended for use in the IGE-410 sniper."
- icon = 'modular_skyrat/modules/assault_operatives/icons/guns/magazines.dmi'
- icon_state = "ige_sniper_mag"
- ammo_type = /obj/item/ammo_casing/p50
- caliber = CALIBER_50BMG
- max_ammo = 5
- multiple_sprites = AMMO_BOX_FULL_EMPTY
- possible_types = list(AMMO_TYPE_LETHAL, AMMO_TYPE_RUBBER, AMMO_TYPE_AP)
-
-/obj/item/ammo_box/magazine/multi_sprite/assault_ops_sniper/sleepytime
- ammo_type = /obj/item/ammo_casing/p50/disruptor
- round_type = AMMO_TYPE_RUBBER
-
-/obj/item/ammo_box/magazine/multi_sprite/assault_ops_sniper/penetrator
- ammo_type = /obj/item/ammo_casing/p50/penetrator
- round_type = AMMO_TYPE_AP
diff --git a/modular_skyrat/modules/black_mesa/code/armaments/_armament_primary.dm b/modular_skyrat/modules/black_mesa/code/armaments/_armament_primary.dm
index 9c5344691d1..80462185a0e 100644
--- a/modular_skyrat/modules/black_mesa/code/armaments/_armament_primary.dm
+++ b/modular_skyrat/modules/black_mesa/code/armaments/_armament_primary.dm
@@ -41,7 +41,7 @@
magazine_cost = 4
/datum/armament_entry/hecu/primary/shotgun/shotgun_highcap
- item_type = /obj/item/gun/ballistic/shotgun/m23
+ item_type = /obj/item/gun/ballistic/shotgun/riot/sol
max_purchase = 2
cost = 5
@@ -55,7 +55,7 @@
mags_to_spawn = 2
/datum/armament_entry/hecu/primary/special/sniper_rifle
- item_type = /obj/item/gun/ballistic/automatic/cfa_rifle
+ item_type = /obj/item/gun/ballistic/automatic/sol_rifle/marksman
max_purchase = 1
cost = 16
diff --git a/modular_skyrat/modules/black_mesa/code/armaments/_armaments_secondary.dm b/modular_skyrat/modules/black_mesa/code/armaments/_armaments_secondary.dm
index da2f9575ed0..2098c72a718 100644
--- a/modular_skyrat/modules/black_mesa/code/armaments/_armaments_secondary.dm
+++ b/modular_skyrat/modules/black_mesa/code/armaments/_armaments_secondary.dm
@@ -12,8 +12,8 @@
item_type = /obj/item/gun/ballistic/automatic/pistol/m1911
max_purchase = 4
-/datum/armament_entry/hecu/secondary/pistol/glock
- item_type = /obj/item/gun/ballistic/automatic/pistol/g17/mesa
+/datum/armament_entry/hecu/secondary/pistol/pistol
+ item_type = /obj/item/gun/ballistic/automatic/pistol/sol
max_purchase = 4
mags_to_spawn = 3
diff --git a/modular_skyrat/modules/black_mesa/code/armaments/armament_miscellaneous.dm b/modular_skyrat/modules/black_mesa/code/armaments/armament_miscellaneous.dm
index 8ec1c5e39a6..1916b4e90fc 100644
--- a/modular_skyrat/modules/black_mesa/code/armaments/armament_miscellaneous.dm
+++ b/modular_skyrat/modules/black_mesa/code/armaments/armament_miscellaneous.dm
@@ -53,6 +53,6 @@
cost = 1
/datum/armament_entry/hecu/misc/hudglasses
- item_type = /obj/item/clothing/glasses/hud/security/sunglasses/peacekeeper/armadyne
+ item_type = /obj/item/clothing/glasses/hud/security/sunglasses/peacekeeper
max_purchase = 6
cost = 2
diff --git a/modular_skyrat/modules/black_mesa/code/drops.dm b/modular_skyrat/modules/black_mesa/code/drops.dm
index a415f790b94..30ab8bf0cf0 100644
--- a/modular_skyrat/modules/black_mesa/code/drops.dm
+++ b/modular_skyrat/modules/black_mesa/code/drops.dm
@@ -1,8 +1,8 @@
/obj/effect/spawner/random/hecu_smg
name = "HECU SMG drops"
spawn_all_loot = FALSE
- loot = list(/obj/item/gun/ballistic/automatic/cfa_wildcat = 15,
- /obj/item/ammo_box/magazine/multi_sprite/cfa_wildcat = 25,
+ loot = list(/obj/item/gun/ballistic/automatic/sol_smg = 15,
+ /obj/item/ammo_box/magazine/c35sol_pistol/stendo = 25,
/obj/item/clothing/mask/gas/hecu2 = 15,
/obj/item/clothing/head/helmet = 15,
/obj/item/clothing/suit/armor/vest = 15,
diff --git a/modular_skyrat/modules/black_mesa/code/ghost_spawners.dm b/modular_skyrat/modules/black_mesa/code/ghost_spawners.dm
index 8efff44325d..416def1973a 100644
--- a/modular_skyrat/modules/black_mesa/code/ghost_spawners.dm
+++ b/modular_skyrat/modules/black_mesa/code/ghost_spawners.dm
@@ -56,9 +56,9 @@
belt = /obj/item/storage/belt/security/full
back = /obj/item/storage/backpack
backpack_contents = list(/obj/item/radio,
- /obj/item/gun/ballistic/automatic/pistol/g17/mesa,
- /obj/item/ammo_box/magazine/multi_sprite/ladon,
- /obj/item/ammo_box/magazine/multi_sprite/ladon,
+ /obj/item/gun/ballistic/automatic/pistol/sol,
+ /obj/item/ammo_box/magazine/c35sol_pistol,
+ /obj/item/ammo_box/magazine/c35sol_pistol,
)
id = /obj/item/card/id
id_trim = /datum/id_trim/security_guard
diff --git a/modular_skyrat/modules/black_mesa/code/mobs/human_mobs.dm b/modular_skyrat/modules/black_mesa/code/mobs/human_mobs.dm
index b83e961a701..514c9aabe7c 100644
--- a/modular_skyrat/modules/black_mesa/code/mobs/human_mobs.dm
+++ b/modular_skyrat/modules/black_mesa/code/mobs/human_mobs.dm
@@ -162,7 +162,7 @@
icon_living = "security_guard_ranged"
casingtype = /obj/item/ammo_casing/c9mm
projectilesound = 'sound/weapons/gun/pistol/shot.ogg'
- loot = list(/obj/effect/gibspawner/human, /obj/item/clothing/suit/armor/vest/blueshirt, /obj/item/gun/ballistic/automatic/pistol/g17/mesa)
+ loot = list(/obj/effect/gibspawner/human, /obj/item/clothing/suit/armor/vest/blueshirt, /obj/item/gun/ballistic/automatic/pistol/sol)
rapid_melee = 1
/mob/living/simple_animal/hostile/blackmesa/blackops
diff --git a/modular_skyrat/modules/blueshield/code/blueshield.dm b/modular_skyrat/modules/blueshield/code/blueshield.dm
index 6492074f82e..afc5d64fb5b 100644
--- a/modular_skyrat/modules/blueshield/code/blueshield.dm
+++ b/modular_skyrat/modules/blueshield/code/blueshield.dm
@@ -37,7 +37,6 @@
/obj/item/stack/spacecash/c500 = 3,
/obj/item/disk/nuclear/fake/obvious = 2,
/obj/item/clothing/head/collectable/captain = 4,
- /obj/projectile/bullet/b460 = 1
)
veteran_only = TRUE
@@ -53,11 +52,6 @@
shoes = /obj/item/clothing/shoes/jackboots
ears = /obj/item/radio/headset/headset_bs/alt
glasses = /obj/item/clothing/glasses/hud/security/sunglasses
- backpack_contents = list(
- // FLUFFY FRONTIER EDIT: REMOVAL
- // /obj/item/storage/box/gunset/blueshield = 1,
- // FLUFFY FRONTIER EDIT END.
- )
// FLUFFY FRONTIER EDIT: ADDITION
suit_store = /obj/item/storage/belt/holster/energy/blueshield
// FLUFFY FRONTIER EDIT END.
diff --git a/modular_skyrat/modules/blueshield/code/closet.dm b/modular_skyrat/modules/blueshield/code/closet.dm
index 7ea4e5a52ea..5b2cd9ac611 100644
--- a/modular_skyrat/modules/blueshield/code/closet.dm
+++ b/modular_skyrat/modules/blueshield/code/closet.dm
@@ -37,4 +37,5 @@
new /obj/item/restraints/handcuffs(src)
new /obj/item/clothing/glasses/hud/security/sunglasses(src)
new /obj/item/storage/medkit/tactical/blueshield(src)
+ new /obj/item/storage/toolbox/guncase/skyrat/carwo_large_case/sindano(src)
new /obj/item/storage/bag/garment/blueshield(src)
diff --git a/modular_skyrat/modules/blueshield/code/weapons.dm b/modular_skyrat/modules/blueshield/code/weapons.dm
deleted file mode 100644
index 089dedefb15..00000000000
--- a/modular_skyrat/modules/blueshield/code/weapons.dm
+++ /dev/null
@@ -1,92 +0,0 @@
-// CMG gunset - IN USE
-/obj/item/storage/box/gunset/blueshield
- name = "Blueshield's CMG-2 gunset"
- w_class = WEIGHT_CLASS_NORMAL
-
-/obj/item/storage/box/gunset/blueshield/PopulateContents()
- . = ..()
- new /obj/item/gun/ballistic/automatic/cmg/nomag(src)
- new /obj/item/ammo_box/magazine/multi_sprite/cmg(src)
- new /obj/item/ammo_box/magazine/multi_sprite/cmg(src)
- new /obj/item/ammo_box/magazine/multi_sprite/cmg/lethal(src)
- new /obj/item/ammo_box/magazine/multi_sprite/cmg/lethal(src)
- new /obj/item/suppressor/nanotrasen(src)
-
-//suppressor for the CMG
-/obj/item/suppressor/nanotrasen
- name = "NT-S suppressor"
- desc = "A Nanotrasen brand small-arms suppressor, including a large NT logo stamped on the side."
-
-
-// -----------
-// Unused guns:
-// -----------
-
-//Energy Revolver
-/obj/item/gun/energy/e_gun/revolver //The virgin gun.
- name = "energy revolver"
- desc = "An advanced energy revolver with the capacity to shoot both electrodes and lasers."
- force = 7
- ammo_type = list(/obj/item/ammo_casing/energy/electrode, /obj/item/ammo_casing/energy/laser)
- ammo_x_offset = 1
- charge_sections = 4
- fire_delay = 4
- icon = 'modular_skyrat/modules/blueshield/icons/energy.dmi'
- icon_state = "bsgun"
- inhand_icon_state = "minidisable"
- lefthand_file = 'modular_skyrat/modules/blueshield/icons/guns_lefthand.dmi'
- righthand_file = 'modular_skyrat/modules/blueshield/icons/guns_righthand.dmi'
- obj_flags = UNIQUE_RENAME
- cell_type = /obj/item/stock_parts/cell/blueshield
- pin = /obj/item/firing_pin/implant/mindshield
- selfcharge = TRUE
-
-/obj/item/stock_parts/cell/blueshield
- name = "internal revolver power cell"
- maxcharge = 1500
- chargerate = 300
-
-//PDW-9 taser pistol
-/obj/item/gun/energy/e_gun/revolver/pdw9 //The chad gun.
- name = "PDW-9 taser pistol"
- desc = "A military grade energy sidearm, used by many militia forces throughout the local sector. It comes with an internally recharging battery which is slow to recharge."
- ammo_x_offset = 2
- icon_state = "pdw9pistol"
- inhand_icon_state = null
- cell_type = /obj/item/stock_parts/cell/pdw9
-
-/obj/item/stock_parts/cell/pdw9
- name = "internal pistol power cell"
- maxcharge = 1000
- chargerate = 300
- var/obj/item/gun/energy/e_gun/revolver/pdw9/parent
-
-/obj/item/stock_parts/cell/pdw9/Initialize(mapload)
- . = ..()
- parent = loc
-
-/obj/item/stock_parts/cell/pdw9/process()
- . = ..()
- parent.update_icon()
-
-//Allstar SC-3 PDW 'Hellfire'
-/obj/item/gun/energy/laser/hellgun/blueshield
- name = "\improper Allstar SC-3 PDW 'Hellfire'"
- desc = "A prototype energy carbine, despite NT's ban on hellfire weaponry due to negative press. \
- Allstar continued to work on it, compacting it into a small form-factor for personal defense. \
- As part of the Asset Retention Program created by Nanotrasen, Allstar's prototype began to be put into use."
- icon = 'modular_skyrat/modules/aesthetics/guns/icons/guns.dmi'
- worn_icon = 'modular_skyrat/modules/aesthetics/guns/icons/guns_back.dmi'
- lefthand_file = 'modular_skyrat/modules/aesthetics/guns/icons/guns_lefthand.dmi'
- righthand_file = 'modular_skyrat/modules/aesthetics/guns/icons/guns_righthand.dmi'
- icon_state = "hellfirepdw"
- worn_icon_state = "hellfirepdw"
- ammo_type = list(/obj/item/ammo_casing/energy/laser/hellfire/bs)
-
-/obj/item/gun/energy/laser/hellgun/blueshield/give_manufacturer_examine()
- AddElement(/datum/element/manufacturer_examine, COMPANY_ALLSTAR)
-
-/obj/item/ammo_casing/energy/laser/hellfire/bs
- projectile_type = /obj/projectile/beam/laser/hellfire
- e_cost = 83 //Lets it squeeze out a few more shots
- select_name = "maim"
diff --git a/modular_skyrat/modules/company_imports/code/armament_datums/bolt_nanotrasen_firearms.dm b/modular_skyrat/modules/company_imports/code/armament_datums/bolt_nanotrasen_firearms.dm
deleted file mode 100644
index 0d744d4b38e..00000000000
--- a/modular_skyrat/modules/company_imports/code/armament_datums/bolt_nanotrasen_firearms.dm
+++ /dev/null
@@ -1,112 +0,0 @@
-/datum/armament_entry/company_import/nanotrasen_bolt_weapons
- category = BOLT_NANOTRASEN_DEFENSE_NAME
- company_bitflag = CARGO_COMPANY_BOLT_NANOTRASEN
-
-// Basic armor vests
-
-/datum/armament_entry/company_import/nanotrasen_bolt_weapons/armor
- subcategory = "Light Body Armor"
-
-/datum/armament_entry/company_import/nanotrasen_bolt_weapons/armor/slim_vest
- name = "type I vest - slim"
- item_type = /obj/item/clothing/suit/armor/vest
- cost = PAYCHECK_CREW * 3
-
-/datum/armament_entry/company_import/nanotrasen_bolt_weapons/armor/normal_vest
- name = "type I vest - normal"
- item_type = /obj/item/clothing/suit/armor/vest/alt
- cost = PAYCHECK_CREW * 3
-
-// Fully non-lethal weapons
-
-/datum/armament_entry/company_import/nanotrasen_bolt_weapons/nonlethal
- subcategory = "Non-Lethal Weapons"
-
-/datum/armament_entry/company_import/nanotrasen_bolt_weapons/nonlethal/responder
- item_type = /obj/item/gun/energy/disabler/bolt_disabler
- cost = PAYCHECK_CREW * 5
-
-/datum/armament_entry/company_import/nanotrasen_bolt_weapons/nonlethal/pepperball
- item_type = /obj/item/gun/ballistic/automatic/pistol/pepperball
- cost = PAYCHECK_CREW * 5
-
-// Lethal pistols, requires some company interest first
-
-/datum/armament_entry/company_import/nanotrasen_bolt_weapons/lethal_sidearm
- subcategory = "Lethal Sidearms"
-
-/datum/armament_entry/company_import/nanotrasen_bolt_weapons/lethal_sidearm/detective_revolver
- item_type = /obj/item/gun/ballistic/revolver/c38/detective
- cost = PAYCHECK_COMMAND * 4
-
-/datum/armament_entry/company_import/nanotrasen_bolt_weapons/lethal_sidearm/g17
- item_type = /obj/item/gun/ballistic/automatic/pistol/g17
- cost = PAYCHECK_COMMAND * 4
-
-/datum/armament_entry/company_import/nanotrasen_bolt_weapons/lethal_sidearm/mk58
- item_type = /obj/item/gun/ballistic/automatic/pistol/mk58
- cost = PAYCHECK_COMMAND * 4
-
-/datum/armament_entry/company_import/nanotrasen_bolt_weapons/lethal_sidearm/m1911
- item_type = /obj/item/gun/ballistic/automatic/pistol/m1911
- cost = PAYCHECK_COMMAND * 4
-
-/datum/armament_entry/company_import/nanotrasen_bolt_weapons/sidearm_magazines
- subcategory = "Sidearm Magazines"
- cost = PAYCHECK_CREW
-
-/datum/armament_entry/company_import/nanotrasen_bolt_weapons/sidearm_magazines/c38speedloader
- item_type = /obj/item/ammo_box/c38
-
-/datum/armament_entry/company_import/nanotrasen_bolt_weapons/sidearm_magazines/c38speedloader_rubber
- item_type = /obj/item/ammo_box/c38/match/bouncy
-
-/datum/armament_entry/company_import/nanotrasen_bolt_weapons/sidearm_magazines/g17
- item_type = /obj/item/ammo_box/magazine/multi_sprite/g17
-
-/datum/armament_entry/company_import/nanotrasen_bolt_weapons/sidearm_magazines/g17_rubber
- item_type = /obj/item/ammo_box/magazine/multi_sprite/g17/rubber
-
-/datum/armament_entry/company_import/nanotrasen_bolt_weapons/sidearm_magazines/mk58
- item_type = /obj/item/ammo_box/magazine/multi_sprite/mk58
-
-/datum/armament_entry/company_import/nanotrasen_bolt_weapons/sidearm_magazines/mk58_rubber
- item_type = /obj/item/ammo_box/magazine/multi_sprite/mk58/rubber
-
-/datum/armament_entry/company_import/nanotrasen_bolt_weapons/sidearm_magazines/m1911
- item_type = /obj/item/ammo_box/magazine/m45
-
-// Lethal anything that's not a pistol, requires high company interest
-
-/datum/armament_entry/company_import/nanotrasen_bolt_weapons/longarm
- subcategory = "Lethal Longarms"
- restricted = TRUE
-
-/datum/armament_entry/company_import/nanotrasen_bolt_weapons/longarm/riot_shotgun
- item_type = /obj/item/gun/ballistic/shotgun/riot
- cost = PAYCHECK_COMMAND * 6
-
-/datum/armament_entry/company_import/nanotrasen_bolt_weapons/longarm/m23
- item_type = /obj/item/gun/ballistic/shotgun/m23
- cost = PAYCHECK_COMMAND * 8
-
-/datum/armament_entry/company_import/nanotrasen_bolt_weapons/longarm/wt550
- item_type = /obj/item/gun/ballistic/automatic/wt550
- cost = PAYCHECK_COMMAND * 6
-
-/datum/armament_entry/company_import/nanotrasen_bolt_weapons/longarm/cmg
- item_type = /obj/item/gun/ballistic/automatic/cmg
- cost = PAYCHECK_COMMAND * 6
-
-/datum/armament_entry/company_import/nanotrasen_bolt_weapons/longarm_magazines
- subcategory = "Longarm Magazines"
- cost = PAYCHECK_CREW
-
-/datum/armament_entry/company_import/nanotrasen_bolt_weapons/longarm_magazines/wt550
- item_type = /obj/item/ammo_box/magazine/wt550m9
-
-/datum/armament_entry/company_import/nanotrasen_bolt_weapons/longarm_magazines/cmg
- item_type = /obj/item/ammo_box/magazine/multi_sprite/cmg/lethal
-
-/datum/armament_entry/company_import/nanotrasen_bolt_weapons/longarm_magazines/cmg_rubber
- item_type = /obj/item/ammo_box/magazine/multi_sprite/cmg
diff --git a/modular_skyrat/modules/company_imports/code/armament_datums/deforest_medical.dm b/modular_skyrat/modules/company_imports/code/armament_datums/deforest_medical.dm
index 40f8ef775f7..d6e5be0049e 100644
--- a/modular_skyrat/modules/company_imports/code/armament_datums/deforest_medical.dm
+++ b/modular_skyrat/modules/company_imports/code/armament_datums/deforest_medical.dm
@@ -226,21 +226,3 @@
/datum/armament_entry/company_import/deforest/cyber_organs/augments/breathing_tube
name = "breathing tube implant"
item_type = /obj/item/organ/internal/cyberimp/mouth/breathing_tube
-
-// Personal Defense Weapons (For when the pharmacist must become the harmacist)
-
-/datum/armament_entry/company_import/deforest/defense
- subcategory = "Personal Defense Equipment"
- contraband = TRUE
-
-/datum/armament_entry/company_import/deforest/defense/firefly
- item_type = /obj/item/gun/ballistic/automatic/pistol/firefly
- cost = PAYCHECK_COMMAND * 4
-
-/datum/armament_entry/company_import/deforest/defense/firefly_mag
- item_type = /obj/item/ammo_box/magazine/multi_sprite/firefly
- cost = PAYCHECK_CREW
-
-/datum/armament_entry/company_import/deforest/defense/firefly_mag_rubber
- item_type = /obj/item/ammo_box/magazine/multi_sprite/firefly/rubber
- cost = PAYCHECK_CREW
diff --git a/modular_skyrat/modules/company_imports/code/armament_datums/microstar_energy.dm b/modular_skyrat/modules/company_imports/code/armament_datums/microstar_energy.dm
index 35c89c03b1f..060a149e5df 100644
--- a/modular_skyrat/modules/company_imports/code/armament_datums/microstar_energy.dm
+++ b/modular_skyrat/modules/company_imports/code/armament_datums/microstar_energy.dm
@@ -15,7 +15,7 @@
item_type = /obj/item/gun/energy/e_gun/mini
cost = PAYCHECK_CREW * 5
-/datum/armament_entry/company_import/nanotrasen_bolt_weapons/lethal_sidearm/energy_holster
+/datum/armament_entry/company_import/microstar/lethal_sidearm/energy_holster
item_type = /obj/item/storage/belt/holster/energy/thermal
cost = PAYCHECK_COMMAND * 6
diff --git a/modular_skyrat/modules/company_imports/code/armament_datums/put_a_donk_on_it.dm b/modular_skyrat/modules/company_imports/code/armament_datums/put_a_donk_on_it.dm
index 97d8307efd9..534801d0031 100644
--- a/modular_skyrat/modules/company_imports/code/armament_datums/put_a_donk_on_it.dm
+++ b/modular_skyrat/modules/company_imports/code/armament_datums/put_a_donk_on_it.dm
@@ -99,6 +99,18 @@
item_type = /obj/item/gun/ballistic/automatic/l6_saw/toy/unrestricted
cost = PAYCHECK_COMMAND * 5
+/datum/armament_entry/company_import/donk/mod_modules
+ subcategory = "Donk Co. MOD modules"
+ cost = PAYCHECK_COMMAND
+
+/datum/armament_entry/company_import/donk/mod_modules/dart_collector_safe
+ item_type = /obj/item/mod/module/recycler/donk/safe
+ cost = PAYCHECK_COMMAND
+
+/datum/armament_entry/company_import/donk/mod_modules/dart_collector
+ item_type = /obj/item/mod/module/recycler/donk
+ cost = PAYCHECK_COMMAND * 4
+
/datum/armament_entry/company_import/donk/foamforce_ammo
subcategory = "Foam Force (TM) Dart Accessories"
cost = PAYCHECK_CREW
@@ -111,14 +123,14 @@
item_type = /obj/item/ammo_box/foambox/riot
cost = PAYCHECK_COMMAND * 1.5
-/datum/armament_entry/company_import/donk/foamforce_ammo
+/datum/armament_entry/company_import/donk/foamforce_ammo/pistol_mag
item_type = /obj/item/ammo_box/magazine/toy/pistol
-/datum/armament_entry/company_import/donk/foamforce_ammo
+/datum/armament_entry/company_import/donk/foamforce_ammo/smg_mag
item_type = /obj/item/ammo_box/magazine/toy/smg
-/datum/armament_entry/company_import/donk/foamforce_ammo
+/datum/armament_entry/company_import/donk/foamforce_ammo/smgm45_mag
item_type = /obj/item/ammo_box/magazine/toy/smgm45
-/datum/armament_entry/company_import/donk/foamforce_ammo
+/datum/armament_entry/company_import/donk/foamforce_ammo/m762_mag
item_type = /obj/item/ammo_box/magazine/toy/m762
diff --git a/modular_skyrat/modules/company_imports/code/armament_datums/sol_defense.dm b/modular_skyrat/modules/company_imports/code/armament_datums/sol_defense.dm
new file mode 100644
index 00000000000..0df662cd959
--- /dev/null
+++ b/modular_skyrat/modules/company_imports/code/armament_datums/sol_defense.dm
@@ -0,0 +1,115 @@
+/datum/armament_entry/company_import/sol_defense
+ category = SOL_DEFENSE_DEFENSE_NAME
+ company_bitflag = CARGO_COMPANY_SOL_DEFENSE
+
+// Basic armor vests
+
+/datum/armament_entry/company_import/sol_defense/armor
+ subcategory = "Light Body Armor"
+
+/datum/armament_entry/company_import/sol_defense/armor/slim_vest
+ name = "type I vest - slim"
+ item_type = /obj/item/clothing/suit/armor/vest
+ cost = PAYCHECK_CREW * 3
+
+/datum/armament_entry/company_import/sol_defense/armor/normal_vest
+ name = "type I vest - normal"
+ item_type = /obj/item/clothing/suit/armor/vest/alt
+ cost = PAYCHECK_CREW * 3
+
+/datum/armament_entry/company_import/sol_defense/case
+ subcategory = "Weapon Cases"
+
+/datum/armament_entry/company_import/sol_defense/case/trappiste
+ item_type = /obj/item/storage/toolbox/guncase/skyrat/pistol/trappiste_small_case/empty
+ cost = PAYCHECK_COMMAND
+
+/datum/armament_entry/company_import/sol_defense/case/carwo
+ item_type = /obj/item/storage/toolbox/guncase/skyrat/carwo_large_case/empty
+ cost = PAYCHECK_COMMAND * 2
+
+/datum/armament_entry/company_import/sol_defense/sidearm
+ subcategory = "Sidearms"
+
+/datum/armament_entry/company_import/sol_defense/sidearm/eland
+ item_type = /obj/item/gun/ballistic/revolver/sol
+ cost = PAYCHECK_COMMAND * 4
+
+/datum/armament_entry/company_import/sol_defense/sidearm/wespe
+ item_type = /obj/item/gun/ballistic/automatic/pistol/sol
+ cost = PAYCHECK_COMMAND * 4
+
+/datum/armament_entry/company_import/sol_defense/sidearm/skild
+ item_type = /obj/item/gun/ballistic/automatic/pistol/trappiste
+ cost = PAYCHECK_COMMAND * 6
+
+/datum/armament_entry/company_import/sol_defense/sidearm/takbok
+ item_type = /obj/item/gun/ballistic/revolver/takbok
+ cost = PAYCHECK_COMMAND * 6
+
+// Lethal anything that's not a pistol, requires high company interest
+
+/datum/armament_entry/company_import/sol_defense/longarm
+ subcategory = "Longarms"
+ restricted = TRUE
+
+/datum/armament_entry/company_import/sol_defense/longarm/renoster
+ item_type = /obj/item/gun/ballistic/shotgun/riot/sol
+ cost = PAYCHECK_COMMAND * 6
+
+/datum/armament_entry/company_import/sol_defense/longarm/sindano
+ item_type = /obj/item/gun/ballistic/automatic/sol_smg
+ cost = PAYCHECK_COMMAND * 6
+
+/datum/armament_entry/company_import/sol_defense/longarm/elite
+ item_type = /obj/item/gun/ballistic/automatic/sol_rifle/marksman
+ cost = PAYCHECK_COMMAND * 12
+
+/datum/armament_entry/company_import/sol_defense/longarm/infanterie
+ item_type = /obj/item/gun/ballistic/automatic/sol_rifle
+ cost = PAYCHECK_COMMAND * 14
+ contraband = TRUE
+
+/datum/armament_entry/company_import/sol_defense/longarm/outomaties
+ item_type = /obj/item/gun/ballistic/automatic/sol_rifle/machinegun
+ cost = PAYCHECK_COMMAND * 23
+ contraband = TRUE
+
+/datum/armament_entry/company_import/sol_defense/longarm/kiboko
+ item_type = /obj/item/gun/ballistic/automatic/sol_grenade_launcher
+ cost = PAYCHECK_COMMAND * 46
+ contraband = TRUE
+
+/datum/armament_entry/company_import/sol_defense/magazines
+ subcategory = "Magazines"
+ cost = PAYCHECK_CREW
+
+/datum/armament_entry/company_import/sol_defense/magazines/c35_mag
+ item_type = /obj/item/ammo_box/magazine/c35sol_pistol/starts_empty
+
+/datum/armament_entry/company_import/sol_defense/magazines/c35_extended
+ item_type = /obj/item/ammo_box/magazine/c35sol_pistol/stendo/starts_empty
+
+/datum/armament_entry/company_import/sol_defense/magazines/c585_mag
+ item_type = /obj/item/ammo_box/magazine/c585trappiste_pistol/spawns_empty
+
+/datum/armament_entry/company_import/sol_defense/magazines/sol_rifle_short
+ item_type = /obj/item/ammo_box/magazine/c40sol_rifle/starts_empty
+
+/datum/armament_entry/company_import/sol_defense/magazines/sol_rifle_standard
+ item_type = /obj/item/ammo_box/magazine/c40sol_rifle/standard/starts_empty
+ cost = PAYCHECK_COMMAND
+
+/datum/armament_entry/company_import/sol_defense/magazines/sol_rifle_drum
+ item_type = /obj/item/ammo_box/magazine/c40sol_rifle/drum/starts_empty
+ cost = PAYCHECK_COMMAND * 3
+ contraband = TRUE
+
+/datum/armament_entry/company_import/sol_defense/magazines/sol_grenade_standard
+ item_type = /obj/item/ammo_box/magazine/c980_grenade/starts_empty
+ cost = PAYCHECK_COMMAND * 2
+
+/datum/armament_entry/company_import/sol_defense/magazines/sol_grenade_drum
+ item_type = /obj/item/ammo_box/magazine/c980_grenade/drum/starts_empty
+ cost = PAYCHECK_CREW * 3
+ contraband = TRUE
diff --git a/modular_skyrat/modules/company_imports/code/armament_datums/vitezstvi_ammo.dm b/modular_skyrat/modules/company_imports/code/armament_datums/vitezstvi_ammo.dm
index 3e6df12d124..d6083b39cbc 100644
--- a/modular_skyrat/modules/company_imports/code/armament_datums/vitezstvi_ammo.dm
+++ b/modular_skyrat/modules/company_imports/code/armament_datums/vitezstvi_ammo.dm
@@ -11,7 +11,7 @@
item_type = /obj/item/circuitboard/machine/ammo_workbench
cost = PAYCHECK_COMMAND * 5
-/datum/armament_entry/company_import/vitezstvi/ammo_bench
+/datum/armament_entry/company_import/vitezstvi/ammo_bench/ammo_disk
item_type = /obj/item/disk/ammo_workbench/advanced
cost = PAYCHECK_COMMAND * 5
@@ -19,26 +19,28 @@
item_type = /obj/item/circuitboard/machine/dish_drive/bullet
cost = PAYCHECK_COMMAND * 2
-// Boxes of non-shotgun ammo
+// Weapon accessories
-/datum/armament_entry/company_import/vitezstvi/ammo_boxes
- subcategory = "Ammunition Boxes"
- cost = PAYCHECK_CREW
+/datum/armament_entry/company_import/vitezstvi/accessory
+ subcategory = "Weapon Accessories"
-/datum/armament_entry/company_import/vitezstvi/ammo_boxes/pepperball
- item_type = /obj/item/ammo_box/advanced/pepperballs
+/datum/armament_entry/company_import/vitezstvi/accessory/suppressor
+ item_type = /obj/item/suppressor
+ cost = PAYCHECK_COMMAND
-/datum/armament_entry/company_import/vitezstvi/ammo_boxes/m1911_lethals
- item_type = /obj/item/ammo_box/c45
+/datum/armament_entry/company_import/vitezstvi/accessory/small_case
+ item_type = /obj/item/storage/toolbox/guncase/skyrat/pistol/empty
+ cost = PAYCHECK_COMMAND
-/datum/armament_entry/company_import/vitezstvi/ammo_boxes/wt550_lethals
- item_type = /obj/item/ammo_box/c46x30mm
+/datum/armament_entry/company_import/vitezstvi/accessory/large_case
+ item_type = /obj/item/storage/toolbox/guncase/skyrat/empty
+ cost = PAYCHECK_COMMAND * 2
-/datum/armament_entry/company_import/vitezstvi/ammo_boxes/wt550_piercing
- item_type = /obj/item/ammo_box/c46x30mm/ap
+// Boxes of non-shotgun ammo
-/datum/armament_entry/company_import/vitezstvi/ammo_boxes/wt550_rubber
- item_type = /obj/item/ammo_box/c46x30mm/rubber
+/datum/armament_entry/company_import/vitezstvi/ammo_boxes
+ subcategory = "Ammunition Boxes"
+ cost = PAYCHECK_CREW
/datum/armament_entry/company_import/vitezstvi/ammo_boxes/peacekeeper_lethal
item_type = /obj/item/ammo_box/c9mm
@@ -73,6 +75,36 @@
/datum/armament_entry/company_import/vitezstvi/ammo_boxes/sabel_blank
item_type = /obj/item/ammo_box/c56mm/blank
+/datum/armament_entry/company_import/vitezstvi/ammo_boxes/sol35
+ item_type = /obj/item/ammo_box/c35sol
+
+/datum/armament_entry/company_import/vitezstvi/ammo_boxes/sol35_disabler
+ item_type = /obj/item/ammo_box/c35sol/incapacitator
+
+/datum/armament_entry/company_import/vitezstvi/ammo_boxes/sol35_ripper
+ item_type = /obj/item/ammo_box/c35sol/ripper
+
+/datum/armament_entry/company_import/vitezstvi/ammo_boxes/sol40
+ item_type = /obj/item/ammo_box/c40sol
+
+/datum/armament_entry/company_import/vitezstvi/ammo_boxes/sol40_disabler
+ item_type = /obj/item/ammo_box/c40sol/fragmentation
+
+/datum/armament_entry/company_import/vitezstvi/ammo_boxes/sol40_flame
+ item_type = /obj/item/ammo_box/c40sol/incendiary
+
+/datum/armament_entry/company_import/vitezstvi/ammo_boxes/sol40_pierce
+ item_type = /obj/item/ammo_box/c40sol/pierce
+
+/datum/armament_entry/company_import/vitezstvi/ammo_boxes/trappiste585
+ item_type = /obj/item/ammo_box/c585trappiste
+
+/datum/armament_entry/company_import/vitezstvi/ammo_boxes/trappiste585_disabler
+ item_type = /obj/item/ammo_box/c585trappiste/incapacitator
+
+/datum/armament_entry/company_import/vitezstvi/ammo_boxes/trappiste585_hollowpoint
+ item_type = /obj/item/ammo_box/c585trappiste/hollowpoint
+
// Revolver speedloaders
/datum/armament_entry/company_import/vitezstvi/speedloader
@@ -121,3 +153,26 @@
/datum/armament_entry/company_import/vitezstvi/shot_shells/confetti
item_type = /obj/item/ammo_box/advanced/s12gauge/honk
description = "A box of 35 confetti shells, firing a spread of harmless confetti everywhere, yippie!"
+
+// Boxes of kiboko launcher ammo
+
+/datum/armament_entry/company_import/vitezstvi/grenade_shells
+ subcategory = "Grenade Shells"
+ cost = PAYCHECK_COMMAND
+
+/datum/armament_entry/company_import/vitezstvi/grenade_shells/practice
+ item_type = /obj/item/ammo_box/c980grenade
+
+/datum/armament_entry/company_import/vitezstvi/grenade_shells/smoke
+ item_type = /obj/item/ammo_box/c980grenade/smoke
+
+/datum/armament_entry/company_import/vitezstvi/grenade_shells/riot
+ item_type = /obj/item/ammo_box/c980grenade/riot
+
+/datum/armament_entry/company_import/vitezstvi/grenade_shells/shrapnel
+ item_type = /obj/item/ammo_box/c980grenade/shrapnel
+ contraband = TRUE
+
+/datum/armament_entry/company_import/vitezstvi/grenade_shells/phosphor
+ item_type = /obj/item/ammo_box/c980grenade/shrapnel/phosphor
+ contraband = TRUE
diff --git a/modular_skyrat/modules/company_imports/code/company_datums.dm b/modular_skyrat/modules/company_imports/code/company_datums.dm
index cdbfddaa03d..263c8214ffc 100644
--- a/modular_skyrat/modules/company_imports/code/company_datums.dm
+++ b/modular_skyrat/modules/company_imports/code/company_datums.dm
@@ -82,8 +82,8 @@
// A coalition between nt and bolt to sell personal defense equipment and weapons
/datum/cargo_company/nanotrasen_bolt_weapons
- name = BOLT_NANOTRASEN_DEFENSE_NAME
- company_flag = CARGO_COMPANY_BOLT_NANOTRASEN
+ name = SOL_DEFENSE_DEFENSE_NAME
+ company_flag = CARGO_COMPANY_SOL_DEFENSE
cost = 6000
cost_change_lower = -1000
cost_change_upper = 4000
diff --git a/modular_skyrat/modules/company_imports/code/objects/vitezstvi/ammo_boxes.dm b/modular_skyrat/modules/company_imports/code/objects/vitezstvi/ammo_boxes.dm
index 20ebab5002f..fc7fb601531 100644
--- a/modular_skyrat/modules/company_imports/code/objects/vitezstvi/ammo_boxes.dm
+++ b/modular_skyrat/modules/company_imports/code/objects/vitezstvi/ammo_boxes.dm
@@ -74,25 +74,6 @@
name = "ammo box (.34 incendiary)"
ammo_type = /obj/item/ammo_casing/c34_incendiary
-/obj/item/ammo_box/c12mm
- name = "ammo box (12mm)"
- icon = 'modular_skyrat/modules/company_imports/icons/ammo.dmi'
- icon_state = "ammo_12mm"
- ammo_type = /obj/item/ammo_casing/c12mm
- max_ammo = 20
-
-/obj/item/ammo_box/c12mm/ap
- name = "ammo box (12mm AP)"
- ammo_type = /obj/item/ammo_casing/c12mm/ap
-
-/obj/item/ammo_box/c12mm/hp
- name = "ammo box (12mm HP)"
- ammo_type = /obj/item/ammo_casing/c12mm/hp
-
-/obj/item/ammo_box/c12mm/fire
- name = "ammo box (12mm incendiary)"
- ammo_type = /obj/item/ammo_casing/c12mm/fire
-
/obj/item/ammo_box/c56mm
name = "ammo box (5.6mm civilian)"
desc = "5.6x40mm ammunition specifically made for civilian use like recreation, hunting, self-defense or LARP. While the package itself lacks any real identification \
diff --git a/modular_skyrat/modules/contractor/code/datums/contractor_datum.dm b/modular_skyrat/modules/contractor/code/datums/contractor_datum.dm
index f7d4e09f41e..5346d412702 100644
--- a/modular_skyrat/modules/contractor/code/datums/contractor_datum.dm
+++ b/modular_skyrat/modules/contractor/code/datums/contractor_datum.dm
@@ -18,7 +18,8 @@
// Special case for reinforcements, we want to show their ckey and name on round end.
if (istype(contractor_purchase, /datum/contractor_item/contractor_partner))
var/datum/contractor_item/contractor_partner/partner = contractor_purchase
- contractor_support_unit += " [partner.partner_mind.key] played [partner.partner_mind.current.name], their contractor support unit."
+ var/mob/living/carbon/human/partner_mob = partner.partner_mind.current
+ contractor_support_unit += " [partner_mob.name] was [partner_mob.p_their()] contractor support unit."
if (length(contractor_hub.purchased_items))
result += " (used [total_spent_rep] Rep) "
diff --git a/modular_skyrat/modules/customization/modules/clothing/hands/hands.dm b/modular_skyrat/modules/customization/modules/clothing/hands/hands.dm
index 1d395d906ae..667796dbce4 100644
--- a/modular_skyrat/modules/customization/modules/clothing/hands/hands.dm
+++ b/modular_skyrat/modules/customization/modules/clothing/hands/hands.dm
@@ -31,5 +31,16 @@
max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT
resistance_flags = NONE
+/obj/item/clothing/gloves/bracer/wraps
+ name = "cloth arm wraps"
+ desc = "Cloth bracers, the colour all left up to the choice of the wearer."
+ icon = 'modular_skyrat/master_files/icons/donator/obj/clothing/gloves.dmi'
+ icon_state = "arm_wraps"
+ inhand_icon_state = "greyscale_gloves"
+ greyscale_config = /datum/greyscale_config/armwraps
+ greyscale_config_worn = /datum/greyscale_config/armwraps/worn
+ greyscale_colors = "#FFFFFF"
+ flags_1 = IS_PLAYER_COLORABLE_1
+
/obj/item/clothing/gloves
worn_icon_teshari = TESHARI_HANDS_ICON
diff --git a/modular_skyrat/modules/customization/modules/clothing/shoes/shoes.dm b/modular_skyrat/modules/customization/modules/clothing/shoes/shoes.dm
index 682d2236a1e..07d7cc81ea0 100644
--- a/modular_skyrat/modules/customization/modules/clothing/shoes/shoes.dm
+++ b/modular_skyrat/modules/customization/modules/clothing/shoes/shoes.dm
@@ -95,13 +95,24 @@
worn_icon = 'modular_skyrat/master_files/icons/mob/clothing/feet.dmi'
icon_state = "blackjack"
-/obj/item/clothing/shoes/wraps/colourable
+/obj/item/clothing/shoes/wraps/cloth
name = "cloth foot wraps"
desc = "Boxer tape or bandages wrapped like a mummy, all left up to the choice of the wearer."
icon_state = "clothwrap"
- greyscale_config = /datum/greyscale_config/wraps
- greyscale_config_worn = /datum/greyscale_config/wraps/worn
- greyscale_config_worn_digi = /datum/greyscale_config/wraps/worn/digi
+ greyscale_config = /datum/greyscale_config/clothwraps
+ greyscale_config_worn = /datum/greyscale_config/clothwraps/worn
+ greyscale_config_worn_digi = /datum/greyscale_config/clothwraps/worn/digi
+ greyscale_colors = "#FFFFFF"
+ body_parts_covered = FALSE
+ flags_1 = IS_PLAYER_COLORABLE_1
+
+/obj/item/clothing/shoes/wraps/colourable
+ name = "colourable foot wraps"
+ desc = "Ankle coverings. These ones have a customisable colour design."
+ icon_state = "legwrap"
+ greyscale_config = /datum/greyscale_config/legwraps
+ greyscale_config_worn = /datum/greyscale_config/legwraps/worn
+ greyscale_config_worn_digi = /datum/greyscale_config/legwraps/worn/digi
greyscale_colors = "#FFFFFF"
body_parts_covered = FALSE
flags_1 = IS_PLAYER_COLORABLE_1
@@ -196,3 +207,14 @@
greyscale_config_worn_better_vox = /datum/greyscale_config/boots/worn/newvox
greyscale_config_worn_vox = /datum/greyscale_config/boots/worn/oldvox
flags_1 = IS_PLAYER_COLORABLE_1
+
+/obj/item/clothing/shoes/wraps/cloth
+ name = "cloth foot wraps"
+ desc = "Boxer tape or bandages wrapped like a mummy, all left up to the choice of the wearer."
+ icon_state = "clothwrap"
+ greyscale_config = /datum/greyscale_config/clothwraps
+ greyscale_config_worn = /datum/greyscale_config/clothwraps/worn
+ greyscale_config_worn_digi = /datum/greyscale_config/clothwraps/worn/digi
+ greyscale_colors = "#FFFFFF"
+ body_parts_covered = FALSE
+ flags_1 = IS_PLAYER_COLORABLE_1
diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species.dm
index 76ebf34b682..b87946aaf37 100644
--- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species.dm
+++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species.dm
@@ -124,13 +124,19 @@ GLOBAL_LIST_EMPTY(customizable_races)
if(species_human.underwear && !(species_human.underwear_visibility & UNDERWEAR_HIDE_UNDIES))
var/datum/sprite_accessory/underwear/underwear = GLOB.underwear_list[species_human.underwear]
var/mutable_appearance/underwear_overlay
+ var/female_sprite_flags = FEMALE_UNIFORM_FULL // the default gender shaping
if(underwear)
var/icon_state = underwear.icon_state
if(underwear.has_digitigrade && (species_human.bodytype & BODYTYPE_DIGITIGRADE))
icon_state += "_d"
- underwear_overlay = mutable_appearance(underwear.icon, icon_state, -BODY_LAYER)
+ female_sprite_flags = FEMALE_UNIFORM_TOP_ONLY // for digi gender shaping
+ if(species_human.dna.species.sexes && species_human.physique == FEMALE && (underwear.gender == MALE))
+ underwear_overlay = wear_female_version(icon_state, underwear.icon, BODY_LAYER, female_sprite_flags)
+ else
+ underwear_overlay = mutable_appearance(underwear.icon, icon_state, -BODY_LAYER)
if(!underwear.use_static)
underwear_overlay.color = species_human.underwear_color
+ underwear_overlay.pixel_y += height_offset
standing += underwear_overlay
if(species_human.bra && !(species_human.underwear_visibility & UNDERWEAR_HIDE_BRA))
@@ -142,7 +148,7 @@ GLOBAL_LIST_EMPTY(customizable_races)
bra_overlay = mutable_appearance(bra.icon, icon_state, -BODY_LAYER)
if(!bra.use_static)
bra_overlay.color = species_human.bra_color
-
+ bra_overlay.pixel_y += height_offset
standing += bra_overlay
if(species_human.undershirt && !(species_human.underwear_visibility & UNDERWEAR_HIDE_SHIRT))
@@ -155,6 +161,7 @@ GLOBAL_LIST_EMPTY(customizable_races)
undershirt_overlay = mutable_appearance(undershirt.icon, undershirt.icon_state, -BODY_LAYER)
if(!undershirt.use_static)
undershirt_overlay.color = species_human.undershirt_color
+ undershirt_overlay.pixel_y += height_offset
standing += undershirt_overlay
if(species_human.socks && species_human.num_legs >= 2 && !(mutant_bodyparts["taur"]) && !(species_human.underwear_visibility & UNDERWEAR_HIDE_SOCKS))
diff --git a/modular_skyrat/modules/encounters/code/nri_raiders.dm b/modular_skyrat/modules/encounters/code/nri_raiders.dm
index ce89ac660a2..aa3b406bc01 100644
--- a/modular_skyrat/modules/encounters/code/nri_raiders.dm
+++ b/modular_skyrat/modules/encounters/code/nri_raiders.dm
@@ -128,7 +128,7 @@ GLOBAL_VAR(first_officer)
belt = /obj/item/storage/belt/security/nri
back = /obj/item/storage/backpack/satchel/leather
- backpack_contents = list(/obj/item/storage/box/nri_survival_pack/raider = 1, /obj/item/ammo_box/magazine/m9mm_aps = 3, /obj/item/gun/ballistic/automatic/pistol/ladon/nri = 1, /obj/item/crucifix = 1, /obj/item/clothing/mask/gas/hecu2 = 1, /obj/item/modular_computer/pda/security = 1)
+ backpack_contents = list(/obj/item/storage/box/nri_survival_pack/raider = 1, /obj/item/ammo_box/magazine/m9mm_aps = 3, /obj/item/gun/ballistic/automatic/pistol/nri = 1, /obj/item/crucifix = 1, /obj/item/clothing/mask/gas/hecu2 = 1, /obj/item/modular_computer/pda/security = 1)
l_pocket = /obj/item/folder/blue/nri_cop
r_pocket = /obj/item/storage/pouch/ammo
@@ -343,40 +343,6 @@ GLOBAL_VAR(first_officer)
command_name = "NRI Enforcer-Class Starship Telegram"
report_sound = ANNOUNCER_NRI_RAIDERS
-/obj/item/gun/ballistic/automatic/pistol/automag
- name = "\improper Automag"
- desc = "A .44 AMP handgun with a sleek metallic finish."
- icon_state = "automag"
- icon = 'modular_skyrat/modules/sec_haul/icons/guns/automag.dmi'
- w_class = WEIGHT_CLASS_NORMAL
- accepted_magazine_type = /obj/item/ammo_box/magazine/automag
- can_suppress = FALSE
- fire_sound = 'modular_skyrat/modules/sec_haul/sound/automag.ogg'
- rack_sound = 'sound/weapons/gun/pistol/rack.ogg'
- lock_back_sound = 'sound/weapons/gun/pistol/slide_lock.ogg'
- bolt_drop_sound = 'sound/weapons/gun/pistol/slide_drop.ogg'
-
-/obj/item/ammo_box/magazine/automag
- name = "handgun magazine (.44 AMP)"
- icon = 'modular_skyrat/modules/sec_haul/icons/guns/mags.dmi'
- icon_state = "automag"
- base_icon_state = "automag"
- ammo_type = /obj/item/ammo_casing/c44
- caliber = CALIBER_44
- max_ammo = 7
- multiple_sprites = AMMO_BOX_PER_BULLET
-
-/obj/item/ammo_casing/c44
- name = ".44 AMP bullet casing"
- desc = "A .44 AMP bullet casing."
- caliber = CALIBER_44
- projectile_type = /obj/projectile/bullet/c44
-
-/obj/projectile/bullet/c44
- name = ".44 AMP bullet"
- damage = 40
- wound_bonus = 30
-
/obj/item/storage/belt/military/nri/captain/pirate_officer/PopulateContents()
generate_items_inside(list(
/obj/item/knife/combat = 1,
diff --git a/modular_skyrat/modules/exp_corps/code/expeditionary_trooper.dm b/modular_skyrat/modules/exp_corps/code/expeditionary_trooper.dm
index 54fc933848a..fdcbef42cab 100644
--- a/modular_skyrat/modules/exp_corps/code/expeditionary_trooper.dm
+++ b/modular_skyrat/modules/exp_corps/code/expeditionary_trooper.dm
@@ -29,4 +29,4 @@
new /obj/item/clothing/suit/armor/vest/expeditionary_corps(src)
new /obj/item/storage/belt/military/expeditionary_corps/marksman(src)
new /obj/item/storage/backpack/duffelbag/expeditionary_corps(src)
- new /obj/item/storage/box/gunset/ladon(src)
+ new /obj/item/storage/toolbox/guncase/skyrat/pistol/trappiste_small_case/skild(src)
diff --git a/modular_skyrat/modules/faction/code/mapping/mapping_helpers.dm b/modular_skyrat/modules/faction/code/mapping/mapping_helpers.dm
index 035e1597f4e..67461a949b7 100644
--- a/modular_skyrat/modules/faction/code/mapping/mapping_helpers.dm
+++ b/modular_skyrat/modules/faction/code/mapping/mapping_helpers.dm
@@ -181,11 +181,11 @@
new /obj/item/knife/combat(src)
new /obj/item/switchblade(src)
new /obj/item/switchblade(src)
- new /obj/item/gun/ballistic/automatic/cfa_wildcat(src)
- new /obj/item/gun/ballistic/automatic/cfa_wildcat(src)
+ new /obj/item/gun/ballistic/automatic/sol_smg(src)
+ new /obj/item/gun/ballistic/automatic/sol_smg(src)
for(var/i in 1 to 2)
- new /obj/item/ammo_box/magazine/multi_sprite/cfa_wildcat(src)
- new /obj/item/ammo_box/magazine/multi_sprite/cfa_wildcat(src)
+ new /obj/item/ammo_box/magazine/c35sol_pistol/stendo(src)
+ new /obj/item/ammo_box/magazine/c35sol_pistol/stendo(src)
new /obj/item/gun/ballistic/automatic/akm(src)
for(var/i in 1 to 2)
new /obj/item/ammo_box/magazine/akm(src)
diff --git a/modular_skyrat/modules/goofsec/code/department_guards.dm b/modular_skyrat/modules/goofsec/code/department_guards.dm
index 7a5828b5fa2..c93b74ffa18 100644
--- a/modular_skyrat/modules/goofsec/code/department_guards.dm
+++ b/modular_skyrat/modules/goofsec/code/department_guards.dm
@@ -200,7 +200,7 @@
l_pocket = /obj/item/restraints/handcuffs/cable/pink
backpack_contents = list(
/obj/item/melee/baton/security/loaded/departmental/science = 1,
- /obj/item/storage/box/gunset/pepperball = 1,
+ /obj/item/storage/toolbox/guncase/skyrat/pistol/pepperball = 1,
)
backpack = /obj/item/storage/backpack/science
@@ -304,7 +304,7 @@
l_pocket = /obj/item/restraints/handcuffs/cable/blue
backpack_contents = list(
/obj/item/melee/baton/security/loaded/departmental/medical = 1,
- /obj/item/storage/box/gunset/pepperball = 1,
+ /obj/item/storage/toolbox/guncase/skyrat/pistol/pepperball = 1,
)
backpack = /obj/item/storage/backpack/medic
@@ -402,7 +402,7 @@
l_pocket = /obj/item/restraints/handcuffs/cable/yellow
backpack_contents = list(
/obj/item/melee/baton/security/loaded/departmental/engineering = 1,
- /obj/item/storage/box/gunset/pepperball = 1,
+ /obj/item/storage/toolbox/guncase/skyrat/pistol/pepperball = 1,
)
backpack = /obj/item/storage/backpack/industrial
@@ -507,7 +507,7 @@
l_pocket = /obj/item/restraints/handcuffs/cable/orange
backpack_contents = list(
/obj/item/melee/baton/security/loaded/departmental/cargo = 1,
- /obj/item/storage/box/gunset/pepperball = 1,
+ /obj/item/storage/toolbox/guncase/skyrat/pistol/pepperball = 1,
)
backpack = /obj/item/storage/backpack
@@ -604,7 +604,7 @@
r_pocket = /obj/item/assembly/flash/handheld
backpack_contents = list(
/obj/item/melee/baton/security/loaded/departmental/service = 1,
- /obj/item/storage/box/gunset/pepperball = 1,
+ /obj/item/storage/toolbox/guncase/skyrat/pistol/pepperball = 1,
)
glasses = /obj/item/clothing/glasses/sunglasses
diff --git a/modular_skyrat/modules/gun_safety/code/safety_additions.dm b/modular_skyrat/modules/gun_safety/code/safety_additions.dm
index 67b6fe8561e..af8f3665315 100644
--- a/modular_skyrat/modules/gun_safety/code/safety_additions.dm
+++ b/modular_skyrat/modules/gun_safety/code/safety_additions.dm
@@ -25,9 +25,6 @@
/obj/item/gun/ballistic/automatic/pistol/deagle/ctf/give_gun_safeties()
return
-/obj/item/gun/ballistic/automatic/pistol/g17/mesa/give_gun_safeties()
- return
-
/obj/item/gun/ballistic/revolver/grenadelauncher/give_gun_safeties()
return
diff --git a/modular_skyrat/modules/hyposprays/code/hypovials.dm b/modular_skyrat/modules/hyposprays/code/hypovials.dm
index edc7b41c85b..a4781bfea8f 100644
--- a/modular_skyrat/modules/hyposprays/code/hypovials.dm
+++ b/modular_skyrat/modules/hyposprays/code/hypovials.dm
@@ -45,32 +45,32 @@
//Fit in all hypos
/obj/item/reagent_containers/cup/vial/small
name = "hypovial"
- desc = "A small, 60u capacity vial compatible with most hyposprays."
- volume = 60
- possible_transfer_amounts = list(1,2,5,10,20,30,40,50,60)
+ desc = "A small, 50u capacity vial compatible with most hyposprays."
+ volume = 50
+ possible_transfer_amounts = list(1,2,5,10,15,25,50)
//Fit in CMO hypo only
/obj/item/reagent_containers/cup/vial/large
name = "large hypovial"
icon_state = "hypoviallarge"
- desc = "A large, 120u capacity vial that fits only in the most deluxe hyposprays."
- volume = 120
+ desc = "A large, 100u capacity vial that fits only in the most deluxe hyposprays."
+ volume = 100
type_suffix = "-l"
- possible_transfer_amounts = list(1,2,5,10,20,30,40,50,100,120)
+ possible_transfer_amounts = list(1,2,5,10,20,30,40,50,100)
//Hypos that are in the CMO's kit round start
/obj/item/reagent_containers/cup/vial/large/deluxe
name = "deluxe hypovial"
- list_reagents = list(/datum/reagent/medicine/omnizine = 20, /datum/reagent/medicine/leporazine = 20, /datum/reagent/medicine/atropine = 20)
+ list_reagents = list(/datum/reagent/medicine/omnizine = 15, /datum/reagent/medicine/leporazine = 15, /datum/reagent/medicine/atropine = 15)
/obj/item/reagent_containers/cup/vial/large/salglu
name = "large green hypovial (salglu)"
- list_reagents = list(/datum/reagent/medicine/salglu_solution = 60)
+ list_reagents = list(/datum/reagent/medicine/salglu_solution = 50)
/obj/item/reagent_containers/cup/vial/large/synthflesh
name = "large orange hypovial (synthflesh)"
- list_reagents = list(/datum/reagent/medicine/c2/synthflesh = 60)
+ list_reagents = list(/datum/reagent/medicine/c2/synthflesh = 50)
/obj/item/reagent_containers/cup/vial/large/multiver
name = "large black hypovial (multiver)"
- list_reagents = list(/datum/reagent/medicine/c2/multiver = 60)
+ list_reagents = list(/datum/reagent/medicine/c2/multiver = 50)
diff --git a/modular_skyrat/modules/loadouts/loadout_items/donator/personal/donator_personal.dm b/modular_skyrat/modules/loadouts/loadout_items/donator/personal/donator_personal.dm
index 7b6e248a278..c41311e4694 100644
--- a/modular_skyrat/modules/loadouts/loadout_items/donator/personal/donator_personal.dm
+++ b/modular_skyrat/modules/loadouts/loadout_items/donator/personal/donator_personal.dm
@@ -667,7 +667,7 @@
/datum/loadout_item/pocket_items/masvedishcigar
name = "Holocigar"
item_path = /obj/item/clothing/mask/holocigarette/masvedishcigar
- ckeywhitelist = list("masvedish")
+ ckeywhitelist = list("masvedish", "lutowski", "lawful", "anyacers", "apolloafk", "avianaviator", "notdhu")
/datum/loadout_item/suit/lt3_armor
name = "Silver Jacket Mk II"
diff --git a/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_gloves.dm b/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_gloves.dm
index 68d10776be6..8adc97dd42b 100644
--- a/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_gloves.dm
+++ b/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_gloves.dm
@@ -82,6 +82,10 @@ GLOBAL_LIST_INIT(loadout_gloves, generate_loadout_items(/datum/loadout_item/glov
name = "Maid Arm Covers"
item_path = /obj/item/clothing/gloves/maid
+/datum/loadout_item/gloves/armwraps
+ name = "Colourable Arm Wraps"
+ item_path = /obj/item/clothing/gloves/bracer/wraps
+
/*
* RINGS
*/
diff --git a/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_shoes.dm b/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_shoes.dm
index d24031b78e2..1ac2cfcb6b4 100644
--- a/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_shoes.dm
+++ b/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_shoes.dm
@@ -158,9 +158,13 @@ GLOBAL_LIST_INIT(loadout_shoes, generate_loadout_items(/datum/loadout_item/shoes
name = "Blue Leg Wraps"
item_path = /obj/item/clothing/shoes/wraps/blue
+/datum/loadout_item/shoes/cuffs/colourable
+ name = "Colourable Leg Wraps"
+ item_path = /obj/item/clothing/shoes/wraps/colourable
+
/datum/loadout_item/shoes/clothwrap
name = "Colourable Cloth Wraps"
- item_path = /obj/item/clothing/shoes/wraps/colourable
+ item_path = /obj/item/clothing/shoes/wraps/cloth
/*
* MISC
diff --git a/modular_skyrat/modules/mapping/code/lockers/cargodiselost/cargodiselockers.dm b/modular_skyrat/modules/mapping/code/lockers/cargodiselost/cargodiselockers.dm
index 00c5d6e8b62..2d9be517a0b 100644
--- a/modular_skyrat/modules/mapping/code/lockers/cargodiselost/cargodiselockers.dm
+++ b/modular_skyrat/modules/mapping/code/lockers/cargodiselost/cargodiselockers.dm
@@ -15,8 +15,8 @@
new /obj/item/ammo_box/magazine/akm(src)
new /obj/item/ammo_box/magazine/akm(src)
new /obj/item/ammo_box/magazine/akm(src)
- new /obj/item/ammo_box/magazine/multi_sprite/makarov(src)
- new /obj/item/ammo_box/magazine/multi_sprite/makarov(src)
+ new /obj/item/ammo_box/magazine/c35sol_pistol(src)
+ new /obj/item/ammo_box/magazine/c35sol_pistol(src)
new /obj/item/ammo_box/strilka310(src)
new /obj/item/ammo_box/strilka310(src)
new /obj/item/ammo_box/strilka310(src)
@@ -25,7 +25,7 @@
/obj/structure/closet/secure_closet/personal/cabinet/freighterboss/PopulateContents()
. = ..()
- new /obj/item/gun/ballistic/automatic/cfa_rifle(src)
+ new /obj/item/gun/ballistic/automatic/sol_rifle/marksman(src)
new /obj/item/storage/pouch/ammo(src)
new /obj/item/clothing/suit/armor/bulletproof(src)
new /obj/item/storage/belt/utility/syndicate(src)
@@ -33,6 +33,6 @@
new /obj/item/clothing/gloves/combat(src)
new /obj/item/storage/backpack/duffelbag/syndie(src)
new /obj/item/radio(src)
- new /obj/item/ammo_box/magazine/cm68(src)
- new /obj/item/ammo_box/magazine/cm68(src)
- new /obj/item/ammo_box/magazine/cm68(src)
+ new /obj/item/ammo_box/magazine/c40sol_rifle(src)
+ new /obj/item/ammo_box/magazine/c40sol_rifle(src)
+ new /obj/item/ammo_box/magazine/c40sol_rifle(src)
diff --git a/modular_skyrat/modules/mapping/code/lockers/interdyne_fob/security.dm b/modular_skyrat/modules/mapping/code/lockers/interdyne_fob/security.dm
index df1aa1cfe3f..82eb8a85314 100644
--- a/modular_skyrat/modules/mapping/code/lockers/interdyne_fob/security.dm
+++ b/modular_skyrat/modules/mapping/code/lockers/interdyne_fob/security.dm
@@ -71,13 +71,12 @@
/obj/structure/closet/secure_closet/interdynefob/munitions_locker/PopulateContents()
..()
- new /obj/item/ammo_box/c9mm(src)
- new /obj/item/ammo_box/c9mm(src)
- new /obj/item/ammo_box/magazine/m9mm(src)
- new /obj/item/ammo_box/magazine/m9mm(src)
- new /obj/item/ammo_box/magazine/m9mm(src)
- new /obj/item/ammo_box/magazine/m9mm(src)
- new /obj/item/ammo_box/advanced/s12gauge(src)
- new /obj/item/ammo_box/advanced/s12gauge(src)
- new /obj/item/ammo_box/advanced/s12gauge/rubber(src)
- new /obj/item/ammo_box/advanced/s12gauge/rubber(src)
+ generate_items_inside(list(
+ /obj/item/ammo_box/magazine/c35sol_pistol = 6,
+ /obj/item/ammo_box/magazine/c35sol_pistol/stendo = 2,
+ /obj/item/ammo_box/c35sol = 2,
+ /obj/item/ammo_box/magazine/c40sol_rifle/standard = 2,
+ /obj/item/ammo_box/c40sol = 2,
+ /obj/item/ammo_box/advanced/s12gauge = 2,
+ /obj/item/ammo_box/advanced/s12gauge/rubber = 2,
+ ),src)
diff --git a/modular_skyrat/modules/mapping/code/shuttles.dm b/modular_skyrat/modules/mapping/code/shuttles.dm
index 9f5293d9a1d..1ad2e883eec 100644
--- a/modular_skyrat/modules/mapping/code/shuttles.dm
+++ b/modular_skyrat/modules/mapping/code/shuttles.dm
@@ -121,19 +121,14 @@
implants = list(/obj/item/implant/weapons_auth)
belt = /obj/item/storage/belt/military
r_pocket = /obj/item/storage/pouch/ammo
- l_pocket = /obj/item/gun/energy/disabler/bolt_disabler
+ l_pocket = /obj/item/gun/energy/e_gun/mini
id = /obj/item/card/id/advanced/chameleon
id_trim = /datum/id_trim/chameleon/operative
skillchips = list(/obj/item/skillchip/job/engineer)
backpack_contents = list(
/obj/item/storage/box/survival/engineer/radio,
/obj/item/melee/baton/telescopic,
- /obj/item/gun/ballistic/automatic/pistol/cfa_snub/empty,
- /obj/item/ammo_box/magazine/multi_sprite/cfa_snub,
- /obj/item/ammo_box/magazine/multi_sprite/cfa_snub,
- /obj/item/ammo_box/magazine/multi_sprite/cfa_snub/ap,
- /obj/item/ammo_box/magazine/multi_sprite/cfa_snub/rubber,
- /obj/item/ammo_box/magazine/multi_sprite/cfa_snub/rubber,
+ /obj/item/storage/toolbox/guncase/skyrat/pistol/trappiste_small_case/wespe,
/obj/item/grenade/c4,
/obj/item/grenade/smokebomb
)
@@ -151,18 +146,14 @@
implants = list(/obj/item/implant/weapons_auth)
belt = /obj/item/storage/belt/military
r_pocket = /obj/item/storage/pouch/ammo
- l_pocket = /obj/item/gun/energy/disabler/bolt_disabler
+ l_pocket = /obj/item/gun/energy/e_gun/mini
id = /obj/item/card/id/advanced/chameleon
id_trim = /datum/id_trim/chameleon/operative
skillchips = list(/obj/item/skillchip/job/engineer)
backpack_contents = list(
/obj/item/storage/box/survival/engineer/radio,
/obj/item/melee/baton/telescopic,
- /obj/item/gun/ballistic/automatic/pistol/cfa_ruby/empty,
- /obj/item/ammo_box/magazine/multi_sprite/cfa_ruby/ap,
- /obj/item/ammo_box/magazine/multi_sprite/cfa_ruby/ap,
- /obj/item/ammo_box/magazine/multi_sprite/cfa_ruby/rubber,
- /obj/item/ammo_box/magazine/multi_sprite/cfa_ruby/rubber,
+ /obj/item/storage/toolbox/guncase/skyrat/pistol/trappiste_small_case/skild,
/obj/item/megaphone/command
)
diff --git a/modular_skyrat/modules/microfusion/code/gun_types.dm b/modular_skyrat/modules/microfusion/code/gun_types.dm
index 24a1eeed053..052e3b32db1 100644
--- a/modular_skyrat/modules/microfusion/code/gun_types.dm
+++ b/modular_skyrat/modules/microfusion/code/gun_types.dm
@@ -49,7 +49,6 @@
*/
/obj/effect/spawner/armory_spawn/microfusion
- icon_state = "random_rifle"
guns = list(
/obj/item/gun/microfusion/mcr01,
/obj/item/gun/microfusion/mcr01,
diff --git a/modular_skyrat/modules/modular_ert/code/odst/odst_outfit.dm b/modular_skyrat/modules/modular_ert/code/odst/odst_outfit.dm
index cb618c41d31..41f35615194 100644
--- a/modular_skyrat/modules/modular_ert/code/odst/odst_outfit.dm
+++ b/modular_skyrat/modules/modular_ert/code/odst/odst_outfit.dm
@@ -5,7 +5,7 @@
glasses = /obj/item/clothing/glasses/hud/security/night
ears = /obj/item/radio/headset/headset_cent/alt
gloves = /obj/item/clothing/gloves/combat
- l_hand = /obj/item/gun/ballistic/automatic/pitbull
+ l_hand = /obj/item/gun/ballistic/automatic/sol_rifle/machinegun
belt = /obj/item/storage/belt/military/odst
back = /obj/item/mod/control/pre_equipped/responsory/security
backpack_contents = list(
diff --git a/modular_skyrat/modules/modular_implants/code/nifs.dm b/modular_skyrat/modules/modular_implants/code/nifs.dm
index 9dd1af28751..6ce9f780f83 100644
--- a/modular_skyrat/modules/modular_implants/code/nifs.dm
+++ b/modular_skyrat/modules/modular_implants/code/nifs.dm
@@ -507,6 +507,7 @@
new /obj/item/disk/nifsoft_uploader/summoner(src)
new /obj/item/disk/nifsoft_uploader/money_sense(src)
new /obj/item/disk/nifsoft_uploader/dorms(src)
+ new /obj/item/disk/nifsoft_uploader/dorms/hypnosis(src)
new /obj/item/disk/nifsoft_uploader/soulcatcher(src)
/obj/item/storage/box/nif_ghost_box/ghost_role/PopulateContents()
diff --git a/modular_skyrat/modules/modular_implants/code/nifs_tgui.dm b/modular_skyrat/modules/modular_implants/code/nifs_tgui.dm
index 6da74c6b89f..dfc9916ab83 100644
--- a/modular_skyrat/modules/modular_implants/code/nifs_tgui.dm
+++ b/modular_skyrat/modules/modular_implants/code/nifs_tgui.dm
@@ -121,6 +121,8 @@
return FALSE
current_theme = target_theme
+ for(var/datum/nifsoft/installed_nifsoft as anything in loaded_nifsofts)
+ installed_nifsoft.update_theme()
if("activate_nifsoft")
var/datum/nifsoft/activated_nifsoft = locate(params["activated_nifsoft"]) in loaded_nifsofts
diff --git a/modular_skyrat/modules/modular_implants/code/nifsofts.dm b/modular_skyrat/modules/modular_implants/code/nifsofts.dm
index 1bf551866f5..ddbff9cf86e 100644
--- a/modular_skyrat/modules/modular_implants/code/nifsofts.dm
+++ b/modular_skyrat/modules/modular_implants/code/nifsofts.dm
@@ -18,6 +18,8 @@
var/buying_category = NIFSOFT_CATEGORY_GENERAL
///What font awesome icon is shown next to the name of the nifsoft?
var/ui_icon = "floppy-disk"
+ ///What UI theme do we want to display to users if this NIFSoft has TGUI?
+ var/ui_theme = "default"
///Can the program be installed with other instances of itself?
var/single_install = TRUE
@@ -67,6 +69,7 @@
qdel(src)
load_persistence_data()
+ update_theme()
/datum/nifsoft/Destroy()
if(active)
@@ -148,6 +151,15 @@
/datum/nifsoft/ui_state(mob/user)
return GLOB.conscious_state
+/// Updates the theme of the NIFSoft to match the parent NIF
+/datum/nifsoft/proc/update_theme()
+ var/obj/item/organ/internal/cyberimp/brain/nif/target_nif = parent_nif.resolve()
+ if(!target_nif)
+ return FALSE
+
+ ui_theme = target_nif.current_theme
+ return TRUE
+
/// A disk that can upload NIFSofts to a recpient with a NIFSoft installed.
/obj/item/disk/nifsoft_uploader
name = "Generic NIFSoft datadisk"
diff --git a/modular_skyrat/modules/modular_implants/code/nifsofts/hypnosis.dm b/modular_skyrat/modules/modular_implants/code/nifsofts/hypnosis.dm
index b4f59561872..8576b7cbab2 100644
--- a/modular_skyrat/modules/modular_implants/code/nifsofts/hypnosis.dm
+++ b/modular_skyrat/modules/modular_implants/code/nifsofts/hypnosis.dm
@@ -1,3 +1,7 @@
+/obj/item/disk/nifsoft_uploader/dorms/hypnosis
+ name = "Purpura Eye"
+ loaded_nifsoft = /datum/nifsoft/action_granter/hypnosis
+
/datum/nifsoft/action_granter/hypnosis
name = "Purpura Eye"
program_desc = "Based on the hypnotic equipment provided by the LustWish vendor, the purpura eyes NIFSoft allows the user to ensnare others in a hypnotic trance. ((This is intended as a tool for ERP, don't use this for gameplay reasons.))"
diff --git a/modular_skyrat/modules/modular_implants/code/nifsofts/soul_poem.dm b/modular_skyrat/modules/modular_implants/code/nifsofts/soul_poem.dm
index 4dc4434d59d..093e9e566b7 100644
--- a/modular_skyrat/modules/modular_implants/code/nifsofts/soul_poem.dm
+++ b/modular_skyrat/modules/modular_implants/code/nifsofts/soul_poem.dm
@@ -166,6 +166,7 @@
var/list/data = list()
data["messages"] = message_list
+ data["theme"] = ui_theme
data["receiving_data"] = receiving_data
data["transmitting_data"] = transmitting_data
diff --git a/modular_skyrat/modules/modular_implants/code/nifsofts/soulcatcher.dm b/modular_skyrat/modules/modular_implants/code/nifsofts/soulcatcher.dm
index 019ff546edc..2ec95a411ef 100644
--- a/modular_skyrat/modules/modular_implants/code/nifsofts/soulcatcher.dm
+++ b/modular_skyrat/modules/modular_implants/code/nifsofts/soulcatcher.dm
@@ -94,6 +94,17 @@
persistence.nif_soulcatcher_rooms = list2params(room_list)
return TRUE
+/datum/nifsoft/soulcatcher/update_theme()
+ . = ..()
+ if(!.)
+ return FALSE // uhoh
+
+ var/datum/component/soulcatcher/current_soulcatcher = linked_soulcatcher.resolve()
+ if(!istype(current_soulcatcher))
+ stack_trace("[src] ([REF(src)]) tried to update its theme when it was missing a linked_soulcatcher component!")
+ return FALSE
+ current_soulcatcher.ui_theme = ui_theme
+
/datum/modular_persistence
///A param string containing soulcatcher rooms
var/nif_soulcatcher_rooms = ""
diff --git a/modular_skyrat/modules/modular_implants/code/soulcatcher/soulcatcher_component.dm b/modular_skyrat/modules/modular_implants/code/soulcatcher/soulcatcher_component.dm
index 03512b2c205..88cca7817a2 100644
--- a/modular_skyrat/modules/modular_implants/code/soulcatcher/soulcatcher_component.dm
+++ b/modular_skyrat/modules/modular_implants/code/soulcatcher/soulcatcher_component.dm
@@ -18,6 +18,8 @@ GLOBAL_LIST_EMPTY(soulcatchers)
var/list/soulcatcher_rooms = list()
/// What soulcatcher room are verbs sending messages to?
var/datum/soulcatcher_room/targeted_soulcatcher_room
+ /// What theme are we using for our soulcatcher UI?
+ var/ui_theme = "default"
/// Are ghosts currently able to join this soulcatcher?
var/ghost_joinable = TRUE
diff --git a/modular_skyrat/modules/modular_implants/code/soulcatcher/soulcatcher_tgui.dm b/modular_skyrat/modules/modular_implants/code/soulcatcher/soulcatcher_tgui.dm
index 0c1d11c272e..5dbd31631ec 100644
--- a/modular_skyrat/modules/modular_implants/code/soulcatcher/soulcatcher_tgui.dm
+++ b/modular_skyrat/modules/modular_implants/code/soulcatcher/soulcatcher_tgui.dm
@@ -13,6 +13,7 @@
data["ghost_joinable"] = ghost_joinable
data["require_approval"] = require_approval
+ data["theme"] = ui_theme
data["communicate_as_parent"] = communicate_as_parent
data["current_soul_count"] = length(get_current_souls())
data["max_souls"] = max_souls
diff --git a/modular_skyrat/modules/modular_items/code/bags.dm b/modular_skyrat/modules/modular_items/code/bags.dm
index 3e5e779268f..78d31b6230f 100644
--- a/modular_skyrat/modules/modular_items/code/bags.dm
+++ b/modular_skyrat/modules/modular_items/code/bags.dm
@@ -26,7 +26,7 @@
atom_storage.max_total_storage = 30
atom_storage.max_slots = 3
atom_storage.numerical_stacking = FALSE
- atom_storage.can_hold = typecacheof(list(/obj/item/ammo_box/magazine, /obj/item/ammo_casing, /obj/item/ammo_box/revolver, /obj/item/stock_parts/cell/microfusion))
+ atom_storage.can_hold = typecacheof(list(/obj/item/ammo_box/magazine, /obj/item/ammo_casing, /obj/item/stock_parts/cell/microfusion))
/obj/item/storage/pouch/material
name = "material pouch"
diff --git a/modular_skyrat/modules/modular_vending/code/clothesmate.dm b/modular_skyrat/modules/modular_vending/code/clothesmate.dm
index 73dc53a6465..19dd353f1fe 100644
--- a/modular_skyrat/modules/modular_vending/code/clothesmate.dm
+++ b/modular_skyrat/modules/modular_vending/code/clothesmate.dm
@@ -36,6 +36,7 @@
/obj/item/clothing/glasses/betterunshit = 5,
/obj/item/clothing/glasses/thin = 5,
/obj/item/clothing/glasses/hud/ar/projector = 5,
+ /obj/item/clothing/gloves/bracer/wraps,
),
),
@@ -125,6 +126,7 @@
/obj/item/clothing/shoes/colorable_sandals = 5,
/obj/item/clothing/shoes/sports = 5,
/obj/item/clothing/shoes/wraps/colourable = 5,
+ /obj/item/clothing/shoes/wraps/cloth = 5,
/obj/item/clothing/shoes/jungleboots = 5,
/obj/item/clothing/shoes/jackboots/knee = 5,
/obj/item/clothing/shoes/jackboots/recolorable = 5,
diff --git a/modular_skyrat/modules/modular_weapons/code/autolathe_designs.dm b/modular_skyrat/modules/modular_weapons/code/autolathe_designs.dm
index f51d6883d64..89695235d2b 100644
--- a/modular_skyrat/modules/modular_weapons/code/autolathe_designs.dm
+++ b/modular_skyrat/modules/modular_weapons/code/autolathe_designs.dm
@@ -46,16 +46,6 @@
build_path = /obj/item/ammo_casing/c45/rubber
category = list(RND_CATEGORY_INITIAL, RND_CATEGORY_WEAPONS + RND_SUBCATEGORY_WEAPONS_AMMO)
-// .460 Rowland magnum, for the M45A5
-
-/datum/design/b460
- name = ".460 Rowland magnum"
- id = "b460"
- build_type = AUTOLATHE
- materials = list(/datum/material/iron = SMALL_MATERIAL_AMOUNT * 8)
- build_path = /obj/item/ammo_casing/b460
- category = list(RND_CATEGORY_HACKED, RND_CATEGORY_WEAPONS + RND_SUBCATEGORY_WEAPONS_AMMO)
-
// 10mm
/datum/design/c10mm_lethal
name = "10mm Bullet"
diff --git a/modular_skyrat/modules/modular_weapons/code/automatic.dm b/modular_skyrat/modules/modular_weapons/code/automatic.dm
deleted file mode 100644
index e9ccae147c9..00000000000
--- a/modular_skyrat/modules/modular_weapons/code/automatic.dm
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
-* MAGAZINES
-*/
-
-/obj/item/ammo_box/magazine/multi_sprite/cfa_wildcat
- name = "CFA Wildcat magazine (.34)"
- desc = "Magazines taking .34 ammunition; it fits in the CFA Wildcat. Alt+click to reskin it."
- icon = 'modular_skyrat/modules/modular_weapons/icons/obj/ammo.dmi'
- icon_state = "smg34"
- possible_types = list(AMMO_TYPE_LETHAL, AMMO_TYPE_AP, AMMO_TYPE_RUBBER, AMMO_TYPE_INCENDIARY)
- ammo_type = /obj/item/ammo_casing/c34
- caliber = "c34acp"
- max_ammo = 30
- multiple_sprites = AMMO_BOX_FULL_EMPTY
-
-/obj/item/ammo_box/magazine/multi_sprite/cfa_wildcat/ap
- ammo_type = /obj/item/ammo_casing/c34/ap
- round_type = AMMO_TYPE_AP
-
-/obj/item/ammo_box/magazine/multi_sprite/cfa_wildcat/rubber
- ammo_type = /obj/item/ammo_casing/c34/rubber
- round_type = AMMO_TYPE_RUBBER
-
-/obj/item/ammo_box/magazine/multi_sprite/cfa_wildcat/incendiary
- ammo_type = /obj/item/ammo_casing/c34_incendiary
- round_type = AMMO_TYPE_INCENDIARY
-
-/obj/item/ammo_box/magazine/multi_sprite/cfa_wildcat/empty
- start_empty = 1
-
-/*
-* WILDCAT
-* 3rnd burst .32 calibre, 15 damage.
-* Fills the role of a low damage, high magazine capacity magdump gun.
-*/
-
-/obj/item/gun/ballistic/automatic/cfa_wildcat
- name = "\improper CFA Wildcat"
- desc = "A robust roller-delayed SMG chambered for .34 ammunition."
- icon = 'modular_skyrat/modules/modular_weapons/icons/obj/guns/projectile40x32.dmi'
- icon_state = "mp5"
- inhand_icon_state = "arg"
- selector_switch_icon = TRUE
- accepted_magazine_type = /obj/item/ammo_box/magazine/multi_sprite/cfa_wildcat
- can_suppress = FALSE
- fire_delay = 1.25
- spread = 5
- mag_display = TRUE
- empty_indicator = FALSE
- fire_sound = 'sound/weapons/gun/smg/shot_alt.ogg'
- weapon_weight = WEAPON_MEDIUM
- w_class = WEIGHT_CLASS_BULKY
-
-/obj/item/gun/ballistic/automatic/cfa_wildcat/Initialize(mapload)
- . = ..()
-
- AddComponent(/datum/component/automatic_fire, fire_delay)
-
-/obj/item/gun/ballistic/automatic/cfa_wildcat/give_manufacturer_examine()
- AddElement(/datum/element/manufacturer_examine, COMPANY_CANTALAN)
-
-/obj/item/gun/ballistic/automatic/cfa_wildcat/no_mag
- spawnwithmagazine = FALSE
-
-/*
-* CFA LYNX
-*/
-
-/obj/item/gun/ballistic/automatic/cfa_lynx
- name = "\improper CFA Lynx"
- desc = "A carbine with a high magazine capacity. Chambered in 4.2x30mm."
- icon = 'modular_skyrat/modules/modular_weapons/icons/obj/guns/projectile.dmi'
- icon_state = "cfa-lynx"
- inhand_icon_state = "arg"
- selector_switch_icon = FALSE
- accepted_magazine_type = /obj/item/ammo_box/magazine/multi_sprite/cfa_lynx
- can_suppress = FALSE
- fire_delay = 1.90 //Previously 0.5. Changed due to it being the Blueshield's default firearm.
- spread = 2
- mag_display = TRUE
- empty_indicator = FALSE
- fire_sound = 'sound/weapons/gun/smg/shot_alt.ogg'
- weapon_weight = WEAPON_MEDIUM
- w_class = WEIGHT_CLASS_BULKY
-
-/obj/item/gun/ballistic/automatic/cfa_lynx/Initialize(mapload)
- . = ..()
-
- AddComponent(/datum/component/automatic_fire, fire_delay)
-
-/obj/item/gun/ballistic/automatic/cfa_lynx/give_manufacturer_examine()
- AddElement(/datum/element/manufacturer_examine, COMPANY_CANTALAN)
-
-/obj/item/gun/ballistic/automatic/cfa_lynx/no_mag
- spawnwithmagazine = FALSE
-
-/obj/item/ammo_box/magazine/multi_sprite/cfa_lynx
- name = "CFA Lynx Magazine (4.2x30mm)"
- desc = "A magazine for the CFA Lynx. It has a small inscription on the base, '4.2x30mm'. Alt+click to reskin it."
- icon = 'modular_skyrat/modules/modular_weapons/icons/obj/ammo.dmi'
- icon_state = "lynx"
- possible_types = list(AMMO_TYPE_LETHAL, AMMO_TYPE_AP, AMMO_TYPE_RUBBER, AMMO_TYPE_INCENDIARY)
- ammo_type = /obj/item/ammo_casing/c42x30mm
- caliber = CALIBER_42X30MM
- max_ammo = 40
- multiple_sprites = AMMO_BOX_FULL_EMPTY
-
-/obj/item/ammo_box/magazine/multi_sprite/cfa_lynx/ap
- ammo_type = /obj/item/ammo_casing/c42x30mm/ap
- round_type = AMMO_TYPE_AP
-
-/obj/item/ammo_box/magazine/multi_sprite/cfa_lynx/rubber
- ammo_type = /obj/item/ammo_casing/c42x30mm/rubber
- round_type = AMMO_TYPE_RUBBER
-
-/obj/item/ammo_box/magazine/multi_sprite/cfa_lynx/incendiary
- ammo_type = /obj/item/ammo_casing/c42x30mm/inc
- round_type = AMMO_TYPE_INCENDIARY
-
-/obj/item/ammo_box/magazine/multi_sprite/cfa_lynx/empty
- start_empty = TRUE
diff --git a/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/advert.dm b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/advert.dm
new file mode 100644
index 00000000000..3f0dedf2889
--- /dev/null
+++ b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/advert.dm
@@ -0,0 +1,36 @@
+/obj/structure/sign/poster/official/carwo_grenade
+ name = "Tydhouer - Precision Timing"
+ desc = "This poster depicts, alongside the prominent logo of Carwo Defense Systems, a variety of specialist .980 Tydhouer grenades for the Kiboko launcher."
+ icon = 'modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/propaganda.dmi'
+ icon_state = "grenadier"
+
+/obj/structure/sign/poster/official/carwo_grenade/examine_more(mob/user)
+ . = ..()
+
+ . += "Small text details that certain types of grenades may not be available in your \
+ region depending on local weapons regulations. Suspiciously, however, if you squint at \
+ it a bit, the background colors of the image come together vaguely in the shape of \
+ a computer board and a multitool. What did they mean by this?"
+
+ return .
+
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/sign/poster/official/carwo_grenade, 32)
+
+/obj/structure/sign/poster/official/carwo_magazine
+ name = "Standardisation - Magazines of the Future"
+ desc = "This poster depicts, alongside the prominent logo of Carwo Defense Systems, the variety of magazine types the company has on offer for rifles. \
+ It also goes into great deal to say, more or less, that any rifle can take any rifle magazine. Now this is technology like never seen before."
+ icon = 'modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/propaganda.dmi'
+ icon_state = "mag_size"
+
+/obj/structure/sign/poster/official/carwo_magazine/examine_more(mob/user)
+ . = ..()
+
+ . += "Small text details that certain types of magazines may not be available in your \
+ region depending on local weapons regulations. Suspiciously, however, if you squint at \
+ it a bit, the background colors of the image come together vaguely in the shape of \
+ a computer board and a multitool. What did they mean by this?"
+
+ return .
+
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/sign/poster/official/carwo_magazine, 32)
diff --git a/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/ammo/grenade.dm b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/ammo/grenade.dm
new file mode 100644
index 00000000000..37c9fc0f835
--- /dev/null
+++ b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/ammo/grenade.dm
@@ -0,0 +1,260 @@
+#define AMMO_MATS_GRENADE list( \
+ /datum/material/iron = SMALL_MATERIAL_AMOUNT * 4, \
+)
+
+#define AMMO_MATS_GRENADE_SHRAPNEL list( \
+ /datum/material/iron = SMALL_MATERIAL_AMOUNT * 2,\
+ /datum/material/titanium = SMALL_MATERIAL_AMOUNT * 2, \
+)
+
+#define AMMO_MATS_GRENADE_INCENDIARY list( \
+ /datum/material/iron = SMALL_MATERIAL_AMOUNT * 2,\
+ /datum/material/plasma = SMALL_MATERIAL_AMOUNT * 2, \
+)
+
+#define GRENADE_SMOKE_RANGE 0.75
+
+// .980 grenades
+// Grenades that can be given a range to detonate at by their firing gun
+
+/obj/item/ammo_casing/c980grenade
+ name = ".980 Tydhouer practice grenade"
+ desc = "A large grenade shell that will detonate at a range given to it by the gun that fires it. Practice shells disintegrate into harmless sparks."
+
+ icon = 'modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/ammo.dmi'
+ icon_state = "980_solid"
+
+ caliber = CALIBER_980TYDHOUER
+ projectile_type = /obj/projectile/bullet/c980grenade
+
+ custom_materials = AMMO_MATS_GRENADE
+
+ harmful = FALSE //Erm, technically
+
+
+/obj/item/ammo_casing/c980grenade/fire_casing(atom/target, mob/living/user, params, distro, quiet, zone_override, spread, atom/fired_from)
+ var/obj/item/gun/ballistic/automatic/sol_grenade_launcher/firing_launcher = fired_from
+ if(istype(firing_launcher))
+ loaded_projectile.range = firing_launcher.target_range
+
+ . = ..()
+
+
+/obj/projectile/bullet/c980grenade
+ name = ".980 Tydhouer practice grenade"
+ damage = 20
+ stamina = 30
+
+ range = 14
+
+ speed = 2 // Higher means slower, y'all
+
+ sharpness = NONE
+
+
+/obj/projectile/bullet/c980grenade/on_hit(atom/target, blocked = FALSE)
+ ..()
+ fuse_activation(target)
+ return BULLET_ACT_HIT
+
+
+/obj/projectile/bullet/c980grenade/on_range()
+ fuse_activation(get_turf(src))
+ return ..()
+
+
+/// Generic proc that is called when the projectile should 'detonate', being either on impact or when the range runs out
+/obj/projectile/bullet/c980grenade/proc/fuse_activation(atom/target)
+ playsound(src, 'modular_skyrat/modules/modular_weapons/sounds/grenade_burst.ogg', 50, TRUE, -3)
+ do_sparks(3, FALSE, src)
+
+
+/obj/item/ammo_box/c980grenade
+ name = "ammo box (.980 Tydhouer practice)"
+ desc = "A box of four .980 Tydhouer practice grenades. Instructions on the box indicate these are dummy practice rounds that will disintegrate into sparks on detonation. Neat!"
+
+ icon = 'modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/ammo.dmi'
+ icon_state = "980box_solid"
+
+ multiple_sprites = AMMO_BOX_FULL_EMPTY
+
+ w_class = WEIGHT_CLASS_NORMAL
+
+ caliber = CALIBER_980TYDHOUER
+ ammo_type = /obj/item/ammo_casing/c980grenade
+ max_ammo = 4
+
+
+// .980 smoke grenade
+
+/obj/item/ammo_casing/c980grenade/smoke
+ name = ".980 Tydhouer smoke grenade"
+ desc = "A large grenade shell that will detonate at a range given to it by the gun that fires it. Bursts into a laser-weakening smoke cloud."
+
+ icon_state = "980_smoke"
+
+ projectile_type = /obj/projectile/bullet/c980grenade/smoke
+
+
+/obj/projectile/bullet/c980grenade/smoke
+ name = ".980 Tydhouer smoke grenade"
+
+
+/obj/projectile/bullet/c980grenade/smoke/fuse_activation(atom/target)
+ playsound(src, 'modular_skyrat/modules/modular_weapons/sounds/grenade_burst.ogg', 50, TRUE, -3)
+ playsound(src, 'sound/effects/smoke.ogg', 50, TRUE, -3)
+ var/datum/effect_system/fluid_spread/smoke/bad/smoke = new
+ smoke.set_up(GRENADE_SMOKE_RANGE, holder = src, location = src)
+ smoke.start()
+
+
+/obj/item/ammo_box/c980grenade/smoke
+ name = "ammo box (.980 Tydhouer smoke)"
+ desc = "A box of four .980 Tydhouer smoke grenades. Instructions on the box indicate these are smoke rounds that will make a small cloud of laser-dampening smoke on detonation."
+
+ icon_state = "980box_smoke"
+
+ ammo_type = /obj/item/ammo_casing/c980grenade/smoke
+
+
+// .980 shrapnel grenade
+
+/obj/item/ammo_casing/c980grenade/shrapnel
+ name = ".980 Tydhouer shrapnel grenade"
+ desc = "A large grenade shell that will detonate at a range given to it by the gun that fires it. Explodes into shrapnel on detonation."
+
+ icon_state = "980_explosive"
+
+ projectile_type = /obj/projectile/bullet/c980grenade/shrapnel
+
+ custom_materials = AMMO_MATS_GRENADE_SHRAPNEL
+ advanced_print_req = TRUE
+
+ harmful = TRUE
+
+
+/obj/projectile/bullet/c980grenade/shrapnel
+ name = ".980 Tydhouer shrapnel grenade"
+
+ /// What type of casing should we put inside the bullet to act as shrapnel later
+ var/casing_to_spawn = /obj/item/grenade/c980payload
+
+
+/obj/projectile/bullet/c980grenade/shrapnel/fuse_activation(atom/target)
+ var/obj/item/grenade/shrapnel_maker = new casing_to_spawn(get_turf(src))
+
+ shrapnel_maker.detonate()
+ qdel(shrapnel_maker)
+
+ playsound(src, 'modular_skyrat/modules/modular_weapons/sounds/grenade_burst.ogg', 50, TRUE, -3)
+
+
+/obj/item/ammo_box/c980grenade/shrapnel
+ name = "ammo box (.980 Tydhouer shrapnel)"
+ desc = "A box of four .980 Tydhouer shrapnel grenades. Instructions on the box indicate these are shrapnel rounds. Its also covered in hazard signs, odd."
+
+ icon_state = "980box_explosive"
+
+ ammo_type = /obj/item/ammo_casing/c980grenade/shrapnel
+
+
+/obj/item/grenade/c980payload
+ shrapnel_type = /obj/projectile/bullet/shrapnel/short_range
+ shrapnel_radius = 2
+ ex_dev = 0
+ ex_heavy = 0
+ ex_light = 0
+ ex_flame = 0
+
+
+/obj/projectile/bullet/shrapnel/short_range
+ range = 2
+
+
+// .980 phosphor grenade
+
+/obj/item/ammo_casing/c980grenade/shrapnel/phosphor
+ name = ".980 Tydhouer phosphor grenade"
+ desc = "A large grenade shell that will detonate at a range given to it by the gun that fires it. Explodes into smoke and flames on detonation."
+
+ icon_state = "980_gas_alternate"
+
+ projectile_type = /obj/projectile/bullet/c980grenade/shrapnel/phosphor
+
+ custom_materials = AMMO_MATS_GRENADE_INCENDIARY
+
+
+/obj/projectile/bullet/c980grenade/shrapnel/phosphor
+ name = ".980 Tydhouer phosphor grenade"
+
+ casing_to_spawn = /obj/item/grenade/c980payload/phosphor
+
+
+/obj/projectile/bullet/c980grenade/shrapnel/phosphor/fuse_activation(atom/target)
+ . = ..()
+
+ playsound(src, 'sound/effects/smoke.ogg', 50, TRUE, -3)
+ var/datum/effect_system/fluid_spread/smoke/quick/smoke = new
+ smoke.set_up(GRENADE_SMOKE_RANGE, holder = src, location = src)
+ smoke.start()
+
+
+/obj/item/ammo_box/c980grenade/shrapnel/phosphor
+ name = "ammo box (.980 Tydhouer phosphor)"
+ desc = "A box of four .980 Tydhouer phosphor grenades. Instructions on the box indicate these are incendiary explosive rounds. Its also covered in hazard signs, odd."
+
+ icon_state = "980box_gas_alternate"
+
+ ammo_type = /obj/item/ammo_casing/c980grenade/shrapnel/phosphor
+
+
+/obj/item/ammo_casing/shrapnel_exploder/phosphor
+ pellets = 8
+
+ projectile_type = /obj/projectile/bullet/incendiary/fire/backblast/short_range
+
+
+/obj/item/grenade/c980payload/phosphor
+ shrapnel_type = /obj/projectile/bullet/incendiary/fire/backblast/short_range
+
+
+/obj/projectile/bullet/incendiary/fire/backblast/short_range
+ range = 2
+
+
+// .980 tear gas grenade
+
+/obj/item/ammo_casing/c980grenade/riot
+ name = ".980 Tydhouer tear gas grenade"
+ desc = "A large grenade shell that will detonate at a range given to it by the gun that fires it. Bursts into a tear gas cloud."
+
+ icon_state = "980_gas"
+
+ projectile_type = /obj/projectile/bullet/c980grenade/riot
+
+
+/obj/projectile/bullet/c980grenade/riot
+ name = ".980 Tydhouer tear gas grenade"
+
+/obj/projectile/bullet/c980grenade/riot/fuse_activation(atom/target)
+ playsound(src, 'modular_skyrat/modules/modular_weapons/sounds/grenade_burst.ogg', 50, TRUE, -3)
+ playsound(src, 'sound/effects/smoke.ogg', 50, TRUE, -3)
+ var/datum/effect_system/fluid_spread/smoke/chem/smoke = new()
+ smoke.chemholder.add_reagent(/datum/reagent/consumable/condensedcapsaicin, 10)
+ smoke.set_up(GRENADE_SMOKE_RANGE, holder = src, location = src)
+ smoke.start()
+
+
+/obj/item/ammo_box/c980grenade/riot
+ name = "ammo box (.980 Tydhouer tear gas)"
+ desc = "A box of four .980 Tydhouer tear gas grenades. Instructions on the box indicate these are smoke rounds that will make a small cloud of laser-dampening smoke on detonation."
+
+ icon_state = "980box_gas"
+
+ ammo_type = /obj/item/ammo_casing/c980grenade/riot
+
+#undef AMMO_MATS_GRENADE
+#undef AMMO_MATS_GRENADE_SHRAPNEL
+#undef AMMO_MATS_GRENADE_INCENDIARY
+
+#undef GRENADE_SMOKE_RANGE
diff --git a/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/ammo/pistol.dm b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/ammo/pistol.dm
new file mode 100644
index 00000000000..e20070dcef5
--- /dev/null
+++ b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/ammo/pistol.dm
@@ -0,0 +1,134 @@
+// .35 Sol Short
+// Pistol caliber caseless round used almost exclusively by SolFed weapons
+
+/obj/item/ammo_casing/c35sol
+ name = ".35 Sol Short lethal bullet casing"
+ desc = "A SolFed standard caseless lethal pistol round."
+
+ icon = 'modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/ammo.dmi'
+ icon_state = "35sol"
+
+ caliber = CALIBER_SOL35SHORT
+ projectile_type = /obj/projectile/bullet/c35sol
+
+
+/obj/item/ammo_casing/c35sol/Initialize(mapload)
+ . = ..()
+
+ AddElement(/datum/element/caseless)
+
+
+/obj/projectile/bullet/c35sol
+ name = ".35 Sol Short bullet"
+ damage = 25
+
+ wound_bonus = 10 // Normal bullets are 20
+ bare_wound_bonus = 20
+
+
+/obj/item/ammo_box/c35sol
+ name = "ammo box (.35 Sol Short lethal)"
+ desc = "A box of .35 Sol Short pistol rounds, holds twenty-four rounds."
+
+ icon = 'modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/ammo.dmi'
+ icon_state = "35box"
+
+ multiple_sprites = AMMO_BOX_FULL_EMPTY
+
+ w_class = WEIGHT_CLASS_NORMAL
+
+ caliber = CALIBER_SOL35SHORT
+ ammo_type = /obj/item/ammo_casing/c35sol
+ max_ammo = 24
+
+
+// .35 Sol's equivalent to a rubber bullet
+
+/obj/item/ammo_casing/c35sol/incapacitator
+ name = ".35 Sol Short incapacitator bullet casing"
+ desc = "A SolFed standard caseless less-lethal pistol round. Exhausts targets on hit, has a tendency to bounce off walls at shallow angles."
+
+ icon_state = "35sol_disabler"
+
+ projectile_type = /obj/projectile/bullet/c35sol/incapacitator
+ harmful = FALSE
+
+
+/obj/projectile/bullet/c35sol/incapacitator
+ name = ".35 Sol Short incapacitator bullet"
+ damage = 5
+ stamina = 30
+
+ wound_bonus = -40
+ bare_wound_bonus = -20
+
+ weak_against_armour = TRUE
+
+ // The stats of the ricochet are a nerfed version of detective revolver rubber ammo
+ // This is due to the fact that there's a lot more rounds fired quickly from weapons that use this, over a revolver
+ ricochet_auto_aim_angle = 30
+ ricochet_auto_aim_range = 5
+ ricochets_max = 4
+ ricochet_incidence_leeway = 50
+ ricochet_chance = 130
+ ricochet_decay_damage = 0.8
+
+ shrapnel_type = null
+ sharpness = NONE
+ embedding = null
+
+
+/obj/item/ammo_box/c35sol/incapacitator
+ name = "ammo box (.35 Sol Short incapacitator)"
+ desc = "A box of .35 Sol Short pistol rounds, holds twenty-four rounds. The blue stripe indicates this should hold less-lethal ammunition."
+
+ icon_state = "35box_disabler"
+
+ ammo_type = /obj/item/ammo_casing/c35sol/incapacitator
+
+
+// .35 Sol ripper, similar to the detective revolver's dumdum rounds, causes slash wounds and is weak to armor
+
+/obj/item/ammo_casing/c35sol/ripper
+ name = ".35 Sol Short ripper bullet casing"
+ desc = "A SolFed standard caseless ripper pistol round. Causes slashing wounds on targets, but is weak to armor."
+
+ icon_state = "35sol_shrapnel"
+ projectile_type = /obj/projectile/bullet/c35sol/ripper
+
+ custom_materials = AMMO_MATS_RIPPER
+ advanced_print_req = TRUE
+
+
+/obj/projectile/bullet/c35sol/ripper
+ name = ".35 Sol ripper bullet"
+ damage = 15
+
+ weak_against_armour = TRUE
+
+ sharpness = SHARP_EDGED
+
+ wound_bonus = 20
+ bare_wound_bonus = 20
+
+ embedding = list(
+ embed_chance = 75,
+ fall_chance = 3,
+ jostle_chance = 4,
+ ignore_throwspeed_threshold = TRUE,
+ pain_stam_pct = 0.4,
+ pain_mult = 5,
+ jostle_pain_mult = 6,
+ rip_time = 1 SECONDS,
+ )
+
+ embed_falloff_tile = -15
+
+
+/obj/item/ammo_box/c35sol/ripper
+ name = "ammo box (.35 Sol Short ripper)"
+ desc = "A box of .35 Sol Short pistol rounds, holds twenty-four rounds. The purple stripe indicates this should hold hollowpoint-like ammunition."
+
+ icon_state = "35box_shrapnel"
+
+ ammo_type = /obj/item/ammo_casing/c35sol/ripper
diff --git a/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/ammo/rifle.dm b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/ammo/rifle.dm
new file mode 100644
index 00000000000..a012b594c29
--- /dev/null
+++ b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/ammo/rifle.dm
@@ -0,0 +1,195 @@
+// .40 Sol Long
+// Rifle caliber caseless ammo that kills people good
+
+/obj/item/ammo_casing/c40sol
+ name = ".40 Sol Long lethal bullet casing"
+ desc = "A SolFed standard caseless lethal rifle round."
+
+ icon = 'modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/ammo.dmi'
+ icon_state = "40sol"
+
+ caliber = CALIBER_SOL40LONG
+ projectile_type = /obj/projectile/bullet/c40sol
+
+
+/obj/item/ammo_casing/c40sol/Initialize(mapload)
+ . = ..()
+
+ AddElement(/datum/element/caseless)
+
+
+/obj/projectile/bullet/c40sol
+ name = ".40 Sol Long bullet"
+ damage = 35
+
+ wound_bonus = 10
+ bare_wound_bonus = 20
+
+
+/obj/item/ammo_box/c40sol
+ name = "ammo box (.40 Sol Long lethal)"
+ desc = "A box of .40 Sol Long rifle rounds, holds thirty bullets."
+
+ icon = 'modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/ammo.dmi'
+ icon_state = "40box"
+
+ multiple_sprites = AMMO_BOX_FULL_EMPTY
+
+ w_class = WEIGHT_CLASS_NORMAL
+
+ caliber = CALIBER_SOL40LONG
+ ammo_type = /obj/item/ammo_casing/c40sol
+ max_ammo = 30
+
+
+// .40 Sol fragmentation rounds, embeds shrapnel in the target almost every time at close to medium range. Teeeechnically less lethals.
+
+/obj/item/ammo_casing/c40sol/fragmentation
+ name = ".40 Sol Long fragmentation bullet casing"
+ desc = "A SolFed standard caseless fragmentation rifle round. Shatters upon impact, ejecting sharp shrapnel that can potentially incapacitate targets."
+
+ icon_state = "40sol_disabler"
+
+ projectile_type = /obj/projectile/bullet/c40sol/fragmentation
+
+ advanced_print_req = TRUE
+
+ harmful = FALSE
+
+
+/obj/projectile/bullet/c40sol/fragmentation
+ name = ".40 Sol Long fragmentation bullet"
+ damage = 15
+ stamina = 30
+
+ weak_against_armour = TRUE
+
+ sharpness = SHARP_EDGED
+ wound_bonus = 0
+ bare_wound_bonus = 10
+
+ shrapnel_type = /obj/item/shrapnel/stingball
+ embedding = list(
+ embed_chance = 50,
+ fall_chance = 5,
+ jostle_chance = 5,
+ ignore_throwspeed_threshold = TRUE,
+ pain_stam_pct = 0.4,
+ pain_mult = 2,
+ jostle_pain_mult = 3,
+ rip_time = 0.5 SECONDS,
+ )
+
+ embed_falloff_tile = -5
+
+
+/obj/item/ammo_box/c40sol/fragmentation
+ name = "ammo box (.40 Sol Long fragmentation)"
+ desc = "A box of .40 Sol Long rifle rounds, holds thirty bullets. The blue stripe indicates this should hold less lethal ammunition."
+
+ icon_state = "40box_disabler"
+
+ ammo_type = /obj/item/ammo_casing/c40sol/fragmentation
+
+
+// .40 Sol match grade, bounces a lot, and if there's less than 20 bullet armor on wherever these hit, it'll go completely through the target and out the other side
+
+/obj/item/ammo_casing/c40sol/pierce
+ name = ".40 Sol Long match bullet casing"
+ desc = "A SolFed standard caseless match grade rifle round. Fires at a higher pressure and thus fires slightly faster projectiles. \
+ Rumors say you can do sick ass wall bounce trick shots with these, though the official suggestion is to just shoot your target and \
+ not the wall next to them."
+
+ icon_state = "40sol_pierce"
+
+ projectile_type = /obj/projectile/bullet/c40sol/pierce
+
+ custom_materials = AMMO_MATS_AP
+ advanced_print_req = TRUE
+
+
+/obj/projectile/bullet/c40sol/pierce
+ name = ".40 Sol match bullet"
+
+ icon_state = "gaussphase"
+
+ speed = 0.5
+
+ damage = 25
+ armour_penetration = 20
+
+ wound_bonus = -30
+ bare_wound_bonus = -10
+
+ ricochets_max = 2
+ ricochet_chance = 80
+ ricochet_auto_aim_range = 4
+ ricochet_incidence_leeway = 65
+
+ projectile_piercing = PASSMOB
+
+
+/obj/projectile/bullet/c40sol/pierce/on_hit(atom/target, blocked = FALSE)
+ if(isliving(target))
+ var/mob/living/poor_sap = target
+
+ // If the target mob has enough armor to stop the bullet, or the bullet has already gone through two people, stop it on this hit
+ if((poor_sap.run_armor_check(def_zone, BULLET, "", "", silent = TRUE) > 20) || (pierces > 2))
+ projectile_piercing = NONE
+
+ if(damage > 10) // Lets just be safe with this one
+ damage -= 5
+ armour_penetration -= 10
+
+ return ..()
+
+
+/obj/item/ammo_box/c40sol/pierce
+ name = "ammo box (.40 Sol Long match)"
+ desc = "A box of .40 Sol Long rifle rounds, holds thirty bullets. The yellow stripe indicates this should hold high performance ammuniton."
+
+ icon_state = "40box_pierce"
+
+ ammo_type = /obj/item/ammo_casing/c40sol/pierce
+
+
+// .40 Sol incendiary
+
+/obj/item/ammo_casing/c40sol/incendiary
+ name = ".40 Sol Long incendiary bullet casing"
+ desc = "A SolFed standard caseless incendiary rifle round. Leaves no flaming trail, only igniting targets on impact."
+
+ icon_state = "40sol_flame"
+
+ projectile_type = /obj/projectile/bullet/c40sol/incendiary
+
+ custom_materials = AMMO_MATS_TEMP
+ advanced_print_req = TRUE
+
+
+/obj/projectile/bullet/c40sol/incendiary
+ name = ".40 Sol Long incendiary bullet"
+ icon_state = "redtrac"
+
+ damage = 25
+
+ /// How many firestacks the bullet should impart upon a target when impacting
+ var/firestacks_to_give = 1
+
+
+/obj/projectile/bullet/c40sol/incendiary/on_hit(atom/target, blocked = FALSE)
+ . = ..()
+
+ if(iscarbon(target))
+ var/mob/living/carbon/gaslighter = target
+ gaslighter.adjust_fire_stacks(firestacks_to_give)
+ gaslighter.ignite_mob()
+
+
+/obj/item/ammo_box/c40sol/incendiary
+ name = "ammo box (.40 Sol Long incendiary)"
+ desc = "A box of .40 Sol Long rifle rounds, holds thirty bullets. The orange stripe indicates this should hold incendiary ammunition."
+
+ icon_state = "40box_flame"
+
+ ammo_type = /obj/item/ammo_casing/c40sol/incendiary
diff --git a/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/grenade_launcher.dm b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/grenade_launcher.dm
new file mode 100644
index 00000000000..b927e1cd38d
--- /dev/null
+++ b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/grenade_launcher.dm
@@ -0,0 +1,93 @@
+// Low caliber grenade launcher (fun & games)
+
+/obj/item/gun/ballistic/automatic/sol_grenade_launcher
+ name = "\improper Carwo 'Kiboko' Grenade Launcher"
+ desc = "A unique grenade launcher firing .980 grenades. A laser sight system allows its user to specify a range for the grenades it fires to detonate at."
+
+ icon = 'modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/guns48x.dmi'
+ icon_state = "kiboko"
+
+ worn_icon = 'modular_skyrat/modules/modular_weapons/icons/mob/company_and_or_faction_based/carwo_defense_systems/guns_worn.dmi'
+ worn_icon_state = "kiboko"
+
+ lefthand_file = 'modular_skyrat/modules/modular_weapons/icons/mob/company_and_or_faction_based/carwo_defense_systems/guns_lefthand.dmi'
+ righthand_file = 'modular_skyrat/modules/modular_weapons/icons/mob/company_and_or_faction_based/carwo_defense_systems/guns_righthand.dmi'
+ inhand_icon_state = "kiboko"
+
+ SET_BASE_PIXEL(-8, 0)
+
+ special_mags = TRUE
+
+ bolt_type = BOLT_TYPE_LOCKING
+
+ w_class = WEIGHT_CLASS_BULKY
+ weapon_weight = WEAPON_HEAVY
+ slot_flags = ITEM_SLOT_BACK | ITEM_SLOT_OCLOTHING
+
+ accepted_magazine_type = /obj/item/ammo_box/magazine/c980_grenade
+
+ fire_sound = 'modular_skyrat/modules/modular_weapons/sounds/grenade_launcher.ogg'
+
+ can_suppress = FALSE
+ can_bayonet = FALSE
+
+ burst_size = 1
+ fire_delay = 5
+ actions_types = list()
+
+ /// The currently stored range to detonate shells at
+ var/target_range = 14
+ /// The maximum range we can set grenades to detonate at, just to be safe
+ var/maximum_target_range = 14
+
+/obj/item/gun/ballistic/automatic/sol_grenade_launcher/give_manufacturer_examine()
+ AddElement(/datum/element/manufacturer_examine, COMPANY_CARWO)
+
+/obj/item/gun/ballistic/automatic/sol_grenade_launcher/examine_more(mob/user)
+ . = ..()
+
+ . += "The Kiboko is one of the strangest weapons Carwo offers. A grenade launcher, \
+ though not in the standard grenade size. The much lighter .980 Tydhouer grenades \
+ developed for the weapon offered many advantages over standard grenade launching \
+ ammunition. For a start, it was significantly lighter, and easier to carry large \
+ amounts of. What it also offered, however, and the reason SolFed funded the \
+ project: Variable time fuze. Using the large and expensive ranging sight on the \
+ launcher, its user can set an exact distance for the grenade to self detonate at. \
+ The dream of militaries for decades, finally realized. The smaller shells do not, \
+ however, make the weapon any more enjoyable to fire. The kick is only barely \
+ manageable thanks to the massive muzzle brake at the front."
+
+ return .
+
+/obj/item/gun/ballistic/automatic/sol_grenade_launcher/examine(mob/user)
+ . = ..()
+
+ . += span_notice("With Right Click you can set the range that shells will detonate at.")
+ . += span_notice("A small indicator in the sight notes the current detonation range is: [target_range].")
+
+/obj/item/gun/ballistic/automatic/sol_grenade_launcher/afterattack_secondary(atom/target, mob/living/user, proximity_flag, click_parameters)
+ if(!target || !user)
+ return
+
+ var/distance_ranged = get_dist(user, target)
+ if(distance_ranged > maximum_target_range)
+ user.balloon_alert(user, "out of range")
+ return
+
+ target_range = distance_ranged
+ user.balloon_alert(user, "range set: [target_range]")
+
+/obj/item/gun/ballistic/automatic/sol_grenade_launcher/no_mag
+ spawnwithmagazine = FALSE
+
+// fun & games but evil this time
+
+/obj/item/gun/ballistic/automatic/sol_grenade_launcher/evil
+ icon_state = "kiboko_evil"
+ worn_icon_state = "kiboko_evil"
+ inhand_icon_state = "kiboko_evil"
+
+ spawn_magazine_type = /obj/item/ammo_box/magazine/c980_grenade/drum
+
+/obj/item/gun/ballistic/automatic/sol_grenade_launcher/evil/no_mag
+ spawnwithmagazine = FALSE
diff --git a/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/gunsets.dm b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/gunsets.dm
new file mode 100644
index 00000000000..030d17d0c43
--- /dev/null
+++ b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/gunsets.dm
@@ -0,0 +1,85 @@
+// Base yellow carwo case
+
+/obj/item/storage/toolbox/guncase/skyrat/carwo_large_case
+ desc = "A thick yellow gun case with foam inserts laid out to fit a weapon, magazines, and gear securely."
+
+ icon = 'modular_skyrat/modules/modular_weapons/icons/obj/gunsets.dmi'
+ icon_state = "case_carwo"
+
+ worn_icon_state = "yellowcase"
+
+ lefthand_file = 'modular_skyrat/modules/modular_weapons/icons/mob/inhands/cases_lefthand.dmi'
+ righthand_file = 'modular_skyrat/modules/modular_weapons/icons/mob/inhands/cases_righthand.dmi'
+ inhand_icon_state = "yellowcase"
+
+// Empty version of the case
+
+/obj/item/storage/toolbox/guncase/skyrat/carwo_large_case/empty
+
+/obj/item/storage/toolbox/guncase/skyrat/carwo_large_case/empty/PopulateContents()
+ return
+
+// Sindano in a box, how innovative!
+
+/obj/item/storage/toolbox/guncase/skyrat/carwo_large_case/sindano
+ name = "\improper Carwo 'Sindano' gunset"
+
+ weapon_to_spawn = /obj/item/gun/ballistic/automatic/sol_smg/no_mag
+ extra_to_spawn = /obj/item/ammo_box/magazine/c35sol_pistol/stendo
+
+/obj/item/storage/toolbox/guncase/skyrat/carwo_large_case/sindano/PopulateContents()
+ new weapon_to_spawn (src)
+
+ generate_items_inside(list(
+ /obj/item/ammo_box/c35sol/incapacitator = 1,
+ /obj/item/ammo_box/c35sol = 1,
+ /obj/item/ammo_box/magazine/c35sol_pistol/stendo/starts_empty = 1,
+ /obj/item/ammo_box/magazine/c35sol_pistol/starts_empty = 2,
+ ), src)
+
+/obj/item/storage/toolbox/guncase/skyrat/carwo_large_case/sindano/evil
+ weapon_to_spawn = /obj/item/gun/ballistic/automatic/sol_smg/evil/no_mag
+
+// Boxed grenade launcher, grenades sold seperately on this one
+
+/obj/item/storage/toolbox/guncase/skyrat/carwo_large_case/kiboko_magless
+ name = "\improper Carwo 'Kiboko' gunset"
+
+ weapon_to_spawn = /obj/item/gun/ballistic/automatic/sol_grenade_launcher/no_mag
+ extra_to_spawn = /obj/item/ammo_box/magazine/c980_grenade/starts_empty
+
+
+/obj/structure/closet/secure_closet/armory_kiboko
+ name = "heavy equipment locker"
+ req_access = list(ACCESS_ARMORY)
+ icon_state = "shotguncase"
+
+/obj/structure/closet/secure_closet/armory_kiboko/PopulateContents()
+ . = ..()
+
+ generate_items_inside(list(
+ /obj/item/storage/toolbox/guncase/skyrat/carwo_large_case/kiboko_magless = 1,
+ /obj/item/ammo_box/c980grenade = 2,
+ /obj/item/ammo_box/c980grenade/smoke = 1,
+ /obj/item/ammo_box/c980grenade/riot = 1,
+ ), src)
+
+/obj/structure/closet/secure_closet/armory_kiboko_but_evil
+ name = "heavy equipment locker"
+ icon = 'modular_skyrat/master_files/icons/obj/closet.dmi'
+ icon_door = "riot"
+ icon_state = "riot"
+ req_access = list(ACCESS_SYNDICATE)
+ anchored = 1
+
+/obj/structure/closet/secure_closet/armory_kiboko_but_evil/PopulateContents()
+ . = ..()
+
+ generate_items_inside(list(
+ /obj/item/gun/ballistic/automatic/sol_grenade_launcher/evil/no_mag = 1,
+ /obj/item/ammo_box/magazine/c980_grenade/drum/starts_empty = 2,
+ /obj/item/ammo_box/c980grenade/shrapnel = 1,
+ /obj/item/ammo_box/c980grenade/shrapnel/phosphor = 1,
+ /obj/item/ammo_box/c980grenade/smoke = 1,
+ /obj/item/ammo_box/c980grenade/riot = 1,
+ ), src)
diff --git a/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/magazines.dm b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/magazines.dm
new file mode 100644
index 00000000000..0734cb89258
--- /dev/null
+++ b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/magazines.dm
@@ -0,0 +1,113 @@
+// .35 Sol pistol magazines
+
+/obj/item/ammo_box/magazine/c35sol_pistol
+ name = "\improper Sol pistol magazine"
+ desc = "A standard size magazine for SolFed pistols, holds twelve rounds."
+
+ icon = 'modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/ammo.dmi'
+ icon_state = "pistol_35_standard"
+
+ multiple_sprites = AMMO_BOX_FULL_EMPTY
+
+ w_class = WEIGHT_CLASS_TINY
+
+ ammo_type = /obj/item/ammo_casing/c35sol
+ caliber = CALIBER_SOL35SHORT
+ max_ammo = 12
+
+/obj/item/ammo_box/magazine/c35sol_pistol/starts_empty
+ start_empty = TRUE
+
+/obj/item/ammo_box/magazine/c35sol_pistol/stendo
+ name = "\improper Sol extended pistol magazine"
+ desc = "An extended magazine for SolFed pistols, holds twenty-four rounds."
+
+ icon_state = "pistol_35_stended"
+
+ w_class = WEIGHT_CLASS_NORMAL
+
+ max_ammo = 24
+
+/obj/item/ammo_box/magazine/c35sol_pistol/stendo/starts_empty
+ start_empty = TRUE
+
+// .40 Sol rifle magazines
+
+/obj/item/ammo_box/magazine/c40sol_rifle
+ name = "\improper Sol rifle short magazine"
+ desc = "A shortened magazine for SolFed rifles, holds fifteen rounds."
+
+ icon = 'modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/ammo.dmi'
+ icon_state = "rifle_short"
+
+ multiple_sprites = AMMO_BOX_FULL_EMPTY
+
+ w_class = WEIGHT_CLASS_TINY
+
+ ammo_type = /obj/item/ammo_casing/c40sol
+ caliber = CALIBER_SOL40LONG
+ max_ammo = 15
+
+/obj/item/ammo_box/magazine/c40sol_rifle/starts_empty
+
+ start_empty = TRUE
+
+/obj/item/ammo_box/magazine/c40sol_rifle/standard
+ name = "\improper Sol rifle magazine"
+ desc = "A standard size magazine for SolFed rifles, holds thirty rounds."
+
+ icon_state = "rifle_standard"
+
+ w_class = WEIGHT_CLASS_SMALL
+
+ max_ammo = 30
+
+/obj/item/ammo_box/magazine/c40sol_rifle/standard/starts_empty
+ start_empty = TRUE
+
+
+/obj/item/ammo_box/magazine/c40sol_rifle/drum
+ name = "\improper Sol rifle drum magazine"
+ desc = "A massive drum magazine for SolFed rifles, holds sixty rounds."
+
+ icon_state = "rifle_drum"
+
+ w_class = WEIGHT_CLASS_BULKY
+
+ max_ammo = 60
+
+/obj/item/ammo_box/magazine/c40sol_rifle/drum/starts_empty
+ start_empty = TRUE
+
+// .980 grenade magazines
+
+/obj/item/ammo_box/magazine/c980_grenade
+ name = "\improper Kiboko grenade box"
+ desc = "A standard size box for .980 grenades, holds four shells."
+
+ icon = 'modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/ammo.dmi'
+ icon_state = "granata_standard"
+
+ multiple_sprites = AMMO_BOX_FULL_EMPTY
+
+ w_class = WEIGHT_CLASS_SMALL
+
+ ammo_type = /obj/item/ammo_casing/c980grenade
+ caliber = CALIBER_980TYDHOUER
+ max_ammo = 4
+
+/obj/item/ammo_box/magazine/c980_grenade/starts_empty
+ start_empty = TRUE
+
+/obj/item/ammo_box/magazine/c980_grenade/drum
+ name = "\improper Kiboko grenade drum"
+ desc = "A drum for .980 grenades, holds six shells."
+
+ icon_state = "granata_drum"
+
+ w_class = WEIGHT_CLASS_NORMAL
+
+ max_ammo = 6
+
+/obj/item/ammo_box/magazine/c980_grenade/drum/starts_empty
+ start_empty = TRUE
diff --git a/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/rifle.dm b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/rifle.dm
new file mode 100644
index 00000000000..5b298fec87c
--- /dev/null
+++ b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/rifle.dm
@@ -0,0 +1,160 @@
+// Base Sol rifle
+
+/obj/item/gun/ballistic/automatic/sol_rifle
+ name = "\improper Carwo 'd'Infanteria' Rifle"
+ desc = "A heavy battle rifle commonly seen in the hands of SolFed military types. Accepts any standard SolFed rifle magazine."
+
+ icon = 'modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/guns48x.dmi'
+ icon_state = "infanterie"
+
+ worn_icon = 'modular_skyrat/modules/modular_weapons/icons/mob/company_and_or_faction_based/carwo_defense_systems/guns_worn.dmi'
+ worn_icon_state = "infanterie"
+
+ lefthand_file = 'modular_skyrat/modules/modular_weapons/icons/mob/company_and_or_faction_based/carwo_defense_systems/guns_lefthand.dmi'
+ righthand_file = 'modular_skyrat/modules/modular_weapons/icons/mob/company_and_or_faction_based/carwo_defense_systems/guns_righthand.dmi'
+ inhand_icon_state = "infanterie"
+
+ SET_BASE_PIXEL(-8, 0)
+
+ special_mags = TRUE
+
+ bolt_type = BOLT_TYPE_LOCKING
+
+ w_class = WEIGHT_CLASS_BULKY
+ weapon_weight = WEAPON_HEAVY
+ slot_flags = ITEM_SLOT_BACK | ITEM_SLOT_OCLOTHING
+
+ accepted_magazine_type = /obj/item/ammo_box/magazine/c40sol_rifle
+ spawn_magazine_type = /obj/item/ammo_box/magazine/c40sol_rifle/standard
+
+ fire_sound = 'modular_skyrat/modules/modular_weapons/sounds/rifle_heavy.ogg'
+ suppressed_sound = 'modular_skyrat/modules/modular_weapons/sounds/suppressed_rifle.ogg'
+ can_suppress = TRUE
+
+ can_bayonet = FALSE
+
+ suppressor_x_offset = 12
+
+ burst_size = 1
+ fire_delay = 0.45 SECONDS
+ actions_types = list()
+
+ spread = 7.5
+ projectile_wound_bonus = -10
+
+/obj/item/gun/ballistic/automatic/sol_rifle/Initialize(mapload)
+ . = ..()
+
+ give_autofire()
+
+/// Separate proc for handling auto fire just because one of these subtypes isn't otomatica
+/obj/item/gun/ballistic/automatic/sol_rifle/proc/give_autofire()
+ AddComponent(/datum/component/automatic_fire, fire_delay)
+
+/obj/item/gun/ballistic/automatic/sol_rifle/give_manufacturer_examine()
+ AddElement(/datum/element/manufacturer_examine, COMPANY_CARWO)
+
+/obj/item/gun/ballistic/automatic/sol_rifle/examine_more(mob/user)
+ . = ..()
+
+ . += "The d'Infanterie rifles are, as the name may imply, built by Carwo for \
+ use by SolFed's various infantry branches. Following the rather reasonable \
+ military requirements of using the same few cartridges and magazines, \
+ the lifespans of logistics coordinators and quartermasters everywhere \
+ were lengthened by several years. While typically only for military sale \
+ in the past, the recent collapse of certain unnamed weapons manufacturers \
+ has caused Carwo to open many of its military weapons to civilian sale, \
+ which includes this one."
+
+ return .
+
+/obj/item/gun/ballistic/automatic/sol_rifle/no_mag
+ spawnwithmagazine = FALSE
+
+// Sol marksman rifle
+
+/obj/item/gun/ballistic/automatic/sol_rifle/marksman
+ name = "\improper Carwo 'd'Elite' Marksman Rifle"
+ desc = "A heavy marksman rifle commonly seen in the hands of SolFed military types. Accepts any standard SolFed rifle magazine."
+
+ icon_state = "elite"
+ worn_icon_state = "elite"
+ inhand_icon_state = "elite"
+
+ spawn_magazine_type = /obj/item/ammo_box/magazine/c40sol_rifle
+
+ fire_delay = 0.75 SECONDS
+
+ spread = 0
+ projectile_damage_multiplier = 1.2
+ projectile_wound_bonus = 10
+
+/obj/item/gun/ballistic/automatic/sol_rifle/marksman/Initialize(mapload)
+ . = ..()
+
+ AddComponent(/datum/component/scope, range_modifier = 2)
+
+/obj/item/gun/ballistic/automatic/sol_rifle/marksman/give_autofire()
+ return
+
+/obj/item/gun/ballistic/automatic/sol_rifle/marksman/examine_more(mob/user)
+ . = ..()
+
+ . += "This particlar variant, often called 'd'Elite', is a marksman rifle. \
+ Automatic fire was forsaken for a semi-automatic setup, a more fitting \
+ stock, and more often than not a scope. Typically also seen with smaller \
+ magazines for convenience for the shooter, but as with any other Sol \
+ rifle, all standard magazine types will work."
+
+ return .
+
+/obj/item/gun/ballistic/automatic/sol_rifle/marksman/no_mag
+ spawnwithmagazine = FALSE
+
+// Machinegun based on the base Sol rifle
+
+/obj/item/gun/ballistic/automatic/sol_rifle/machinegun
+ name = "\improper Carwo 'd'Outomaties' Machinegun"
+ desc = "A hefty machinegun commonly seen in the hands of SolFed military types. Accepts any standard SolFed rifle magazine."
+
+ icon_state = "outomaties"
+ worn_icon_state = "outomaties"
+ inhand_icon_state = "outomaties"
+
+ bolt_type = BOLT_TYPE_OPEN
+
+ spawn_magazine_type = /obj/item/ammo_box/magazine/c40sol_rifle/drum
+
+ fire_delay = 0.1 SECONDS
+
+ recoil = 1
+ spread = 12.5
+ projectile_wound_bonus = -20
+
+/obj/item/gun/ballistic/automatic/sol_rifle/machinegun/examine_more(mob/user)
+ . = ..()
+
+ . += "The d'Outomaties variant of the rifle, what you are looking at now, \
+ is a modification to turn the weapon into a passable, if sub-optimal \
+ light machinegun. To support the machinegun role, the internals were \
+ converted to make the gun into an open bolt, faster firing machine. These \
+ additions, combined with a battle rifle not meant to be used fully auto \
+ much to begin with, made for a relatively unwieldy weapon. A machinegun, \
+ however, is still a machinegun, no matter how hard it is to keep on target."
+
+ return .
+
+/obj/item/gun/ballistic/automatic/sol_rifle/machinegun/no_mag
+ spawnwithmagazine = FALSE
+
+// Evil version of the rifle (nothing different its just black)
+
+/obj/item/gun/ballistic/automatic/sol_rifle/evil
+ desc = "A heavy battle rifle, this one seems to be painted tacticool black. Accepts any standard SolFed rifle magazine."
+
+ icon_state = "infanterie_evil"
+ worn_icon_state = "infanterie_evil"
+ inhand_icon_state = "infanterie_evil"
+
+/obj/item/gun/ballistic/automatic/sol_rifle/evil/no_mag
+ spawnwithmagazine = FALSE
diff --git a/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/shotgun.dm b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/shotgun.dm
new file mode 100644
index 00000000000..af5f6131d88
--- /dev/null
+++ b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/shotgun.dm
@@ -0,0 +1,62 @@
+// SolFed shotgun (this was gonna be in a proprietary shotgun shell type outside of 12ga at some point, wild right?)
+
+/obj/item/gun/ballistic/shotgun/riot/sol
+ name = "\improper Carwo 'Renoster' Shotgun"
+ desc = "A twelve gauge shotgun with a six shell capacity underneath. Made for and used by SolFed's various military branches."
+
+ icon = 'modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/guns48x.dmi'
+ icon_state = "renoster"
+
+ worn_icon = 'modular_skyrat/modules/modular_weapons/icons/mob/company_and_or_faction_based/carwo_defense_systems/guns_worn.dmi'
+ worn_icon_state = "renoster"
+
+ lefthand_file = 'modular_skyrat/modules/modular_weapons/icons/mob/company_and_or_faction_based/carwo_defense_systems/guns_lefthand.dmi'
+ righthand_file = 'modular_skyrat/modules/modular_weapons/icons/mob/company_and_or_faction_based/carwo_defense_systems/guns_righthand.dmi'
+ inhand_icon_state = "renoster"
+
+ inhand_x_dimension = 32
+ inhand_y_dimension = 32
+
+ SET_BASE_PIXEL(-8, 0)
+
+ fire_sound = 'modular_skyrat/modules/modular_weapons/sounds/shotgun_heavy.ogg'
+ rack_sound = 'modular_skyrat/modules/modular_weapons/sounds/shotgun_rack.ogg'
+ suppressed_sound = 'modular_skyrat/modules/modular_weapons/sounds/suppressed_heavy.ogg'
+ can_suppress = TRUE
+
+ suppressor_x_offset = 9
+
+ w_class = WEIGHT_CLASS_BULKY
+ slot_flags = ITEM_SLOT_BACK | ITEM_SLOT_OCLOTHING
+
+/obj/item/gun/ballistic/shotgun/riot/sol/give_manufacturer_examine()
+ AddElement(/datum/element/manufacturer_examine, COMPANY_CARWO)
+
+/obj/item/gun/ballistic/shotgun/riot/sol/examine_more(mob/user)
+ . = ..()
+
+ . += "The Renoster was designed at its core as a police shotgun. \
+ As consequence, it holds all the qualities a police force would want \
+ in one. Large shell capacity, sturdy frame, while holding enough \
+ capacity for modification to satiate even the most overfunded of \
+ peacekeeper forces. Inevitably, the weapon made its way into civilian \
+ markets alongside its sale to several military branches that also \
+ saw value in having a heavy shotgun."
+
+ return .
+
+/obj/item/gun/ballistic/shotgun/riot/sol/update_appearance(updates)
+ if(sawn_off)
+ suppressor_x_offset = 0
+ SET_BASE_PIXEL(0, 0)
+
+ . = ..()
+
+// Shotgun but EVIL!
+
+/obj/item/gun/ballistic/shotgun/riot/sol/evil
+ desc = "A twleve guage shotgun with an eight shell capacity underneath. This one is painted in a tacticool black."
+
+ icon_state = "renoster_evil"
+ worn_icon_state = "renoster_evil"
+ inhand_icon_state = "renoster_evil"
diff --git a/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/submachinegun.dm b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/submachinegun.dm
new file mode 100644
index 00000000000..61b1ed902fa
--- /dev/null
+++ b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/submachinegun.dm
@@ -0,0 +1,62 @@
+// Base Sol SMG
+
+/obj/item/gun/ballistic/automatic/sol_smg
+ name = "\improper Carwo 'Sindano' Submachinegun"
+ desc = "A small submachinegun commonly seen in the hands of PMCs and other unsavory corpos. Accepts any standard Sol pistol magazine."
+
+ icon = 'modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/guns32x.dmi'
+ icon_state = "sindano"
+
+ inhand_icon_state = "c20r"
+
+ special_mags = TRUE
+
+ bolt_type = BOLT_TYPE_OPEN
+
+ w_class = WEIGHT_CLASS_NORMAL
+ weapon_weight = WEAPON_MEDIUM
+ slot_flags = ITEM_SLOT_OCLOTHING | ITEM_SLOT_BELT
+
+ accepted_magazine_type = /obj/item/ammo_box/magazine/c35sol_pistol
+ spawn_magazine_type = /obj/item/ammo_box/magazine/c35sol_pistol/stendo
+
+ fire_sound = 'modular_skyrat/modules/modular_weapons/sounds/smg_light.ogg'
+ can_suppress = TRUE
+
+ can_bayonet = FALSE
+
+ suppressor_x_offset = 11
+
+ burst_size = 3
+ fire_delay = 0.2 SECONDS
+
+ spread = 7.5
+
+/obj/item/gun/ballistic/automatic/sol_smg/give_manufacturer_examine()
+ AddElement(/datum/element/manufacturer_examine, COMPANY_CARWO)
+
+/obj/item/gun/ballistic/automatic/sol_smg/examine_more(mob/user)
+ . = ..()
+
+ . += "The Sindano submachinegun was originally produced for military contract. \
+ These guns were seen in the hands of anyone from medics, ship techs, logistics officers, \
+ and shuttle pilots often had several just to show off. Due to SolFed's quest to \
+ extend the lifespans of their logistics officers and quartermasters, the weapon \
+ uses the same standard pistol cartridge that most other miltiary weapons of \
+ small caliber use. This results in interchangeable magazines between pistols \
+ and submachineguns, neat!"
+
+ return .
+
+/obj/item/gun/ballistic/automatic/sol_smg/no_mag
+ spawnwithmagazine = FALSE
+
+// Sindano (evil)
+
+/obj/item/gun/ballistic/automatic/sol_smg/evil
+ desc = "A small submachinegun, this one is painted in tacticool black. Accepts any standard Sol pistol magazine."
+
+ icon_state = "sindano_evil"
+
+/obj/item/gun/ballistic/automatic/sol_smg/evil/no_mag
+ spawnwithmagazine = FALSE
diff --git a/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/trappiste_fabriek/advert.dm b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/trappiste_fabriek/advert.dm
new file mode 100644
index 00000000000..f076b0d73b3
--- /dev/null
+++ b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/trappiste_fabriek/advert.dm
@@ -0,0 +1,41 @@
+/obj/structure/sign/poster/official/trappiste_suppressor
+ name = "Keep It Quiet - Ear Protection Unneeded"
+ desc = "This poster depicts, alongside the prominent logo of Trappiste Fabriek, a \
+ diagram of the average suppressor, and how on most* Trappiste weapons \
+ the sound of firing will be low enough to eradicate the need for ear protection. \
+ How safety minded, they even have a non-liability statement too."
+ icon = 'modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/trappiste_fabriek/propaganda.dmi'
+ icon_state = "keep_it_quiet"
+
+/obj/structure/sign/poster/official/trappiste_suppressor/examine_more(mob/user)
+ . = ..()
+
+ . += "It was hard to notice before, but now that you really look at it... \
+ This thing is completely covered in micro scale text telling you in just about \
+ every human language and then some that Trappiste isn't liable for ear damage \
+ caused by their weapons, suppressed or not."
+
+ return .
+
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/sign/poster/official/trappiste_suppressor, 32)
+
+/obj/structure/sign/poster/official/trappiste_ammunition
+ name = "Know Your Ammuniton Colors"
+ desc = "This poster depicts, alongside the prominent logo of Trappiste Fabriek, \
+ a variety of colors that one may find on .585 Trappiste rounds. \
+ A plain white case usually means lethal, while a blue stripe is less-lethal \
+ and a purple stripe is more lethal. How informative."
+ icon = 'modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/trappiste_fabriek/propaganda.dmi'
+ icon_state = "know_the_difference"
+
+/obj/structure/sign/poster/official/trappiste_ammunition/examine_more(mob/user)
+ . = ..()
+
+ . += "Small text details that this information may also be transferrable \
+ to other types of SolFed ammunition, but that you should check the box \
+ the bullets come in just to be sure. Trappiste is, of course,\
+ not liable for excess harm caused by misreading color identification systems."
+
+ return .
+
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/sign/poster/official/trappiste_ammunition, 32)
diff --git a/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/trappiste_fabriek/ammo.dm b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/trappiste_fabriek/ammo.dm
new file mode 100644
index 00000000000..498f55a5627
--- /dev/null
+++ b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/trappiste_fabriek/ammo.dm
@@ -0,0 +1,91 @@
+// .585 Trappiste
+// High caliber round used in large pistols and revolvers
+
+/obj/item/ammo_casing/c585trappiste
+ name = ".585 Trappiste lethal bullet casing"
+ desc = "A white polymer cased high caliber round commonly used in handguns."
+
+ icon = 'modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/trappiste_fabriek/ammo.dmi'
+ icon_state = "585trappiste"
+
+ caliber = CALIBER_585TRAPPISTE
+ projectile_type = /obj/projectile/bullet/c585trappiste
+
+/obj/projectile/bullet/c585trappiste
+ name = ".585 Trappiste bullet"
+ damage = 45
+ wound_bonus = 0 // Normal bullets are 20
+
+/obj/item/ammo_box/c585trappiste
+ name = "ammo box (.585 Trappiste lethal)"
+ desc = "A box of .585 Trappiste pistol rounds, holds twelve cartridges."
+
+ icon = 'modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/trappiste_fabriek/ammo.dmi'
+ icon_state = "585box"
+
+ multiple_sprites = AMMO_BOX_FULL_EMPTY
+
+ w_class = WEIGHT_CLASS_NORMAL
+
+ caliber = CALIBER_585TRAPPISTE
+ ammo_type = /obj/item/ammo_casing/c585trappiste
+ max_ammo = 12
+
+// .585 Trappiste equivalent to a rubber bullet
+
+/obj/item/ammo_casing/c585trappiste/incapacitator
+ name = ".585 Trappiste flathead bullet casing"
+ desc = "A white polymer cased high caliber round with a relatively soft, flat tip. Designed to flatten against targets and usually not penetrate on impact."
+
+ icon_state = "585trappiste_disabler"
+
+ projectile_type = /obj/projectile/bullet/c585trappiste/incapacitator
+ harmful = FALSE
+
+/obj/projectile/bullet/c585trappiste/incapacitator
+ name = ".585 Trappiste flathead bullet"
+ damage = 20
+ stamina = 40
+ wound_bonus = 10
+
+ weak_against_armour = TRUE
+
+ shrapnel_type = null
+ sharpness = NONE
+ embedding = null
+
+/obj/item/ammo_box/c585trappiste/incapacitator
+ name = "ammo box (.585 Trappiste flathead)"
+ desc = "A box of .585 Trappiste pistol rounds, holds twelve cartridges. The blue stripe indicates that it should hold less lethal rounds."
+
+ icon_state = "585box_disabler"
+
+ ammo_type = /obj/item/ammo_casing/c585trappiste/incapacitator
+
+// .585 hollowpoint, made to cause nasty wounds
+
+/obj/item/ammo_casing/c585trappiste/hollowpoint
+ name = ".585 Trappiste hollowhead bullet casing"
+ desc = "A white polymer cased high caliber round with a hollowed tip. Designed to cause as much damage on impact to fleshy targets as possible."
+
+ icon_state = "585trappiste_shrapnel"
+ projectile_type = /obj/projectile/bullet/c585trappiste/hollowpoint
+
+ advanced_print_req = TRUE
+
+/obj/projectile/bullet/c585trappiste/hollowpoint
+ name = ".585 Trappiste hollowhead bullet"
+ damage = 35
+
+ weak_against_armour = TRUE
+
+ wound_bonus = 30
+ bare_wound_bonus = 40
+
+/obj/item/ammo_box/c585trappiste/hollowpoint
+ name = "ammo box (.585 Trappiste hollowhead)"
+ desc = "A box of .585 Trappiste pistol rounds, holds twelve cartridges. The purple stripe indicates that it should hold hollowpoint-like rounds."
+
+ icon_state = "585box_shrapnel"
+
+ ammo_type = /obj/item/ammo_casing/c585trappiste/hollowpoint
diff --git a/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/trappiste_fabriek/gunsets.dm b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/trappiste_fabriek/gunsets.dm
new file mode 100644
index 00000000000..41607663a50
--- /dev/null
+++ b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/trappiste_fabriek/gunsets.dm
@@ -0,0 +1,34 @@
+// Base yellow with symbol trappiste case
+
+/obj/item/storage/toolbox/guncase/skyrat/pistol/trappiste_small_case
+ desc = "A thick yellow gun case with foam inserts laid out to fit a weapon, magazines, and gear securely. The five square grid of Trappiste Fabriek is displayed prominently on the top."
+
+ icon = 'modular_skyrat/modules/modular_weapons/icons/obj/gunsets.dmi'
+ icon_state = "case_trappiste"
+
+ lefthand_file = 'modular_skyrat/modules/modular_weapons/icons/mob/inhands/cases_lefthand.dmi'
+ righthand_file = 'modular_skyrat/modules/modular_weapons/icons/mob/inhands/cases_righthand.dmi'
+ inhand_icon_state = "yellowcase"
+
+// Empty version of the case
+
+/obj/item/storage/toolbox/guncase/skyrat/pistol/trappiste_small_case/empty
+
+/obj/item/storage/toolbox/guncase/skyrat/pistol/trappiste_small_case/empty/PopulateContents()
+ return
+
+// Gunset for the Wespe pistol
+
+/obj/item/storage/toolbox/guncase/skyrat/pistol/trappiste_small_case/wespe
+ name = "Trappiste 'Wespe' gunset"
+
+ weapon_to_spawn = /obj/item/gun/ballistic/automatic/pistol/sol/no_mag
+ extra_to_spawn = /obj/item/ammo_box/magazine/c35sol_pistol
+
+// Gunset for the Skild heavy pistol
+
+/obj/item/storage/toolbox/guncase/skyrat/pistol/trappiste_small_case/skild
+ name = "Trappiste 'Skild' gunset"
+
+ weapon_to_spawn = /obj/item/gun/ballistic/automatic/pistol/trappiste/no_mag
+ extra_to_spawn = /obj/item/ammo_box/magazine/c585trappiste_pistol
diff --git a/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/trappiste_fabriek/magazines.dm b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/trappiste_fabriek/magazines.dm
new file mode 100644
index 00000000000..77506ccd29f
--- /dev/null
+++ b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/trappiste_fabriek/magazines.dm
@@ -0,0 +1,19 @@
+// .585 pistol magazines
+
+/obj/item/ammo_box/magazine/c585trappiste_pistol
+ name = "\improper Trappiste pistol magazine"
+ desc = "A standard size magazine for Trappiste pistols, holds six rounds."
+
+ icon = 'modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/trappiste_fabriek/ammo.dmi'
+ icon_state = "pistol_585_standard"
+
+ multiple_sprites = AMMO_BOX_FULL_EMPTY
+
+ w_class = WEIGHT_CLASS_SMALL
+
+ ammo_type = /obj/item/ammo_casing/c585trappiste
+ caliber = CALIBER_585TRAPPISTE
+ max_ammo = 6
+
+/obj/item/ammo_box/magazine/c585trappiste_pistol/spawns_empty
+ start_empty = TRUE
diff --git a/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/trappiste_fabriek/pistol.dm b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/trappiste_fabriek/pistol.dm
new file mode 100644
index 00000000000..1ae391325d0
--- /dev/null
+++ b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/trappiste_fabriek/pistol.dm
@@ -0,0 +1,100 @@
+// .35 Sol pistol
+
+/obj/item/gun/ballistic/automatic/pistol/sol
+ name = "\improper Trappiste 'Wespe' Pistol"
+ desc = "The standard issue service pistol of SolFed's various military branches. Comes with attached light."
+
+ icon = 'modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/trappiste_fabriek/guns32x.dmi'
+ icon_state = "wespe"
+
+ fire_sound = 'modular_skyrat/modules/modular_weapons/sounds/pistol_light.ogg'
+
+ w_class = WEIGHT_CLASS_NORMAL
+
+ accepted_magazine_type = /obj/item/ammo_box/magazine/c35sol_pistol
+ special_mags = TRUE
+
+ suppressor_x_offset = 7
+ suppressor_y_offset = 0
+
+ fire_delay = 0.3 SECONDS
+
+/obj/item/gun/ballistic/automatic/pistol/sol/give_manufacturer_examine()
+ AddElement(/datum/element/manufacturer_examine, COMPANY_TRAPPISTE)
+
+/obj/item/gun/ballistic/automatic/pistol/sol/add_seclight_point()
+ AddComponent(/datum/component/seclite_attachable, \
+ starting_light = new /obj/item/flashlight/seclite(src), \
+ is_light_removable = FALSE, \
+ )
+
+/obj/item/gun/ballistic/automatic/pistol/sol/examine_more(mob/user)
+ . = ..()
+
+ . += "The Wespe is a pistol that was made entirely for military use. \
+ Required to use a standard round, standard magazines, and be able \
+ to function in all of the environments that SolFed operated in \
+ commonly. These qualities just so happened to make the weapon \
+ popular in frontier space and is likely why you are looking at \
+ one now."
+
+ return .
+
+/obj/item/gun/ballistic/automatic/pistol/sol/no_mag
+ spawnwithmagazine = FALSE
+
+// Sol pistol evil gun
+
+/obj/item/gun/ballistic/automatic/pistol/sol/evil
+ desc = "The standard issue service pistol of SolFed's various military branches. Comes with attached light. This one is painted tacticool black."
+
+ icon_state = "wespe_evil"
+
+/obj/item/gun/ballistic/automatic/pistol/sol/evil/no_mag
+ spawnwithmagazine = FALSE
+
+// Trappiste high caliber pistol in .585
+
+/obj/item/gun/ballistic/automatic/pistol/trappiste
+ name = "\improper Trappiste 'Skild' Pistol"
+ desc = "A somewhat rare to see Trappiste pistol firing the high caliber .585 developed by the same company. Sees rare use mainly due to its tendency to cause severe wrist discomfort."
+
+ icon = 'modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/trappiste_fabriek/guns32x.dmi'
+ icon_state = "skild"
+
+ fire_sound = 'modular_skyrat/modules/modular_weapons/sounds/pistol_heavy.ogg'
+ suppressed_sound = 'modular_skyrat/modules/modular_weapons/sounds/suppressed_heavy.ogg'
+
+ w_class = WEIGHT_CLASS_NORMAL
+
+ accepted_magazine_type = /obj/item/ammo_box/magazine/c585trappiste_pistol
+
+ suppressor_x_offset = 8
+ suppressor_y_offset = 0
+
+ fire_delay = 1 SECONDS
+
+ recoil = 3
+
+/obj/item/gun/ballistic/automatic/pistol/trappiste/give_manufacturer_examine()
+ AddElement(/datum/element/manufacturer_examine, COMPANY_TRAPPISTE)
+
+/obj/item/gun/ballistic/automatic/pistol/trappiste/examine_more(mob/user)
+ . = ..()
+
+ . += "The Skild only exists due to a widely known event that SolFed's military \
+ would prefer wasn't anywhere near as popular. A general, name unknown as of now, \
+ was recorded complaining about the lack of capability the Wespe provided to the \
+ military, alongside several statements comparing the Wespe's lack of masculinity \
+ to the, quote, 'unique lack of testosterone those NRI mongrels field'. While the \
+ identities of both the general and people responsible for the leaking of the recording \
+ are still classified, many high ranking SolFed military staff suspiciously have stopped \
+ appearing in public, unlike the Skild. A lot of several thousand pistols, the first \
+ of the weapons to ever exist, were not so silently shipped to SolFed's Plutonian \
+ shipping hub from TRAPPIST. SolFed military command refuses to answer any \
+ further questions about the incident to this day."
+
+ return .
+
+/obj/item/gun/ballistic/automatic/pistol/trappiste/no_mag
+ spawnwithmagazine = FALSE
diff --git a/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/trappiste_fabriek/revolver.dm b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/trappiste_fabriek/revolver.dm
new file mode 100644
index 00000000000..22cbb471449
--- /dev/null
+++ b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/trappiste_fabriek/revolver.dm
@@ -0,0 +1,81 @@
+// .35 Sol mini revolver
+
+/obj/item/gun/ballistic/revolver/sol
+ name = "\improper Trappiste 'Eland' Revolver"
+ desc = "A small revolver with a comically short barrel and cylinder space for eight .35 Sol Short rounds."
+
+ icon = 'modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/trappiste_fabriek/guns32x.dmi'
+ icon_state = "eland"
+
+ accepted_magazine_type = /obj/item/ammo_box/magazine/internal/cylinder/c35sol
+
+ suppressor_x_offset = 3
+
+ w_class = WEIGHT_CLASS_SMALL
+
+ can_suppress = TRUE
+
+/obj/item/gun/ballistic/revolver/sol/give_manufacturer_examine()
+ AddElement(/datum/element/manufacturer_examine, COMPANY_TRAPPISTE)
+
+/obj/item/gun/ballistic/revolver/sol/examine_more(mob/user)
+ . = ..()
+
+ . += "The Eland is one of the few Trappiste weapons not made for military contract. \
+ Instead, the Eland started life as a police weapon, offered as a gun to finally \
+ outmatch all others in the cheap police weapons market. Unfortunately, this \
+ coincided with nearly every SolFed police force realising they are actually \
+ comically overfunded. With military weapons bought for police forces taking \
+ over the market, the Eland instead found home in the civilian personal defense \
+ market. That is likely the reason you are looking at this one now."
+
+ return .
+
+/obj/item/ammo_box/magazine/internal/cylinder/c35sol
+ ammo_type = /obj/item/ammo_casing/c35sol
+ caliber = CALIBER_SOL35SHORT
+ max_ammo = 8
+
+// .585 super revolver
+
+/obj/item/gun/ballistic/revolver/takbok
+ name = "\improper Trappiste 'Takbok' Revolver"
+ desc = "A hefty revolver with an equally large cylinder capable of holding five .585 Trappiste rounds."
+
+ icon = 'modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/trappiste_fabriek/guns32x.dmi'
+ icon_state = "takbok"
+
+ fire_sound = 'modular_skyrat/modules/modular_weapons/sounds/revolver_heavy.ogg'
+ suppressed_sound = 'modular_skyrat/modules/modular_weapons/sounds/suppressed_heavy.ogg'
+
+ accepted_magazine_type = /obj/item/ammo_box/magazine/internal/cylinder/c585trappiste
+
+ suppressor_x_offset = 5
+
+ can_suppress = TRUE
+
+ fire_delay = 1 SECONDS
+ recoil = 3
+
+/obj/item/gun/ballistic/revolver/takbok/give_manufacturer_examine()
+ AddElement(/datum/element/manufacturer_examine, COMPANY_TRAPPISTE)
+
+/obj/item/gun/ballistic/revolver/takbok/examine_more(mob/user)
+ . = ..()
+
+ . += "The Takbok is a unique design for Trappiste for the sole reason that it \
+ was made at first to be a one-off. Founder of partner company Carwo Defense, \
+ Darmaan Khaali Carwo herself, requested a sporting revolver from Trappiste. \
+ What was delivered wasn't a target revolver, it was a target crusher. The \
+ weapon became popular as Carwo crushed many shooting competitions using \
+ the Takbok, with the design going on several production runs up until \
+ 2523 when the popularity of the gun fell off. Due to the number of revolvers \
+ made, they are still easy enough to find if you look despite production \
+ having already ceased many years ago."
+
+ return .
+
+/obj/item/ammo_box/magazine/internal/cylinder/c585trappiste
+ ammo_type = /obj/item/ammo_casing/c585trappiste
+ caliber = CALIBER_585TRAPPISTE
+ max_ammo = 5
diff --git a/modular_skyrat/modules/modular_weapons/code/energy.dm b/modular_skyrat/modules/modular_weapons/code/energy.dm
deleted file mode 100644
index 550af2c130e..00000000000
--- a/modular_skyrat/modules/modular_weapons/code/energy.dm
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
-* BOLT RESPONDER
-* A mini disabler
-* 12 shot capacity VS normal disabler's 20.
-*/
-
-
-/obj/item/gun/energy/disabler/bolt_disabler
- name = "Bolt Responder"
- desc = "A pocket-sized non-lethal energy gun with low ammo capacity."
- icon = 'modular_skyrat/modules/modular_weapons/icons/obj/guns/projectile.dmi'
- icon_state = "cfa-disabler"
- righthand_file = 'modular_skyrat/modules/aesthetics/guns/icons/guns_righthand.dmi'
- lefthand_file = 'modular_skyrat/modules/aesthetics/guns/icons/guns_lefthand.dmi'
- ammo_type = list(/obj/item/ammo_casing/energy/disabler)
- ammo_x_offset = 2
- w_class = WEIGHT_CLASS_SMALL
- cell_type = /obj/item/stock_parts/cell/mini_egun
- ammo_x_offset = 2
- charge_sections = 3
-
-/obj/item/gun/energy/disabler/give_manufacturer_examine()
- AddElement(/datum/element/manufacturer_examine, COMPANY_BOLT)
-
-/obj/item/gun/energy/disabler/bolt_disabler/give_gun_safeties()
- return
-
-/obj/item/gun/energy/disabler/bolt_disabler/add_seclight_point()
- return
-/*
-* CFA PHALANX
-* Similar to the HoS's laser
-* Fires a bouncing non-lethal, lethal and knockdown projectile.
-*/
-
-/obj/item/gun/energy/e_gun/cfa_phalanx
- name = "\improper Mk.II Phalanx plasma blaster"
- desc = "Fires a disabling and lethal bouncing projectile, as well as a special muscle-seizing projectile that knocks targets down."
- icon = 'modular_skyrat/modules/modular_weapons/icons/obj/guns/projectile.dmi'
- icon_state = "phalanx1"
- righthand_file = 'modular_skyrat/modules/aesthetics/guns/icons/guns_righthand.dmi'
- lefthand_file = 'modular_skyrat/modules/aesthetics/guns/icons/guns_lefthand.dmi'
- w_class = WEIGHT_CLASS_NORMAL
- force = 10
- ammo_type = list(/obj/item/ammo_casing/energy/disabler/bounce, /obj/item/ammo_casing/energy/laser/bounce, /obj/item/ammo_casing/energy/electrode/knockdown)
- ammo_x_offset = 1
- charge_sections = 5
- cell_type = /obj/item/stock_parts/cell/hos_gun
-
-/obj/item/gun/energy/e_gun/cfa_phalanx/give_manufacturer_examine()
- AddElement(/datum/element/manufacturer_examine, COMPANY_CANTALAN)
-
-/obj/item/gun/energy/e_gun/cfa_phalanx/give_gun_safeties()
- return
-
-/*
-* CFA PALADIN
-* Identical to a heavy laser.
-*/
-
-/obj/item/gun/energy/laser/cfa_paladin
- name = "\improper Mk.IV Paladin plasma carbine"
- desc = "Essentially a handheld laser cannon. This is solely for killing, and it's dual-laser system reflects that."
- icon = 'modular_skyrat/modules/modular_weapons/icons/obj/guns/projectile.dmi'
- icon_state = "paladin"
- force = 10
- ammo_type = list(/obj/item/ammo_casing/energy/laser/double)
- charge_sections = 5
-
-/obj/item/gun/energy/laser/cfa_paladin/give_manufacturer_examine()
- AddElement(/datum/element/manufacturer_examine, COMPANY_CANTALAN)
-
-/obj/item/gun/energy/laser/cfa_paladin/give_gun_safeties()
- return
-
-/*
-* BOUNCE DISABLER
-* A disabler that will always ricochet.
-*/
-
-/obj/item/ammo_casing/energy/disabler/bounce
- projectile_type = /obj/projectile/beam/disabler/bounce
- select_name = "disable"
- e_cost = 60
- fire_sound = 'sound/weapons/taser2.ogg'
- harmful = FALSE
-
-/obj/effect/projectile/tracer/disabler/bounce
- name = "disabler"
- icon = 'modular_skyrat/modules/modular_weapons/icons/obj/projectiles.dmi'
- icon_state = "bouncebeam"
-
-/obj/projectile/beam/disabler/bounce
- name = "disabler arc"
- icon = 'modular_skyrat/modules/modular_weapons/icons/obj/projectiles.dmi'
- icon_state = "bouncebeam"
- damage = 30
- damage_type = STAMINA
- armor_flag = ENERGY
- eyeblur = 1
- tracer_type = /obj/effect/projectile/tracer/disabler/bounce
- light_range = 5
- light_power = 0.75
- speed = 1.4
- ricochets_max = 6
- ricochet_incidence_leeway = 170
- ricochet_chance = 130
- ricochet_decay_damage = 0.9
-
-// Allows the projectile to reflect on walls like how bullets ricochet.
-/obj/projectile/beam/disabler/bounce/check_ricochet_flag(atom/A)
- return TRUE
-
-/*
-* BOUNCE LASER
-* A laser that will always ricochet.
-*/
-
-/obj/item/ammo_casing/energy/laser/bounce
- projectile_type = /obj/projectile/beam/laser/bounce
- select_name = "lethal"
- e_cost = 100
-
-/obj/projectile/beam/laser/bounce
- name = "energy arc"
- icon = 'modular_skyrat/modules/modular_weapons/icons/obj/projectiles.dmi'
- icon_state = "bouncebeam_red"
- damage = 20
- damage_type = BURN
- armor_flag = LASER
- light_range = 5
- light_power = 0.75
- speed = 1.4
- ricochets_max = 6
- ricochet_incidence_leeway = 170
- ricochet_chance = 130
- ricochet_decay_damage = 0.9
-
-// Allows the projectile to reflect on walls like how bullets ricochet.
-/obj/projectile/beam/laser/bounce/check_ricochet_flag(atom/A)
- return TRUE
-
-/*
-* KNOCKDOWN BOLT
-* A taser that had the same stamina impact as a disabler, but a five-second knockdown and taser hitter effects.
-*/
-
-/obj/item/ammo_casing/energy/electrode/knockdown
- projectile_type = /obj/projectile/energy/electrode/knockdown
- select_name = "knockdown"
- fire_sound = 'sound/weapons/taser.ogg'
- e_cost = 200
- harmful = FALSE
-
-/obj/projectile/energy/electrode/knockdown
- name = "electrobolt"
- icon = 'modular_skyrat/modules/modular_weapons/icons/obj/projectiles.dmi'
- icon_state = "electro_bolt"
- knockdown = 50
- stamina = 30
- range = 6
-
-/*
-* SINGLE LASER
-* Has an unique sprite
-* Low-powered laser for rapid fire
-* Pea-shooter tier.
-*/
-
-
-/obj/item/ammo_casing/energy/laser/single
- projectile_type = /obj/projectile/beam/laser/single
- e_cost = 50
- select_name = "lethal"
-
-/obj/projectile/beam/laser/single
- name = "laser bolt"
- icon = 'modular_skyrat/modules/modular_weapons/icons/obj/projectiles.dmi'
- icon_state = "single_laser"
- damage = 15
- eyeblur = 1
- light_range = 5
- light_power = 0.75
- speed = 0.5
- armour_penetration = 10
-
-/*
-* DOUBLE LASER
-* Visually, this fires two lasers. In code, it's just one.
-* It's fast and great for turrets.
-*/
-
-/obj/item/ammo_casing/energy/laser/double
- projectile_type = /obj/projectile/beam/laser/double
- e_cost = 100
- select_name = "lethal"
- fire_sound = 'sound/weapons/lasercannonfire.ogg'
-
-/obj/projectile/beam/laser/double
- name = "laser bolt"
- icon = 'modular_skyrat/modules/modular_weapons/icons/obj/projectiles.dmi'
- icon_state = "double_laser"
- damage = 40
- eyeblur = 1
- light_range = 5
- light_power = 0.75
- speed = 0.5
- armour_penetration = 10
-
-/*
-* ENERGY BULLETS
-* Ballistic gunplay but it allows us to target a different part of the armour block.
-* Also allows the benefits of lasers (blobs strains, xenos) over bullets to be used with ballistic gunplay.
-*/
-
-/obj/item/ammo_casing/laser
- name = "type I plasma projectile"
- desc = "A chemical mixture that once triggered, creates a deadly projectile, melting it's own casing in the process."
- icon = 'modular_skyrat/modules/modular_weapons/icons/obj/ammo.dmi'
- icon_state = "plasma_shell"
- worn_icon_state = "shell"
- caliber = CALIBER_LASER
- custom_materials = list(/datum/material/iron=SHEET_MATERIAL_AMOUNT * 2,/datum/material/plasma=HALF_SHEET_MATERIAL_AMOUNT)
- projectile_type = /obj/projectile/beam/laser/single
-
-/obj/item/ammo_casing/laser/double
- name = "type II plasma projectile"
- desc = "A chemical mixture that once triggered, creates a deadly projectile, melting it's own casing in the process."
- icon_state = "plasma_shell2"
- worn_icon_state = "shell"
- custom_materials = list(/datum/material/iron=SHEET_MATERIAL_AMOUNT * 2,/datum/material/plasma=HALF_SHEET_MATERIAL_AMOUNT)
- projectile_type = /obj/projectile/beam/laser/double
-
-/obj/item/ammo_casing/laser/bounce
- name = "type III reflective projectile (lethal)"
- desc = "A chemical mixture that once triggered, creates a deadly bouncing projectile, melting it's own casing in the process."
- icon_state = "bounce_shell"
- worn_icon_state = "shell"
- custom_materials = list(/datum/material/iron=SHEET_MATERIAL_AMOUNT * 2,/datum/material/plasma=HALF_SHEET_MATERIAL_AMOUNT)
- projectile_type = /obj/projectile/beam/laser/bounce
-
-/obj/item/ammo_casing/laser/bounce/disabler
- name = "type III reflective projectile (disabler)"
- desc = "A chemical mixture that once triggered, creates bouncing disabler projectile, melting it's own casing in the process."
- icon_state = "disabler_shell"
- projectile_type = /obj/projectile/beam/disabler/bounce
-
-
diff --git a/modular_skyrat/modules/modular_weapons/code/gunsets.dm b/modular_skyrat/modules/modular_weapons/code/gunsets.dm
new file mode 100644
index 00000000000..7373e0fa729
--- /dev/null
+++ b/modular_skyrat/modules/modular_weapons/code/gunsets.dm
@@ -0,0 +1,70 @@
+/*
+* GUNSET BOXES
+*/
+
+/obj/item/storage/toolbox/guncase/skyrat
+ desc = "A thick gun case with foam inserts laid out to fit a weapon, magazines, and gear securely."
+
+ icon = 'modular_skyrat/modules/modular_weapons/icons/obj/gunsets.dmi'
+ icon_state = "guncase"
+
+ worn_icon = 'modular_skyrat/modules/modular_weapons/icons/mob/worn/cases.dmi'
+ worn_icon_state = "darkcase"
+
+ slot_flags = ITEM_SLOT_BACK
+
+ material_flags = NONE
+
+ /// Is the case visually opened or not
+ var/opened = FALSE
+
+/obj/item/storage/toolbox/guncase/skyrat/Initialize(mapload)
+ . = ..()
+ atom_storage.max_total_storage = 14 // Technically means you could fit multiple large guns in here but its a case you cant backpack anyways so what it do
+ atom_storage.max_slots = 6 // We store some extra items in these so lets make a little extra room
+
+/obj/item/storage/toolbox/guncase/skyrat/update_icon()
+ . = ..()
+ if(opened)
+ icon_state = "[initial(icon_state)]-open"
+ else
+ icon_state = initial(icon_state)
+
+/obj/item/storage/toolbox/guncase/skyrat/AltClick(mob/user)
+ . = ..()
+ opened = !opened
+ update_icon()
+
+/obj/item/storage/toolbox/guncase/skyrat/attack_self(mob/user)
+ . = ..()
+ opened = !opened
+ update_icon()
+
+// Empty guncase
+
+/obj/item/storage/toolbox/guncase/skyrat/empty
+
+/obj/item/storage/toolbox/guncase/skyrat/empty/PopulateContents()
+ return
+
+// Small case for pistols and whatnot
+
+/obj/item/storage/toolbox/guncase/skyrat/pistol
+ name = "small gun case"
+
+ icon_state = "guncase_s"
+
+ slot_flags = NONE
+
+ w_class = WEIGHT_CLASS_NORMAL
+
+/obj/item/storage/toolbox/guncase/skyrat/pistol/Initialize(mapload)
+ . = ..()
+ atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL
+
+// Empty pistol case
+
+/obj/item/storage/toolbox/guncase/skyrat/pistol/empty
+
+/obj/item/storage/toolbox/guncase/skyrat/pistol/empty/PopulateContents()
+ return
diff --git a/modular_skyrat/modules/modular_weapons/code/modular_projectiles.dm b/modular_skyrat/modules/modular_weapons/code/modular_projectiles.dm
index 16a9ba35f7f..4a0625b491f 100644
--- a/modular_skyrat/modules/modular_weapons/code/modular_projectiles.dm
+++ b/modular_skyrat/modules/modular_weapons/code/modular_projectiles.dm
@@ -167,149 +167,3 @@
damage = 8
fire_stacks = 1
wound_bonus = -90
-
-/*
-* 4.2x30mm
-*/
-
-/obj/item/ammo_casing/c42x30mm
- name = "4.2x30mm bullet casing"
- desc = "A 4.2x30mm bullet casing."
- caliber = CALIBER_42X30MM
- projectile_type = /obj/projectile/bullet/c42x30mm
-
-/obj/item/ammo_casing/c42x30mm/ap
- name = "4.2x30mm armor-piercing bullet casing"
- desc = "A 4.2x30mm armor-piercing bullet casing."
- projectile_type = /obj/projectile/bullet/c42x30mm/ap
- custom_materials = AMMO_MATS_AP
- advanced_print_req = TRUE
-
-/obj/item/ammo_casing/c42x30mm/inc
- name = "4.2x30mm incendiary bullet casing"
- desc = "A 4.2x30mm incendiary bullet casing."
- projectile_type = /obj/projectile/bullet/incendiary/c42x30mm
- custom_materials = AMMO_MATS_TEMP
- advanced_print_req = TRUE
-
-/obj/projectile/bullet/c42x30mm
- name = "4.2x30mm bullet"
- damage = 20
- wound_bonus = -5
- bare_wound_bonus = 5
- embed_falloff_tile = -4
-
-/obj/projectile/bullet/c42x30mm/ap
- name = "4.2x30mm armor-piercing bullet"
- damage = 15
- armour_penetration = 40
- embedding = null
-
-/obj/projectile/bullet/incendiary/c42x30mm
- name = "4.2x30mm incendiary bullet"
- damage = 10
- fire_stacks = 1
-
-/obj/projectile/bullet/c42x30mm_rubber
- name = "4.2x30mm rubber bullet"
- damage = 3
- stamina = 17
- ricochets_max = 6
- ricochet_incidence_leeway = 0
- ricochet_chance = 130
- ricochet_decay_damage = 0.7
- shrapnel_type = null
- sharpness = NONE
- embedding = null
- wound_bonus = -50
-
-/obj/item/ammo_casing/c42x30mm/rubber
- name = "4.2x30mm rubber bullet casing"
- desc = "A 4.2x30mm rubber bullet casing."
- projectile_type = /obj/projectile/bullet/c42x30mm_rubber
- harmful = FALSE
-
-/*
-* 12mm Magnum
-*/
-
-/obj/item/ammo_casing/c12mm
- name = "12mm Magnum bullet casing"
- desc = "A 12mm Magnum bullet casing."
- caliber = CALIBER_12MM
- projectile_type = /obj/projectile/bullet/c12mm
-
-/obj/item/ammo_casing/c12mm/ap
- name = "12mm Magnum armor-piercing bullet casing"
- desc = "A 12mm Magnum bullet casing with a titanium core."
- custom_materials = AMMO_MATS_AP
- projectile_type = /obj/projectile/bullet/c12mm/ap
- advanced_print_req = TRUE
-
-/obj/item/ammo_casing/c12mm/hp
- name = "12mm Magnum hollow-point bullet casing"
- desc = "A 12mm Magnum bullet casing with a hollow tip that fragments on contact."
- projectile_type = /obj/projectile/bullet/c12mm/hp
- advanced_print_req = TRUE
-
-/obj/item/ammo_casing/c12mm/fire
- name = "12mm Magnum incendiary bullet casing"
- desc = "A 12mm Magnum bullet casing with a magnesium coated tip meant for setting things on fire."
- custom_materials = AMMO_MATS_TEMP
- projectile_type = /obj/projectile/bullet/incendiary/c12mm
- advanced_print_req = TRUE
-
-/obj/item/ammo_casing/c12mm/rubber
- name = "12mm Magnum rubber bullet casing"
- desc = "A low powder load 12mm Magnum bullet casing with a flat rubber tip. Headshots heavily discouraged."
- projectile_type = /obj/projectile/bullet/c12mm/rubber
- harmful = FALSE
-
-/obj/projectile/bullet/c12mm
- name = "12mm bullet"
- damage = 40
-
-/obj/projectile/bullet/c12mm/ap
- name = "12mm armor-piercing bullet"
- damage = 37
- armour_penetration = 40
-
-/obj/projectile/bullet/c12mm/hp
- name = "12mm hollow-point bullet"
- damage = 60
- weak_against_armour = TRUE
-
-/obj/projectile/bullet/incendiary/c12mm
- name = "12mm incendiary bullet"
- damage = 20
- fire_stacks = 2
-
-/obj/projectile/bullet/c12mm/rubber
- name = "12mm Magnum rubber ball"
- damage = 10
- stamina = 40
- ricochets_max = 6
- ricochet_incidence_leeway = 0
- ricochet_chance = 130
- ricochet_decay_damage = 0.7
- shrapnel_type = null
- sharpness = NONE
- embedding = null
-
-/*
-* 6.8x43mm
-*/
-
-/obj/item/ammo_casing/a68
- name = "6.8mm bullet casing"
- desc = "A 6.8mm bullet casing."
- icon_state = "762-casing"
- caliber = CALIBER_A68
- projectile_type = /obj/projectile/bullet/a68
-
-/obj/projectile/bullet/a68
- name = "6.8 bullet"
- damage = 55
- armour_penetration = 10
- wound_bonus = -45
- wound_falloff_tile = 0
diff --git a/modular_skyrat/modules/sec_haul/code/guns/pepperball_gun.dm b/modular_skyrat/modules/modular_weapons/code/pepperball_gun.dm
similarity index 81%
rename from modular_skyrat/modules/sec_haul/code/guns/pepperball_gun.dm
rename to modular_skyrat/modules/modular_weapons/code/pepperball_gun.dm
index ffca51d4e67..e507cfe1a6a 100644
--- a/modular_skyrat/modules/sec_haul/code/guns/pepperball_gun.dm
+++ b/modular_skyrat/modules/modular_weapons/code/pepperball_gun.dm
@@ -1,7 +1,7 @@
/obj/item/gun/ballistic/automatic/pistol/pepperball
name = "\improper Bolt Pepperball AHG"
desc = "An incredibly mediocre 'firearm' designed to fire soft pepper balls meant to easily subdue targets."
- icon = 'modular_skyrat/modules/sec_haul/icons/guns/pepperball.dmi'
+ icon = 'modular_skyrat/modules/modular_weapons/icons/obj/pepperball/pepperball.dmi'
icon_state = "peppergun"
w_class = WEIGHT_CLASS_NORMAL
accepted_magazine_type = /obj/item/ammo_box/magazine/pepperball
@@ -21,7 +21,7 @@
/obj/item/ammo_box/magazine/pepperball
name = "pistol magazine (pepperball)"
desc = "A gun magazine filled with balls."
- icon = 'modular_skyrat/modules/sec_haul/icons/guns/pepperball.dmi'
+ icon = 'modular_skyrat/modules/modular_weapons/icons/obj/pepperball/pepperball.dmi'
icon_state = "pepperball"
ammo_type = /obj/item/ammo_casing/pepperball
caliber = CALIBER_PEPPERBALL
@@ -37,7 +37,7 @@
/obj/projectile/bullet/pepperball
name = "pepperball orb"
- icon = 'modular_skyrat/modules/sec_haul/icons/guns/projectiles.dmi'
+ icon = 'modular_skyrat/modules/modular_weapons/icons/obj/pepperball/projectiles.dmi'
icon_state = "pepperball"
damage = 0
stamina = 5
@@ -67,8 +67,16 @@
/obj/item/ammo_box/advanced/pepperballs
name = "pepperball ammo box"
- icon = 'modular_skyrat/modules/sec_haul/icons/guns/ammoboxes.dmi'
+ icon = 'modular_skyrat/modules/modular_weapons/icons/obj/pepperball/ammoboxes.dmi'
icon_state = "box10x24"
ammo_type = /obj/item/ammo_casing/pepperball
custom_materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT * 3)
max_ammo = 15
+
+// Gunset for the pepperball pistol
+
+/obj/item/storage/toolbox/guncase/skyrat/pistol/pepperball
+ name = "Pepperball AHG gunset"
+
+ weapon_to_spawn = /obj/item/gun/ballistic/automatic/pistol/pepperball
+ extra_to_spawn = /obj/item/ammo_box/magazine/pepperball
diff --git a/modular_skyrat/modules/modular_weapons/code/pistol.dm b/modular_skyrat/modules/modular_weapons/code/pistol.dm
deleted file mode 100644
index 7333fa60324..00000000000
--- a/modular_skyrat/modules/modular_weapons/code/pistol.dm
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
-* PISTOLS
-*/
-
-/obj/item/gun/ballistic/automatic/pistol/cfa_snub
- name = "CFA Snub"
- desc = "An easily-concealable pistol chambered for 4.2x30mm."
- icon = 'modular_skyrat/modules/modular_weapons/icons/obj/guns/projectile.dmi'
- icon_state = "cfa-snub"
- accepted_magazine_type = /obj/item/ammo_box/magazine/multi_sprite/cfa_snub
- can_suppress = TRUE
- fire_sound_volume = 30
- w_class = WEIGHT_CLASS_SMALL
-
-/obj/item/gun/ballistic/automatic/pistol/cfa_snub/give_manufacturer_examine()
- AddElement(/datum/element/manufacturer_examine, COMPANY_CANTALAN)
-
-/obj/item/gun/ballistic/automatic/pistol/cfa_snub/give_gun_safeties()
- return
-
-/obj/item/gun/ballistic/automatic/pistol/cfa_snub/empty
- spawnwithmagazine = FALSE
-
-/obj/item/gun/ballistic/automatic/pistol/cfa_ruby
- name = "CFA Ruby"
- desc = "A heavy-duty sidearm chambered in 12x27mm."
- icon = 'modular_skyrat/modules/modular_weapons/icons/obj/guns/projectile.dmi'
- icon_state = "cfa_ruby"
- accepted_magazine_type = /obj/item/ammo_box/magazine/multi_sprite/cfa_ruby
- can_suppress = FALSE
- fire_sound_volume = 120
- w_class = WEIGHT_CLASS_NORMAL
-
-/obj/item/gun/ballistic/automatic/pistol/cfa_ruby/give_manufacturer_examine()
- AddElement(/datum/element/manufacturer_examine, COMPANY_CANTALAN)
-
-/obj/item/gun/ballistic/automatic/pistol/cfa_ruby/give_gun_safeties()
- return
-
-/obj/item/gun/ballistic/automatic/pistol/cfa_ruby/empty
- spawnwithmagazine = FALSE
-
-/*
-* AMMO
-*/
-
-/obj/item/ammo_box/magazine/multi_sprite/cfa_snub
- name = "CFA Snub magazine (4.2x30mm)"
- desc = "An advanced magazine with smart type displays. Alt+click to reskin it."
- icon = 'modular_skyrat/modules/modular_weapons/icons/obj/ammo.dmi'
- icon_state = "m42x30"
- possible_types = list(AMMO_TYPE_LETHAL, AMMO_TYPE_AP, AMMO_TYPE_RUBBER, AMMO_TYPE_INCENDIARY)
- ammo_type = /obj/item/ammo_casing/c42x30mm
- caliber = CALIBER_42X30MM
- max_ammo = 16
- multiple_sprites = AMMO_BOX_FULL_EMPTY
-
-/obj/item/ammo_box/magazine/multi_sprite/cfa_snub/ap
- ammo_type = /obj/item/ammo_casing/c42x30mm/ap
- round_type = AMMO_TYPE_AP
-
-/obj/item/ammo_box/magazine/multi_sprite/cfa_snub/rubber
- ammo_type = /obj/item/ammo_casing/c42x30mm/rubber
- round_type = AMMO_TYPE_RUBBER
-
-/obj/item/ammo_box/magazine/multi_sprite/cfa_snub/incendiary
- ammo_type = /obj/item/ammo_casing/c42x30mm/inc
- round_type = AMMO_TYPE_INCENDIARY
-
-/obj/item/ammo_box/magazine/multi_sprite/cfa_snub/empty
- start_empty = TRUE
-
-/obj/item/ammo_box/magazine/multi_sprite/cfa_ruby
- name = "CFA Ruby magazine (12mm Magnum)"
- desc = "An advanced magazine with smart type displays. Alt+click to reskin it."
- icon = 'modular_skyrat/modules/modular_weapons/icons/obj/ammo.dmi'
- icon_state = "m12mm"
- possible_types = list(AMMO_TYPE_LETHAL, AMMO_TYPE_AP, AMMO_TYPE_RUBBER, AMMO_TYPE_HOLLOWPOINT, AMMO_TYPE_INCENDIARY)
- ammo_type = /obj/item/ammo_casing/c12mm
- caliber = CALIBER_12MM
- max_ammo = 8
- multiple_sprites = AMMO_BOX_FULL_EMPTY
-
-/obj/item/ammo_box/magazine/multi_sprite/cfa_ruby/empty
- start_empty = TRUE
-
-/obj/item/ammo_box/magazine/multi_sprite/cfa_ruby/ap
- ammo_type = /obj/item/ammo_casing/c12mm/ap
- round_type = AMMO_TYPE_AP
-
-/obj/item/ammo_box/magazine/multi_sprite/cfa_ruby/rubber
- ammo_type = /obj/item/ammo_casing/c12mm/rubber
- round_type = AMMO_TYPE_RUBBER
-
-/obj/item/ammo_box/magazine/multi_sprite/cfa_ruby/hp
- ammo_type = /obj/item/ammo_casing/c12mm/hp
- round_type = AMMO_TYPE_HOLLOWPOINT
-
-/obj/item/ammo_box/magazine/multi_sprite/cfa_ruby/incendiary
- ammo_type = /obj/item/ammo_casing/c12mm/fire
- round_type = AMMO_TYPE_INCENDIARY
diff --git a/modular_skyrat/modules/modular_weapons/code/revolver.dm b/modular_skyrat/modules/modular_weapons/code/revolver.dm
deleted file mode 100644
index 669f874026f..00000000000
--- a/modular_skyrat/modules/modular_weapons/code/revolver.dm
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
-* REVOLVERS
-* Revolving rifles! We have three versions. An improvised slower firing one, a normal one, and a golden premium one.
-* The gold rifle uses .45, it's only 5 more points of damage unfortunately.
-* Fun hint: A box of .45 bullets functions the same as a speedloader.
-*/
-
-/obj/item/gun/ballistic/revolver/rifle
- name = "\improper .38 revolving rifle"
- desc = "A revolving rifle chambered in .38. "
- icon = 'modular_skyrat/modules/modular_weapons/icons/obj/guns/projectile40x32.dmi'
- icon_state = "revolving-rifle"
- accepted_magazine_type = /obj/item/ammo_box/magazine/internal/cylinder/rev38 //This is just a detective's revolver but it's too big for bags..
- pixel_x = -4 // It's centred on a 40x32 pixel spritesheet.
- w_class = WEIGHT_CLASS_BULKY
- weapon_weight = WEAPON_HEAVY // The entire purpose of this is that it's a bulky rifle instead of a revolver.
- slot_flags = ITEM_SLOT_BELT
- inhand_x_dimension = 64
- inhand_y_dimension = 64
- lefthand_file = 'modular_skyrat/modules/modular_weapons/icons/mob/inhands/weapons/64x_guns_left.dmi'
- righthand_file = 'modular_skyrat/modules/modular_weapons/icons/mob/inhands/weapons/64x_guns_right.dmi'
- inhand_icon_state = "revolving"
-
-/obj/item/gun/ballistic/revolver/rifle/give_manufacturer_examine()
- AddElement(/datum/element/manufacturer_examine, COMPANY_IZHEVSK)
-
-/obj/item/gun/ballistic/revolver/rifle/gold
- name = "\improper .45 revolving rifle"
- desc = "A gold trimmed revolving rifle! It fires .45 bullets."
- icon_state = "revolving-rifle-gold"
- accepted_magazine_type = /obj/item/ammo_box/magazine/internal/cylinder/rev45 //Gold! We're using .45 because TG's 10mm does 40 damage, this does 30.
- w_class = WEIGHT_CLASS_BULKY
- inhand_icon_state = "revolving_gold"
-
-// .45 Cylinder
-
-/obj/item/ammo_box/magazine/internal/cylinder/rev45
- name = "revolver .45 cylinder"
- ammo_type = /obj/item/ammo_casing/c45
- caliber = list(".45")
- max_ammo = 6
diff --git a/modular_skyrat/modules/modular_weapons/code/rifle.dm b/modular_skyrat/modules/modular_weapons/code/rifle.dm
deleted file mode 100644
index eb40dc20330..00000000000
--- a/modular_skyrat/modules/modular_weapons/code/rifle.dm
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
-* CFA RIFLE
-*/
-
-/obj/item/gun/ballistic/automatic/cfa_rifle
- name = "Cantanheim 6.8mm rifle"
- desc = "A simple semi-automatic rifle chambered in 6.8mm. The letters 'XJP' are crossed out in the receiver." //Different 6.8mm than the FTU's propietary pulse ballistics
- icon = 'modular_skyrat/modules/modular_weapons/icons/obj/guns/projectile40x32.dmi'
- icon_state = "cfa_rifle"
- inhand_icon_state = "irifle"
- inhand_x_dimension = 64
- inhand_y_dimension = 64
- lefthand_file = 'modular_skyrat/modules/modular_weapons/icons/mob/inhands/weapons/64x_guns_left.dmi'
- righthand_file = 'modular_skyrat/modules/modular_weapons/icons/mob/inhands/weapons/64x_guns_right.dmi'
- worn_icon_state = "gun"
- accepted_magazine_type = /obj/item/ammo_box/magazine/cm68
- fire_delay = 5
- can_suppress = FALSE
- burst_size = 1
- actions_types = list()
- mag_display = FALSE
- mag_display_ammo = FALSE
- empty_indicator = FALSE
- recoil = 1
- weapon_weight = WEAPON_HEAVY
- pixel_x = -8
- w_class = WEIGHT_CLASS_BULKY
-
-/obj/item/gun/ballistic/automatic/cfa_rifle/Initialize(mapload)
- . = ..()
- AddComponent(/datum/component/scope, range_modifier = 1.5)
-
-/obj/item/gun/ballistic/automatic/cfa_rifle/give_manufacturer_examine()
- AddElement(/datum/element/manufacturer_examine, COMPANY_CANTALAN)
-
-/obj/item/gun/ballistic/automatic/cfa_rifle/give_gun_safeties()
- return
-
-/obj/item/gun/ballistic/automatic/cfa_rifle/empty
- spawnwithmagazine = FALSE
-
-/obj/item/ammo_box/magazine/cm68
- name = "rifle magazine (6.8mm)"
- icon = 'modular_skyrat/modules/modular_weapons/icons/obj/ammo.dmi'
- icon_state = "6.8"
- ammo_type = /obj/item/ammo_casing/a68
- caliber = CALIBER_A68
- max_ammo = 10
- multiple_sprites = 2
-
-/obj/item/ammo_box/magazine/cm68/empty
- start_empty = 1
diff --git a/modular_skyrat/modules/modular_weapons/icons/mob/company_and_or_faction_based/carwo_defense_systems/guns_lefthand.dmi b/modular_skyrat/modules/modular_weapons/icons/mob/company_and_or_faction_based/carwo_defense_systems/guns_lefthand.dmi
new file mode 100644
index 00000000000..b5f9ad7b01f
Binary files /dev/null and b/modular_skyrat/modules/modular_weapons/icons/mob/company_and_or_faction_based/carwo_defense_systems/guns_lefthand.dmi differ
diff --git a/modular_skyrat/modules/modular_weapons/icons/mob/company_and_or_faction_based/carwo_defense_systems/guns_righthand.dmi b/modular_skyrat/modules/modular_weapons/icons/mob/company_and_or_faction_based/carwo_defense_systems/guns_righthand.dmi
new file mode 100644
index 00000000000..ae79418dfff
Binary files /dev/null and b/modular_skyrat/modules/modular_weapons/icons/mob/company_and_or_faction_based/carwo_defense_systems/guns_righthand.dmi differ
diff --git a/modular_skyrat/modules/modular_weapons/icons/mob/company_and_or_faction_based/carwo_defense_systems/guns_worn.dmi b/modular_skyrat/modules/modular_weapons/icons/mob/company_and_or_faction_based/carwo_defense_systems/guns_worn.dmi
new file mode 100644
index 00000000000..d0a854cf303
Binary files /dev/null and b/modular_skyrat/modules/modular_weapons/icons/mob/company_and_or_faction_based/carwo_defense_systems/guns_worn.dmi differ
diff --git a/modular_skyrat/modules/modular_weapons/icons/mob/inhands/cases_lefthand.dmi b/modular_skyrat/modules/modular_weapons/icons/mob/inhands/cases_lefthand.dmi
new file mode 100644
index 00000000000..c9fac088741
Binary files /dev/null and b/modular_skyrat/modules/modular_weapons/icons/mob/inhands/cases_lefthand.dmi differ
diff --git a/modular_skyrat/modules/modular_weapons/icons/mob/inhands/cases_righthand.dmi b/modular_skyrat/modules/modular_weapons/icons/mob/inhands/cases_righthand.dmi
new file mode 100644
index 00000000000..56a5d535c0d
Binary files /dev/null and b/modular_skyrat/modules/modular_weapons/icons/mob/inhands/cases_righthand.dmi differ
diff --git a/modular_skyrat/modules/modular_weapons/icons/mob/inhands/weapons/swords_righthand.dmi b/modular_skyrat/modules/modular_weapons/icons/mob/inhands/weapons/swords_righthand.dmi
index 8cd99c88bce..96e2c1f5d97 100644
Binary files a/modular_skyrat/modules/modular_weapons/icons/mob/inhands/weapons/swords_righthand.dmi and b/modular_skyrat/modules/modular_weapons/icons/mob/inhands/weapons/swords_righthand.dmi differ
diff --git a/modular_skyrat/modules/modular_weapons/icons/mob/worn/cases.dmi b/modular_skyrat/modules/modular_weapons/icons/mob/worn/cases.dmi
new file mode 100644
index 00000000000..f029c295629
Binary files /dev/null and b/modular_skyrat/modules/modular_weapons/icons/mob/worn/cases.dmi differ
diff --git a/modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/ammo.dmi b/modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/ammo.dmi
new file mode 100644
index 00000000000..cb733806546
Binary files /dev/null and b/modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/ammo.dmi differ
diff --git a/modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/guns32x.dmi b/modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/guns32x.dmi
new file mode 100644
index 00000000000..c74c79b6e8c
Binary files /dev/null and b/modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/guns32x.dmi differ
diff --git a/modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/guns48x.dmi b/modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/guns48x.dmi
new file mode 100644
index 00000000000..9131e6d19bb
Binary files /dev/null and b/modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/guns48x.dmi differ
diff --git a/modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/propaganda.dmi b/modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/propaganda.dmi
new file mode 100644
index 00000000000..9438b887628
Binary files /dev/null and b/modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/propaganda.dmi differ
diff --git a/modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/cases.dmi b/modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/cases.dmi
index 238153cd32b..d639b8b4d86 100644
Binary files a/modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/cases.dmi and b/modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/cases.dmi differ
diff --git a/modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/trappiste_fabriek/ammo.dmi b/modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/trappiste_fabriek/ammo.dmi
new file mode 100644
index 00000000000..89e7d90f56d
Binary files /dev/null and b/modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/trappiste_fabriek/ammo.dmi differ
diff --git a/modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/trappiste_fabriek/guns32x.dmi b/modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/trappiste_fabriek/guns32x.dmi
new file mode 100644
index 00000000000..067d79a810b
Binary files /dev/null and b/modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/trappiste_fabriek/guns32x.dmi differ
diff --git a/modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/trappiste_fabriek/propaganda.dmi b/modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/trappiste_fabriek/propaganda.dmi
new file mode 100644
index 00000000000..4ddf2216e7c
Binary files /dev/null and b/modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/trappiste_fabriek/propaganda.dmi differ
diff --git a/modular_skyrat/modules/modular_weapons/icons/obj/guns/projectile.dmi b/modular_skyrat/modules/modular_weapons/icons/obj/guns/projectile.dmi
deleted file mode 100644
index 410bb551109..00000000000
Binary files a/modular_skyrat/modules/modular_weapons/icons/obj/guns/projectile.dmi and /dev/null differ
diff --git a/modular_skyrat/modules/modular_weapons/icons/obj/guns/projectile40x32.dmi b/modular_skyrat/modules/modular_weapons/icons/obj/guns/projectile40x32.dmi
deleted file mode 100644
index 2e3c0b4e5a3..00000000000
Binary files a/modular_skyrat/modules/modular_weapons/icons/obj/guns/projectile40x32.dmi and /dev/null differ
diff --git a/modular_skyrat/modules/modular_weapons/icons/obj/gunsets.dmi b/modular_skyrat/modules/modular_weapons/icons/obj/gunsets.dmi
index bc5b963bd5c..098a8f30481 100644
Binary files a/modular_skyrat/modules/modular_weapons/icons/obj/gunsets.dmi and b/modular_skyrat/modules/modular_weapons/icons/obj/gunsets.dmi differ
diff --git a/modular_skyrat/modules/sec_haul/icons/guns/ammoboxes.dmi b/modular_skyrat/modules/modular_weapons/icons/obj/pepperball/ammoboxes.dmi
similarity index 100%
rename from modular_skyrat/modules/sec_haul/icons/guns/ammoboxes.dmi
rename to modular_skyrat/modules/modular_weapons/icons/obj/pepperball/ammoboxes.dmi
diff --git a/modular_skyrat/modules/sec_haul/icons/guns/pepperball.dmi b/modular_skyrat/modules/modular_weapons/icons/obj/pepperball/pepperball.dmi
similarity index 100%
rename from modular_skyrat/modules/sec_haul/icons/guns/pepperball.dmi
rename to modular_skyrat/modules/modular_weapons/icons/obj/pepperball/pepperball.dmi
diff --git a/modular_skyrat/modules/sec_haul/icons/guns/projectiles.dmi b/modular_skyrat/modules/modular_weapons/icons/obj/pepperball/projectiles.dmi
similarity index 100%
rename from modular_skyrat/modules/sec_haul/icons/guns/projectiles.dmi
rename to modular_skyrat/modules/modular_weapons/icons/obj/pepperball/projectiles.dmi
diff --git a/modular_skyrat/modules/modular_weapons/sounds/grenade_burst.ogg b/modular_skyrat/modules/modular_weapons/sounds/grenade_burst.ogg
new file mode 100644
index 00000000000..d5a8562f45f
Binary files /dev/null and b/modular_skyrat/modules/modular_weapons/sounds/grenade_burst.ogg differ
diff --git a/modular_skyrat/modules/modular_weapons/sounds/grenade_launcher.ogg b/modular_skyrat/modules/modular_weapons/sounds/grenade_launcher.ogg
new file mode 100644
index 00000000000..5ddb76de7d0
Binary files /dev/null and b/modular_skyrat/modules/modular_weapons/sounds/grenade_launcher.ogg differ
diff --git a/modular_skyrat/modules/modular_weapons/sounds/laser_fire.ogg b/modular_skyrat/modules/modular_weapons/sounds/laser_fire.ogg
deleted file mode 100644
index 7b003b8cc8b..00000000000
Binary files a/modular_skyrat/modules/modular_weapons/sounds/laser_fire.ogg and /dev/null differ
diff --git a/modular_skyrat/modules/modular_weapons/sounds/pistol_heavy.ogg b/modular_skyrat/modules/modular_weapons/sounds/pistol_heavy.ogg
new file mode 100644
index 00000000000..34e0412f823
Binary files /dev/null and b/modular_skyrat/modules/modular_weapons/sounds/pistol_heavy.ogg differ
diff --git a/modular_skyrat/modules/modular_weapons/sounds/pistol_light.ogg b/modular_skyrat/modules/modular_weapons/sounds/pistol_light.ogg
new file mode 100644
index 00000000000..cd014f5eda8
Binary files /dev/null and b/modular_skyrat/modules/modular_weapons/sounds/pistol_light.ogg differ
diff --git a/modular_skyrat/modules/modular_weapons/sounds/revolver_heavy.ogg b/modular_skyrat/modules/modular_weapons/sounds/revolver_heavy.ogg
new file mode 100644
index 00000000000..d02d1c750c2
Binary files /dev/null and b/modular_skyrat/modules/modular_weapons/sounds/revolver_heavy.ogg differ
diff --git a/modular_skyrat/modules/modular_weapons/sounds/rifle_heavy.ogg b/modular_skyrat/modules/modular_weapons/sounds/rifle_heavy.ogg
new file mode 100644
index 00000000000..3ad9d60c901
Binary files /dev/null and b/modular_skyrat/modules/modular_weapons/sounds/rifle_heavy.ogg differ
diff --git a/modular_skyrat/modules/modular_weapons/sounds/shotgun_heavy.ogg b/modular_skyrat/modules/modular_weapons/sounds/shotgun_heavy.ogg
new file mode 100644
index 00000000000..2de9e77bf08
Binary files /dev/null and b/modular_skyrat/modules/modular_weapons/sounds/shotgun_heavy.ogg differ
diff --git a/modular_skyrat/modules/modular_weapons/sounds/shotgun_rack.ogg b/modular_skyrat/modules/modular_weapons/sounds/shotgun_rack.ogg
new file mode 100644
index 00000000000..2d68a21e5df
Binary files /dev/null and b/modular_skyrat/modules/modular_weapons/sounds/shotgun_rack.ogg differ
diff --git a/modular_skyrat/modules/modular_weapons/sounds/smg_light.ogg b/modular_skyrat/modules/modular_weapons/sounds/smg_light.ogg
new file mode 100644
index 00000000000..d34cb9440ca
Binary files /dev/null and b/modular_skyrat/modules/modular_weapons/sounds/smg_light.ogg differ
diff --git a/modular_skyrat/modules/modular_weapons/sounds/suppressed_heavy.ogg b/modular_skyrat/modules/modular_weapons/sounds/suppressed_heavy.ogg
new file mode 100644
index 00000000000..b7b721b7666
Binary files /dev/null and b/modular_skyrat/modules/modular_weapons/sounds/suppressed_heavy.ogg differ
diff --git a/modular_skyrat/modules/modular_weapons/sounds/suppressed_rifle.ogg b/modular_skyrat/modules/modular_weapons/sounds/suppressed_rifle.ogg
new file mode 100644
index 00000000000..06aba901c06
Binary files /dev/null and b/modular_skyrat/modules/modular_weapons/sounds/suppressed_rifle.ogg differ
diff --git a/modular_skyrat/modules/mold/code/mold_mobs.dm b/modular_skyrat/modules/mold/code/mold_mobs.dm
index 59b1db55462..c7ba1226435 100644
--- a/modular_skyrat/modules/mold/code/mold_mobs.dm
+++ b/modular_skyrat/modules/mold/code/mold_mobs.dm
@@ -15,6 +15,7 @@
icon = 'modular_skyrat/modules/mold/icons/blob_mobs.dmi'
gold_core_spawnable = NO_SPAWN
faction = list(FACTION_MOLD)
+ basic_mob_flags = DEL_ON_DEATH
/**
* OIL SHAMBLERS
@@ -69,6 +70,17 @@
SSvis_overlays.add_vis_overlay(src, icon, OIL_SHAMBLER_OVERLAY, layer, plane, dir, alpha)
SSvis_overlays.add_vis_overlay(src, icon, OIL_SHAMBLER_OVERLAY, OIL_SHAMBLER_OVERLAY_LAYER, EMISSIVE_PLANE, dir, alpha)
+/mob/living/basic/mold/oil_shambler/melee_attack(atom/target, list/modifiers, ignore_cooldown)
+ . = ..()
+ if(!isliving(target))
+ return
+
+ var/mob/living/ignite_target = target
+ if(prob(ignite_chance))
+ ignite_target.adjust_fire_stacks(additional_fire_stacks)
+
+ ignite_target.ignite_mob()
+
/datum/ai_controller/basic_controller/oil_shambler
blackboard = list(
BB_TARGETTING_DATUM = new /datum/targetting_datum/basic,
@@ -79,7 +91,7 @@
planning_subtrees = list(
/datum/ai_planning_subtree/simple_find_target,
/datum/ai_planning_subtree/attack_obstacle_in_path,
- /datum/ai_planning_subtree/basic_melee_attack_subtree/oil_shambler,
+ /datum/ai_planning_subtree/basic_melee_attack_subtree,
/datum/ai_planning_subtree/random_speech/oil_shambler,
)
@@ -88,23 +100,6 @@
emote_hear = list("bubbles.", "crackles.", "groans.")
emote_see = list("bubbles.")
-/datum/ai_planning_subtree/basic_melee_attack_subtree/oil_shambler
- melee_attack_behavior = /datum/ai_behavior/basic_melee_attack/oil_shambler
-
-/datum/ai_behavior/basic_melee_attack/oil_shambler/perform(seconds_per_tick, datum/ai_controller/controller, target_key, targetting_datum_key, hiding_location_key)
- . = ..()
- var/atom/target = controller.blackboard[target_key]
- var/mob/living/basic/mold/oil_shambler/oil_shambler = controller.pawn
-
- if(!isliving(target))
- return
-
- var/mob/living/ignite_target = target
- if(prob(oil_shambler.ignite_chance))
- ignite_target.adjust_fire_stacks(oil_shambler.additional_fire_stacks)
-
- if(ignite_target.fire_stacks)
- ignite_target.ignite_mob()
/**
* DISEASE MOLD
@@ -139,6 +134,17 @@
/// The disease given on melee attacks
var/datum/disease/given_disease = /datum/disease/cryptococcus
+/mob/living/basic/mold/diseased_rat/melee_attack(atom/target, list/modifiers, ignore_cooldown)
+ . = ..()
+
+ if(!isliving(target))
+ return
+
+ var/mob/living/carbon/disease_target = target
+ if(can_inject(disease_target))
+ to_chat(disease_target, span_danger("[src] manages to penetrate your clothing with its teeth!"))
+ disease_target.ForceContractDisease(new given_disease(), FALSE, TRUE)
+
/datum/ai_controller/basic_controller/diseased_rat
blackboard = list(
BB_TARGETTING_DATUM = new /datum/targetting_datum/basic,
@@ -149,7 +155,7 @@
planning_subtrees = list(
/datum/ai_planning_subtree/simple_find_target,
/datum/ai_planning_subtree/attack_obstacle_in_path,
- /datum/ai_planning_subtree/basic_melee_attack_subtree/diseased_rat,
+ /datum/ai_planning_subtree/basic_melee_attack_subtree,
/datum/ai_planning_subtree/random_speech/diseased_rat,
)
@@ -158,21 +164,6 @@
emote_hear = list("squeaks.", "gnashes.", "hisses.")
emote_see = list("drools.")
-/datum/ai_planning_subtree/basic_melee_attack_subtree/diseased_rat
- melee_attack_behavior = /datum/ai_behavior/basic_melee_attack/diseased_rat
-
-/datum/ai_behavior/basic_melee_attack/diseased_rat/perform(seconds_per_tick, datum/ai_controller/controller, target_key, targetting_datum_key, hiding_location_key)
- . = ..()
- var/atom/target = controller.blackboard[target_key]
- var/mob/living/basic/mold/diseased_rat/diseased_rat = controller.pawn
-
- if(!isliving(target))
- return
-
- var/mob/living/carbon/disease_target = target
- if(diseased_rat.can_inject(disease_target))
- to_chat(disease_target, span_danger("[diseased_rat] manages to penetrate your clothing with its teeth!"))
- disease_target.ForceContractDisease(new diseased_rat.given_disease(), FALSE, TRUE)
/**
* ELECTRIC MOLD
@@ -202,6 +193,15 @@
pass_flags = PASSTABLE
+ /// What the mob injects per bite
+ var/inject_reagent = /datum/reagent/teslium
+ /// How many units to inject per bite
+ var/inject_amount = 2
+
+/mob/living/basic/mold/electric_mosquito/Initialize(mapload)
+ . = ..()
+ AddElement(/datum/element/venomous, inject_reagent, inject_amount)
+
/datum/ai_controller/basic_controller/electric_mosquito
blackboard = list(
BB_TARGETTING_DATUM = new /datum/targetting_datum/basic,
@@ -212,7 +212,7 @@
planning_subtrees = list(
/datum/ai_planning_subtree/simple_find_target,
/datum/ai_planning_subtree/attack_obstacle_in_path,
- /datum/ai_planning_subtree/basic_melee_attack_subtree/electric_mosquito,
+ /datum/ai_planning_subtree/basic_melee_attack_subtree,
/datum/ai_planning_subtree/random_speech/electric_mosquito,
)
@@ -221,24 +221,11 @@
emote_hear = list("zaps.", "buzzes.", "crackles.")
emote_see = list("arcs.")
-/datum/ai_planning_subtree/basic_melee_attack_subtree/electric_mosquito
- melee_attack_behavior = /datum/ai_behavior/basic_melee_attack/electric_mosquito
-
-/datum/ai_behavior/basic_melee_attack/electric_mosquito/perform(seconds_per_tick, datum/ai_controller/controller, target_key, targetting_datum_key, hiding_location_key)
- . = ..()
- var/atom/target = controller.blackboard[target_key]
-
- if(!iscarbon(target))
- return
-
- var/mob/living/carbon/shock_target = target
- shock_target.reagents.add_reagent(/datum/reagent/teslium, 2)
-
/**
* RADIATION MOLD
*
* Weird centipede things that spawn with a rad mold
- * They have a chance to irradiate their target on hit, as well as splashing mutagen on death
+ * They have a chance to irradiate their target on hit
*/
/mob/living/basic/mold/centaur
name = "centaur"
@@ -271,21 +258,21 @@
/// The chance to irradiate on hit
var/irradiate_chance = 20
- /// The chem to splash on death
- var/death_chem = /datum/reagent/toxin/mutagen
/mob/living/basic/mold/centaur/Initialize(mapload)
. = ..()
update_overlays()
-/mob/living/basic/mold/centaur/death(gibbed)
- visible_message(span_warning("[src] ruptures!"))
- var/datum/reagents/reagent_spawn = new /datum/reagents(300)
- reagent_spawn.my_atom = src
- reagent_spawn.add_reagent(death_chem, 20)
- chem_splash(loc, null, CENTAUR_DEATH_SPLASH_RANGE, list(reagent_spawn))
- playsound(src, 'sound/effects/splat.ogg', CENTAUR_DEATH_SPLAT_VOLUME, TRUE)
- return ..()
+/mob/living/basic/mold/centaur/melee_attack(atom/target, list/modifiers, ignore_cooldown)
+ . = ..()
+
+ if(!isliving(target))
+ return
+
+ var/mob/living/radiation_target = target
+ if(prob(irradiate_chance))
+ radiation_pulse(radiation_target, CENTAUR_RAD_PULSE_RANGE, CENTAUR_RAD_PULSE_THRESHOLD, FALSE, TRUE)
+ playsound(src, 'modular_skyrat/modules/horrorform/sound/horror_scream.ogg', CENTAUR_ATTACK_SCREAM_VOLUME, TRUE)
/datum/ai_controller/basic_controller/centaur
blackboard = list(
@@ -297,7 +284,7 @@
planning_subtrees = list(
/datum/ai_planning_subtree/simple_find_target,
/datum/ai_planning_subtree/attack_obstacle_in_path,
- /datum/ai_planning_subtree/basic_melee_attack_subtree/centaur,
+ /datum/ai_planning_subtree/basic_melee_attack_subtree,
/datum/ai_planning_subtree/random_speech/centaur,
)
@@ -306,21 +293,6 @@
emote_hear = list("chitters.", "groans.", "wails.")
emote_see = list("writhes.")
-/datum/ai_planning_subtree/basic_melee_attack_subtree/centaur
- melee_attack_behavior = /datum/ai_behavior/basic_melee_attack/centaur
-
-/datum/ai_behavior/basic_melee_attack/centaur/perform(seconds_per_tick, datum/ai_controller/controller, target_key, targetting_datum_key, hiding_location_key)
- . = ..()
- var/atom/target = controller.blackboard[target_key]
- var/mob/living/basic/mold/centaur/centaur = controller.pawn
-
- if(!isliving(target))
- return
-
- var/mob/living/radiation_target = target
- if(prob(centaur.irradiate_chance))
- radiation_pulse(radiation_target, CENTAUR_RAD_PULSE_RANGE, CENTAUR_RAD_PULSE_THRESHOLD, FALSE, TRUE)
- playsound(src, 'modular_skyrat/modules/horrorform/sound/horror_scream.ogg', CENTAUR_ATTACK_SCREAM_VOLUME, TRUE)
#undef OIL_SHAMBLER_OVERLAY
diff --git a/modular_skyrat/modules/nanotrasen_naval_command/code/outfits.dm b/modular_skyrat/modules/nanotrasen_naval_command/code/outfits.dm
index ff6662d210d..bca8833da46 100644
--- a/modular_skyrat/modules/nanotrasen_naval_command/code/outfits.dm
+++ b/modular_skyrat/modules/nanotrasen_naval_command/code/outfits.dm
@@ -29,7 +29,10 @@
gloves = /obj/item/clothing/gloves/tackler/combat/insulated
- backpack_contents = list(/obj/item/storage/box/survival/security, /obj/item/storage/box/gunset/pdh)
+ backpack_contents = list(
+ /obj/item/storage/box/survival/security,
+ /obj/item/storage/toolbox/guncase/skyrat/pistol/trappiste_small_case/skild,
+ )
/datum/outfit/centcom/naval/lieutenant
name = "Nanotrasen Naval Command - Lieutenant"
@@ -44,7 +47,10 @@
gloves = /obj/item/clothing/gloves/combat/naval
- backpack_contents = list(/obj/item/storage/box/survival/security, /obj/item/storage/box/gunset/pdh)
+ backpack_contents = list(
+ /obj/item/storage/box/survival/security,
+ /obj/item/storage/toolbox/guncase/skyrat/pistol/trappiste_small_case/skild,
+ )
/datum/outfit/centcom/naval/lieutenant_commander
name = "Nanotrasen Naval Command - Lieutenant Commander"
@@ -61,7 +67,10 @@
gloves = /obj/item/clothing/gloves/combat/naval
- backpack_contents = list(/obj/item/storage/box/survival/security, /obj/item/storage/box/gunset/pdh)
+ backpack_contents = list(
+ /obj/item/storage/box/survival/security,
+ /obj/item/storage/toolbox/guncase/skyrat/pistol/trappiste_small_case/skild,
+ )
/datum/outfit/centcom/naval/commander
name = "Nanotrasen Naval Command - Commander"
@@ -78,7 +87,10 @@
gloves = /obj/item/clothing/gloves/combat/naval
- backpack_contents = list(/obj/item/storage/box/survival/security, /obj/item/storage/box/gunset/pdh)
+ backpack_contents = list(
+ /obj/item/storage/box/survival/security,
+ /obj/item/storage/toolbox/guncase/skyrat/pistol/trappiste_small_case/skild,
+ )
/datum/outfit/centcom/naval/captain
name = "Nanotrasen Naval Command - Captain"
@@ -95,7 +107,10 @@
gloves = /obj/item/clothing/gloves/combat/naval
- backpack_contents = list(/obj/item/storage/box/survival/security, /obj/item/storage/box/gunset/pdh)
+ backpack_contents = list(
+ /obj/item/storage/box/survival/security,
+ /obj/item/storage/toolbox/guncase/skyrat/pistol/trappiste_small_case/skild,
+ )
/datum/outfit/centcom/naval/rear_admiral
name = "Nanotrasen Naval Command - Rear Admiral"
@@ -108,7 +123,10 @@
gloves = /obj/item/clothing/gloves/combat/naval
- backpack_contents = list(/obj/item/storage/box/survival/security, /obj/item/storage/box/gunset/pdh_captain)
+ backpack_contents = list(
+ /obj/item/storage/box/survival/security,
+ /obj/item/storage/toolbox/guncase/skyrat/pistol/trappiste_small_case/skild,
+ )
/datum/outfit/centcom/naval/admiral
name = "Nanotrasen Naval Command - Admiral"
@@ -123,7 +141,10 @@
gloves = /obj/item/clothing/gloves/combat/naval
- backpack_contents = list(/obj/item/storage/box/survival/security, /obj/item/storage/box/gunset/pdh_captain)
+ backpack_contents = list(
+ /obj/item/storage/box/survival/security,
+ /obj/item/storage/toolbox/guncase/skyrat/pistol/trappiste_small_case/skild,
+ )
/datum/outfit/centcom/naval/fleet_admiral
name = "Nanotrasen Naval Command - Fleet Admiral"
@@ -138,4 +159,7 @@
gloves = /obj/item/clothing/gloves/combat/naval/fleet_admiral
- backpack_contents = list(/obj/item/storage/box/survival/security, /obj/item/storage/box/gunset/pdh_corpo)
+ backpack_contents = list(
+ /obj/item/storage/box/survival/security,
+ /obj/item/storage/toolbox/guncase/skyrat/pistol/trappiste_small_case/skild,
+ )
diff --git a/modular_skyrat/modules/nanotrasen_rep/code/m45a5.dm b/modular_skyrat/modules/nanotrasen_rep/code/m45a5.dm
deleted file mode 100644
index 8d14eab2b2f..00000000000
--- a/modular_skyrat/modules/nanotrasen_rep/code/m45a5.dm
+++ /dev/null
@@ -1,45 +0,0 @@
-
-
-/obj/item/gun/ballistic/automatic/pistol/m45a5
- name = "\improper M45A5 Elite"
- desc = "A hand-assembled custom sporting handgun by Alpha Centauri Armories, chambered in .460 Rowland magnum. This model has a highly modular structure, to acommodate for ammo costs."
- icon = 'modular_skyrat/modules/blueshield/icons/M45A5.dmi'
- icon_state = "m45a5"
- w_class = WEIGHT_CLASS_NORMAL
- accepted_magazine_type = /obj/item/ammo_box/magazine/m45a5
- can_suppress = FALSE
- fire_delay = 4.25 //Originally 1.75 which was unintentionally extremely fast.
- fire_sound_volume = 60
- spread = 2
- force = 8 //There's heavier guns that dealt less damage on melee than this so we're reducing it from the original 12
- recoil = 0
- fire_sound = 'modular_skyrat/modules/sec_haul/sound/dp_fire.ogg'
-
-/obj/item/gun/ballistic/automatic/pistol/m45a5/add_seclight_point()
- AddComponent(/datum/component/seclite_attachable, light_overlay_icon = 'icons/obj/weapons/guns/flashlights.dmi', light_overlay = "flight")
-
-/obj/item/ammo_box/magazine/m45a5
- name = "ACA modular magazine"
- desc = "A magazine able to chamber .460 Rowland Magnun. Made for the M45A5, as it's the only available sidearm with a smart multi-caliber mechanism."
- icon = 'modular_skyrat/modules/blueshield/icons/M45A5.dmi'
- icon_state = "rowlandmodular"
- ammo_type = /obj/item/ammo_casing/b460
- caliber = CALIBER_460
- max_ammo = 8 //Previously 15, then previously 10. Locked to 8, as you can now restock .460 Magnum which was unintended due to its strong nature.
- multiple_sprites = AMMO_BOX_FULL_EMPTY
-
-/obj/item/ammo_casing/b460
- name = ".460 Rowland Magnum bullet casing"
- desc = "A .460 Rowland magnum casing."
- icon = 'modular_skyrat/modules/sec_haul/icons/guns/ammo_cartridges.dmi'
- icon_state = "sl-casing"
- caliber = CALIBER_460
- projectile_type = /obj/projectile/bullet/b460
-
-/obj/projectile/bullet/b460
- name = ".460 RM JHP bullet"
- damage = 30
- wound_bonus = 30
- weak_against_armour = TRUE
- speed = 2 //Previously 2.25. Now compensates for ammo count.
-
diff --git a/modular_skyrat/modules/nanotrasen_rep/code/nanotrasen_consultant.dm b/modular_skyrat/modules/nanotrasen_rep/code/nanotrasen_consultant.dm
index b9126f3a3a5..02524eafb6f 100644
--- a/modular_skyrat/modules/nanotrasen_rep/code/nanotrasen_consultant.dm
+++ b/modular_skyrat/modules/nanotrasen_rep/code/nanotrasen_consultant.dm
@@ -54,7 +54,7 @@
head = /obj/item/clothing/head/nanotrasen_consultant
backpack_contents = list(
/obj/item/melee/baton/telescopic = 1,
- /obj/item/storage/box/gunset/nanotrasen_consultant = 1,
+ /obj/item/storage/toolbox/guncase/skyrat/pistol/trappiste_small_case/skild = 1,
)
skillchips = list(/obj/item/skillchip/disk_verifier)
@@ -111,21 +111,6 @@
inserted_item = /obj/item/pen/fountain/captain
greyscale_colors = "#017941#0060b8"
-/obj/item/storage/box/gunset/nanotrasen_consultant
- name = "M45A5 gunset"
- w_class = WEIGHT_CLASS_NORMAL
-
-/obj/item/gun/ballistic/automatic/pistol/m45a5/nomag
- spawnwithmagazine = FALSE
-
-/obj/item/storage/box/gunset/nanotrasen_consultant/PopulateContents()
- . = ..()
- new /obj/item/gun/ballistic/automatic/pistol/m45a5/nomag(src)
- new /obj/item/ammo_box/magazine/m45a5(src)
- new /obj/item/ammo_box/magazine/m45a5(src)
- new /obj/item/ammo_box/magazine/m45a5(src)
- new /obj/item/ammo_box/magazine/m45a5(src)
-
/obj/item/storage/bag/garment/nanotrasen_consultant
name = "Nanotrasen consultant's garment bag"
desc = "A bag for storing extra clothes and shoes. This one belongs to the Nanotrasen consultant."
diff --git a/modular_skyrat/modules/novaya_ert/code/advanced_choice_beacon.dm b/modular_skyrat/modules/novaya_ert/code/advanced_choice_beacon.dm
index 094970ccd55..0003bed02e2 100644
--- a/modular_skyrat/modules/novaya_ert/code/advanced_choice_beacon.dm
+++ b/modular_skyrat/modules/novaya_ert/code/advanced_choice_beacon.dm
@@ -121,7 +121,7 @@
icon = 'modular_skyrat/modules/novaya_ert/icons/turret_deployable.dmi'
icon_state = "living"
base_icon_state = "living"
- stun_projectile = /obj/projectile/bullet/b12mm/rubber
+ stun_projectile = /obj/projectile/bullet/a762x39/rubber
lethal_projectile = /obj/projectile/bullet/a762x39
max_integrity = 150
req_access = list(ACCESS_CENT_GENERAL)
diff --git a/modular_skyrat/modules/novaya_ert/code/automatic.dm b/modular_skyrat/modules/novaya_ert/code/automatic.dm
index a3ed2765279..64e2637edd5 100644
--- a/modular_skyrat/modules/novaya_ert/code/automatic.dm
+++ b/modular_skyrat/modules/novaya_ert/code/automatic.dm
@@ -12,7 +12,7 @@
icon_state = "nri_smg"
inhand_icon_state = "nri_smg"
w_class = WEIGHT_CLASS_BULKY
- accepted_magazine_type = /obj/item/ammo_box/magazine/multi_sprite/cfa_lynx
+ accepted_magazine_type = /obj/item/ammo_box/magazine/uzim9mm
fire_delay = 1
burst_size = 5
dual_wield_spread = 5
@@ -26,15 +26,16 @@
/obj/item/gun/ballistic/automatic/nri_smg/give_manufacturer_examine()
AddElement(/datum/element/manufacturer_examine, COMPANY_IZHEVSK)
-/obj/item/gun/ballistic/automatic/pistol/ladon/nri
+/obj/item/gun/ballistic/automatic/pistol/nri
name = "\improper Szabo-Ivanek service pistol"
- desc = "A mass produced NRI-made modified reproduction of the PDH-6 line of handguns rechambered in 9×25mm.\
+ desc = "A mass produced NRI-made modified reproduction of the Wespe line of handguns rechambered in 9×25mm.\
'PATRIOT DEFENSE SYSTEMS' is inscribed on the receiver, indicating it's been made with a plasteel printer."
icon = 'modular_skyrat/modules/novaya_ert/icons/pistol.dmi'
+ icon_state = "ladon"
w_class = WEIGHT_CLASS_SMALL
accepted_magazine_type = /obj/item/ammo_box/magazine/m9mm_aps
burst_size = 3
fire_delay = 3
-/obj/item/gun/ballistic/automatic/pistol/ladon/nri/give_manufacturer_examine()
+/obj/item/gun/ballistic/automatic/pistol/nri/give_manufacturer_examine()
AddElement(/datum/element/manufacturer_examine, COMPANY_IZHEVSK)
diff --git a/modular_skyrat/modules/novaya_ert/code/belt.dm b/modular_skyrat/modules/novaya_ert/code/belt.dm
index 02cedded45f..cb34dbe63fd 100644
--- a/modular_skyrat/modules/novaya_ert/code/belt.dm
+++ b/modular_skyrat/modules/novaya_ert/code/belt.dm
@@ -52,7 +52,7 @@
/obj/item/storage/belt/military/nri/medic/full/PopulateContents()
generate_items_inside(list(
- /obj/item/ammo_box/magazine/multi_sprite/cfa_lynx = 4,
+ /obj/item/ammo_box/magazine/uzim9mm = 4,
/obj/item/knife/combat = 1,
/obj/item/grenade/smokebomb = 1,
/obj/item/grenade/frag = 1,
@@ -60,7 +60,7 @@
/obj/item/storage/belt/military/nri/engineer/full/PopulateContents()
generate_items_inside(list(
- /obj/item/ammo_box/magazine/multi_sprite/cfa_lynx = 4,
+ /obj/item/ammo_box/magazine/uzim9mm = 4,
/obj/item/knife/combat = 1,
/obj/item/grenade/smokebomb = 1,
/obj/item/grenade/frag = 1,
diff --git a/modular_skyrat/modules/novaya_ert/code/outfit.dm b/modular_skyrat/modules/novaya_ert/code/outfit.dm
index a88805933af..35b90414bd0 100644
--- a/modular_skyrat/modules/novaya_ert/code/outfit.dm
+++ b/modular_skyrat/modules/novaya_ert/code/outfit.dm
@@ -17,7 +17,7 @@
/obj/item/beamout_tool,
/obj/item/crucifix,
/obj/item/reagent_containers/cup/glass/waterbottle/large/cryptobiolin)
- l_pocket = /obj/item/gun/ballistic/automatic/pistol/ladon/nri
+ l_pocket = /obj/item/gun/ballistic/automatic/pistol/nri
r_pocket = /obj/item/ammo_box/magazine/m9mm_aps
shoes = /obj/item/clothing/shoes/combat
@@ -157,7 +157,7 @@
belt = /obj/item/clipboard
back = /obj/item/storage/backpack/satchel/leather
backpack_contents = list(/obj/item/storage/box/nri_survival_pack,
- /obj/item/gun/ballistic/automatic/pistol/ladon/nri,
+ /obj/item/gun/ballistic/automatic/pistol/nri,
/obj/item/ammo_box/magazine/m9mm_aps,
/obj/item/ammo_box/magazine/m9mm_aps,
/obj/item/storage/medkit/expeditionary,
diff --git a/modular_skyrat/modules/novaya_ert/code/toolbox.dm b/modular_skyrat/modules/novaya_ert/code/toolbox.dm
index 19dde9e7ef2..77ad7051a52 100644
--- a/modular_skyrat/modules/novaya_ert/code/toolbox.dm
+++ b/modular_skyrat/modules/novaya_ert/code/toolbox.dm
@@ -48,15 +48,9 @@
desc = "It contains a few magazines."
ammo_type = /obj/item/ammo_box/magazine/akm/ap
-/obj/item/storage/toolbox/ammobox/full/bison
- name = "ammo box (PP-95)"
- desc = "It contains a few magazines."
- ammo_type = /obj/item/ammo_box/magazine/multi_sprite/cfa_lynx
- amount = 4
-
/obj/item/storage/toolbox/ammobox/full/nri_smg
name = "ammo box (QLP/04)"
- ammo_type = /obj/item/ammo_box/magazine/multi_sprite/cfa_lynx
+ ammo_type = /obj/item/ammo_box/magazine/uzim9mm
amount = 7
/obj/item/storage/toolbox/ammobox/full/l6_saw
@@ -65,12 +59,6 @@
ammo_type = /obj/item/ammo_box/magazine/m7mm
amount = 7
-/obj/item/storage/toolbox/ammobox/full/makarov
- name = "ammo box (R-C Makarov)"
- desc = "It contains a few magazines."
- ammo_type = /obj/item/ammo_box/magazine/multi_sprite/makarov
- amount = 7
-
/obj/item/storage/toolbox/ammobox/full/aps
name = "ammo box (Szabo-Ivanek/APS)"
desc = "It contains a few magazines."
diff --git a/modular_skyrat/modules/opposing_force/code/equipment/ammo.dm b/modular_skyrat/modules/opposing_force/code/equipment/ammo.dm
index 687e74fe581..cbdbc89bc19 100644
--- a/modular_skyrat/modules/opposing_force/code/equipment/ammo.dm
+++ b/modular_skyrat/modules/opposing_force/code/equipment/ammo.dm
@@ -33,13 +33,13 @@
item_type = /obj/item/ammo_box/magazine/uzim9mm
description = "A thirty-two round magazine for the mini uzi. Uses 9x19mm ammunition."
-/datum/opposing_force_equipment/ammo/lynx
- item_type = /obj/item/ammo_box/magazine/multi_sprite/cfa_lynx
- description = "A forty round magazine for CFA Lynx and QLP/04 submachine guns."
+/datum/opposing_force_equipment/ammo/sol40standard
+ item_type = /obj/item/ammo_box/magazine/c40sol_rifle/standard
+ description = "A thirty round magazine for any SolFed rifle."
-/datum/opposing_force_equipment/ammo/cm68
- item_type = /obj/item/ammo_box/magazine/cm68
- description = "6.8mm bullets in a ten round magazine for a Cantanheim 6.8 rifle."
+/datum/opposing_force_equipment/ammo/sol40drum
+ item_type = /obj/item/ammo_box/magazine/c40sol_rifle/drum
+ description = "A sixty round drum for any SolFed rifle."
/datum/opposing_force_equipment/ammo/makarov
item_type = /obj/item/ammo_box/magazine/m9mm
@@ -81,144 +81,14 @@
item_type = /obj/item/ammo_box/a357/match
description = "A seven-round .357 magnum speedloader for a revolver, loaded with match-grade ammunition that bounces off walls several times."
-/datum/opposing_force_equipment/ammo/cfa_snub
- item_type = /obj/item/ammo_box/magazine/multi_sprite/cfa_snub
+/datum/opposing_force_equipment/ammo/sol35_standard
+ item_type = /obj/item/ammo_box/magazine/c35sol_pistol
-/datum/opposing_force_equipment/ammo/cfa_snubap
- item_type = /obj/item/ammo_box/magazine/multi_sprite/cfa_snub/ap
+/datum/opposing_force_equipment/ammo/sol35_extended
+ item_type = /obj/item/ammo_box/magazine/c35sol_pistol/stendo
-/datum/opposing_force_equipment/ammo/cfa_snubrubber
- item_type = /obj/item/ammo_box/magazine/multi_sprite/cfa_snub/rubber
-
-/datum/opposing_force_equipment/ammo/cfa_snubincendiary
- item_type = /obj/item/ammo_box/magazine/multi_sprite/cfa_snub/incendiary
-
-/datum/opposing_force_equipment/ammo/cfa_ruby
- item_type = /obj/item/ammo_box/magazine/multi_sprite/cfa_ruby
-
-/datum/opposing_force_equipment/ammo/cfa_rubyap
- item_type = /obj/item/ammo_box/magazine/multi_sprite/cfa_ruby/ap
-
-/datum/opposing_force_equipment/ammo/cfa_rubyrubber
- item_type = /obj/item/ammo_box/magazine/multi_sprite/cfa_ruby/rubber
-
-/datum/opposing_force_equipment/ammo/cfa_rubyhp
- item_type = /obj/item/ammo_box/magazine/multi_sprite/cfa_ruby/hp
-
-/datum/opposing_force_equipment/ammo/cfa_rubyincendiary
- item_type = /obj/item/ammo_box/magazine/multi_sprite/cfa_ruby/incendiary
-
-/datum/opposing_force_equipment/ammo/wildcat
- item_type = /obj/item/ammo_box/magazine/multi_sprite/cfa_wildcat
-
-/datum/opposing_force_equipment/ammo/wildcatap
- item_type = /obj/item/ammo_box/magazine/multi_sprite/cfa_wildcat/ap
-
-/datum/opposing_force_equipment/ammo/wildcatrubber
- item_type = /obj/item/ammo_box/magazine/multi_sprite/cfa_wildcat/rubber
-
-/datum/opposing_force_equipment/ammo/wildcatincendiary
- item_type = /obj/item/ammo_box/magazine/multi_sprite/cfa_wildcat/incendiary
-
-/datum/opposing_force_equipment/ammo/glock17
- name = "Glock 17 Magazine"
- item_type = /obj/item/ammo_box/magazine/multi_sprite/g17
-
-/datum/opposing_force_equipment/ammo/glock17hp
- name = "Glock 17 Magazine (HP)"
- item_type = /obj/item/ammo_box/magazine/multi_sprite/g17/hp
-
-/datum/opposing_force_equipment/ammo/glock18
- name = "Glock 18 Magazine"
- item_type = /obj/item/ammo_box/magazine/multi_sprite/g18
-
-/datum/opposing_force_equipment/ammo/glock18hp
- name = "Glock 18 Magazine (HP)"
- item_type = /obj/item/ammo_box/magazine/multi_sprite/g18/hp
-
-/datum/opposing_force_equipment/ammo/ladon
- name = "P-3 'Ladon' Magazine"
- item_type = /obj/item/ammo_box/magazine/multi_sprite/ladon
-
-/datum/opposing_force_equipment/ammo/ladonhp
- name = "P-3 'Ladon' Magazine (HP)"
- item_type = /obj/item/ammo_box/magazine/multi_sprite/ladon/hp
-
-/datum/opposing_force_equipment/ammo/dozer
- name = "DZR-9 'Dozer' Magazine"
- item_type = /obj/item/ammo_box/magazine/multi_sprite/dozer
-
-/datum/opposing_force_equipment/ammo/dozerhp
- name = "DZR-9 'Dozer' Magazine (HP)"
- item_type = /obj/item/ammo_box/magazine/multi_sprite/dozer/hp
-
-/datum/opposing_force_equipment/ammo/pdh
- name = "PDH-6H 'Peacekeeper' Magazine"
- item_type = /obj/item/ammo_box/magazine/multi_sprite/pdh
-
-/datum/opposing_force_equipment/ammo/pdhhp
- name = "PDH-6H 'Peacekeeper' Magazine (HP)"
- item_type = /obj/item/ammo_box/magazine/multi_sprite/pdh/hp
-
-/datum/opposing_force_equipment/ammo/mk58
- name = "MK-58 Magazine"
- item_type = /obj/item/ammo_box/magazine/multi_sprite/mk58
-
-/datum/opposing_force_equipment/ammo/mk58hp
- name = "MK-58 Magazine (HP)"
- item_type = /obj/item/ammo_box/magazine/multi_sprite/mk58/hp
-
-/datum/opposing_force_equipment/ammo/croon
- name = "DT-4 'Croon' Magazine"
- item_type = /obj/item/ammo_box/magazine/multi_sprite/croon
-
-/datum/opposing_force_equipment/ammo/zeta
- name = "Zeta-6 'Spurchamber' Speedloader"
- item_type = /obj/item/ammo_box/revolver/zeta/full
-
-/datum/opposing_force_equipment/ammo/revolution
- name = "Revolution-8 'Spurmaster' Speedloader"
- item_type = /obj/item/ammo_box/revolver/revolution/full
-
-/datum/opposing_force_equipment/ammo/g11
- name = "G11 K-490 Magazine"
- item_type = /obj/item/ammo_box/magazine/multi_sprite/g11
-
-/datum/opposing_force_equipment/ammo/g11hp
- name = "G11 K-490 Magazine (HP)"
- item_type = /obj/item/ammo_box/magazine/multi_sprite/g11/hp
-
-/datum/opposing_force_equipment/ammo/vintorez
- name = "PCR Magazine"
- item_type = /obj/item/ammo_box/magazine/multi_sprite/vintorez
-
-/datum/opposing_force_equipment/ammo/vintorezhp
- name = "PCR Magazine (HP)"
- item_type = /obj/item/ammo_box/magazine/multi_sprite/vintorez/hp
-
-/datum/opposing_force_equipment/ammo/pcr
- name = "PCR Magazine"
- item_type = /obj/item/ammo_box/magazine/multi_sprite/pcr
-
-/datum/opposing_force_equipment/ammo/pcrhp
- name = "PCR Magazine (HP)"
- item_type = /obj/item/ammo_box/magazine/multi_sprite/pcr/hp
-
-/datum/opposing_force_equipment/ammo/pitbull
- name = "Pitbull PDW Magazine"
- item_type = /obj/item/ammo_box/magazine/multi_sprite/pitbull
-
-/datum/opposing_force_equipment/ammo/pitbullhp
- name = "Pitbull PDW Magazine (HP)"
- item_type = /obj/item/ammo_box/magazine/multi_sprite/pitbull/hp
-
-/datum/opposing_force_equipment/ammo/ostwind
- name = "DTR-6 Rifle Magazine"
- item_type = /obj/item/ammo_box/magazine/multi_sprite/ostwind
-
-/datum/opposing_force_equipment/ammo/ostwindfrag
- name = "DTR-6 Rifle Magazine (Frag)"
- item_type = /obj/item/ammo_box/magazine/multi_sprite/ostwind/ihdf
+/datum/opposing_force_equipment/ammo/trappiste585_standard
+ item_type = /obj/item/ammo_box/magazine/c585trappiste_pistol
/datum/opposing_force_equipment/ammo/bulldog
name = "Bulldog Magazine"
@@ -252,7 +122,3 @@
/datum/opposing_force_equipment/ammo/c20rfire
name = "C-20r Magazine (Incendiary)"
item_type = /obj/item/ammo_box/magazine/smgm45/incen
-
-/datum/opposing_force_equipment/ammo/pepperball
- name = "Pepperball Magazine"
- item_type = /obj/item/ammo_box/magazine/pepperball
diff --git a/modular_skyrat/modules/opposing_force/code/equipment/pistols.dm b/modular_skyrat/modules/opposing_force/code/equipment/pistols.dm
index 88abe0e68b1..8d77b5c37a3 100644
--- a/modular_skyrat/modules/opposing_force/code/equipment/pistols.dm
+++ b/modular_skyrat/modules/opposing_force/code/equipment/pistols.dm
@@ -17,7 +17,7 @@
admin_note = "WARNING: Roughly on-par with the .357, can use AP rounds."
/datum/opposing_force_equipment/pistol/nri_pistol
- item_type = /obj/item/gun/ballistic/automatic/pistol/ladon/nri
+ item_type = /obj/item/gun/ballistic/automatic/pistol/nri
admin_note = "WARNING: Roughly on-par with the .357, can use AP rounds. Essentially a reflavored APS."
/datum/opposing_force_equipment/pistol/g357
@@ -33,36 +33,5 @@
item_type = /obj/item/gun/ballistic/revolver/nagant
admin_note = "WARNING: This weapon is very powerful, firing semi-auto 60 damage bullets."
-/datum/opposing_force_equipment/pistol/snub
- item_type = /obj/item/gun/ballistic/automatic/pistol/cfa_snub
- description = "A small easily-concealable modern pistol chambered in the more widely-used 4.6x30mm. It's specifically designed to be compact."
- admin_note = "Fires 20 damage bullets."
-
-/datum/opposing_force_equipment/pistol/ruby
- item_type = /obj/item/gun/ballistic/automatic/pistol/cfa_ruby
- description = "A large and loud modern handgun made to fit more universally used cartridges. It's chambered in .45, or 11.43x23mm."
- admin_note = "Fires 40 damage bullets."
-
-/datum/opposing_force_equipment/pistol/glock17
- item_type = /obj/item/gun/ballistic/automatic/pistol/g17
-
-/datum/opposing_force_equipment/pistol/glock18
- item_type = /obj/item/gun/ballistic/automatic/pistol/g18
-
-/datum/opposing_force_equipment/pistol/ladon
- item_type = /obj/item/gun/ballistic/automatic/pistol/ladon
-
-/datum/opposing_force_equipment/pistol/pdh
- item_type = /obj/item/gun/ballistic/automatic/pistol/pdh
-
-/datum/opposing_force_equipment/pistol/mk58
- item_type = /obj/item/gun/ballistic/automatic/pistol/mk58
-
-/datum/opposing_force_equipment/pistol/zeta
- item_type = /obj/item/gun/ballistic/revolver/zeta
-
-/datum/opposing_force_equipment/pistol/revolution
- item_type = /obj/item/gun/ballistic/revolver/revolution
-
-/datum/opposing_force_equipment/pistol/pepperball
- item_type = /obj/item/gun/ballistic/automatic/pistol/pepperball
+/datum/opposing_force_equipment/pistol/wespe
+ item_type = /obj/item/gun/ballistic/automatic/pistol/sol/evil
diff --git a/modular_skyrat/modules/opposing_force/code/equipment/rifles.dm b/modular_skyrat/modules/opposing_force/code/equipment/rifles.dm
index cc9e853eb7c..05739759a80 100644
--- a/modular_skyrat/modules/opposing_force/code/equipment/rifles.dm
+++ b/modular_skyrat/modules/opposing_force/code/equipment/rifles.dm
@@ -9,17 +9,5 @@
item_type = /obj/item/gun/ballistic/automatic/akm/nri
admin_note = "WARNING: This weapon is extremely powerful, firing a 3 round burst of 38 damage bullets."
-/datum/opposing_force_equipment/rifle/cfa
- item_type = /obj/item/gun/ballistic/automatic/cfa_rifle
- admin_note = "WARNING: This weapon is very powerful, firing single-shot 60 damage bullets."
-
-/datum/opposing_force_equipment/rifle/norwind
- item_type = /obj/item/gun/ballistic/automatic/norwind
- description = "A rare M112 DMR rechambered to 12.7x30mm for peacekeeping work, it comes with a scope for medium-long range engagements. A bayonet lug is visible."
-
-/datum/opposing_force_equipment/rifle/ostwind
- item_type = /obj/item/gun/ballistic/automatic/ostwind
- description = "A 6.3mm special-purpose rifle designed for specific situations."
-
-/datum/opposing_force_equipment/rifle/g11
- item_type = /obj/item/gun/ballistic/automatic/g11
+/datum/opposing_force_equipment/rifle/infanterie
+ item_type = /obj/item/gun/ballistic/automatic/sol_rifle/evil
diff --git a/modular_skyrat/modules/opposing_force/code/equipment/shotguns.dm b/modular_skyrat/modules/opposing_force/code/equipment/shotguns.dm
index 4a33b9bb162..74e5d53263c 100644
--- a/modular_skyrat/modules/opposing_force/code/equipment/shotguns.dm
+++ b/modular_skyrat/modules/opposing_force/code/equipment/shotguns.dm
@@ -1,9 +1,8 @@
/datum/opposing_force_equipment/shotgun
category = OPFOR_EQUIPMENT_CATEGORY_SHOTGUNS
-/datum/opposing_force_equipment/shotgun/m23
- item_type = /obj/item/gun/ballistic/shotgun/m23
- description = "An eight-round pump-action shotgun found in an old station. Comes loaded with beanbag shells but can take any 12 gauge load."
+/datum/opposing_force_equipment/shotgun/renoster
+ item_type = /obj/item/gun/ballistic/shotgun/riot/sol/evil
/datum/opposing_force_equipment/shotgun/as2
item_type = /obj/item/gun/ballistic/shotgun/automatic/as2
diff --git a/modular_skyrat/modules/opposing_force/code/equipment/submachineguns.dm b/modular_skyrat/modules/opposing_force/code/equipment/submachineguns.dm
index 15b7b82940b..7b687ae7eca 100644
--- a/modular_skyrat/modules/opposing_force/code/equipment/submachineguns.dm
+++ b/modular_skyrat/modules/opposing_force/code/equipment/submachineguns.dm
@@ -1,6 +1,9 @@
/datum/opposing_force_equipment/submachine_gun
category = OPFOR_EQUIPMENT_CATEGORY_SUBMACHINE_GUNS
+/datum/opposing_force_equipment/submachine_gun/sindano
+ item_type = /obj/item/gun/ballistic/automatic/sol_smg/evil
+
/datum/opposing_force_equipment/submachine_gun/mp40
item_type = /obj/item/gun/ballistic/automatic/mp40
admin_note = "WARNING: This weapon is extremely powerful, firing a 3 round burst of 30 damage bullets."
@@ -23,27 +26,9 @@
description = "The uzi nine millimeter, a timeless submachinegun for a warrior out of time."
admin_note = "WARNING: This weapon is decently powerful, firing a 2 round burst of 30 damage bullets."
-/datum/opposing_force_equipment/submachine_gun/lynx
- item_type = /obj/item/gun/ballistic/automatic/cfa_lynx
- admin_note = "Capable of high rate of fire full auto of 20 damage bullets."
-
/datum/opposing_force_equipment/submachine_gun/nri_smg
item_type = /obj/item/gun/ballistic/automatic/nri_smg
admin_note = "Capable of high rate of fire bursts of 20 damage bullets."
-/datum/opposing_force_equipment/submachine_gun/dozer
- item_type = /obj/item/gun/ballistic/automatic/dozer
-
-/datum/opposing_force_equipment/submachine_gun/croon
- item_type = /obj/item/gun/ballistic/automatic/croon
-
-/datum/opposing_force_equipment/submachine_gun/pcr
- item_type = /obj/item/gun/ballistic/automatic/pcr
- description = "An accurate, fast-firing SMG chambered in 9x19mm."
-
-/datum/opposing_force_equipment/submachine_gun/pitbull
- item_type = /obj/item/gun/ballistic/automatic/pitbull
- description = "A sturdy personal defense weapon designed to fire 10mm Auto rounds."
-
/datum/opposing_force_equipment/submachine_gun/c20r
item_type = /obj/item/gun/ballistic/automatic/c20r/unrestricted
diff --git a/modular_skyrat/modules/opposing_force/code/roundend.dm b/modular_skyrat/modules/opposing_force/code/roundend.dm
index 07b81ff4e8a..1725eeaf363 100644
--- a/modular_skyrat/modules/opposing_force/code/roundend.dm
+++ b/modular_skyrat/modules/opposing_force/code/roundend.dm
@@ -1,7 +1,7 @@
/datum/controller/subsystem/ticker/proc/opfor_report()
var/list/result = list()
- result += "
Opposing Force Report: "
+ result += "Opposing Force Report: "
if(!SSopposing_force.approved_applications.len)
result += span_red("No applications were approved.")
@@ -9,6 +9,4 @@
for(var/datum/opposing_force/opfor in SSopposing_force.approved_applications)
result += opfor.roundend_report()
- result += "