Kills seconds_per_tick from status effect tick, replaces it with seconds_between_ticks to clarify some things (#77219)

## About The Pull Request

https://github.com/tgstation/tgstation/pull/66573#discussion_r861157216

`status_effect/proc/tick(seconds_per_tick)` is wildly misleading and I
feel like I should address it

For a majority of status effects, they process on fast processing but do
not tick every fastprocessing tick

This means that using `seconds_per_tick` here is not giving you the
seconds between status effect ticks, it's giving you seconds between
processing ticks (`0.2`)

This is how it's misleading - If you have a tick interval of `1
SECONDS`, you'd think `seconds_per_tick` is, well, one. But it's
actually one-fifth. So all of your effects are now 80% weaker.

I have replaced the use of `seconds_per_tick` in tick with
`seconds_between_ticks`.

This number is, quite simply, the initial tick interval of the status
effect divided by ten.

An effect with the tick interval of `1 SECONDS` has a
`seconds_between_ticks` of 1.

As a consequence, some things which were inadvertently made weaker, such
as fire and some heretic things (at a glance), are now a little
stronger.

## Why It's Good For The Game

See above. Makes it more clear what you're doing when working with
effects.

## Changelog

🆑 Melbert
code: Updated some status effect tick code to be more clear of how long
is elapsing between ticks. Some effects that were inadvertently weakened
are now stronger as a result (fire and some heretic effects).
/🆑
This commit is contained in:
MrMelbert
2023-08-08 11:54:12 +12:00
committed by GitHub
parent fa10b18a4b
commit eea20b83e3
39 changed files with 212 additions and 158 deletions
+24 -9
View File
@@ -8,8 +8,9 @@
/// -1 = infinite duration.
var/duration = -1
/// When set initially / in on_creation, this is how long between [proc/tick] calls in deciseconds.
/// Note that this cannot be faster than the processing subsystem you choose to fire the effect on. (See: [var/processing_speed])
/// While processing, this becomes the world.time when the next tick will occur.
/// -1 = will stop processing, if duration is also unlimited (-1).
/// -1 = will prevent ticks, and if duration is also unlimited (-1), stop processing wholesale.
var/tick_interval = 1 SECONDS
/// The mob affected by the status effect.
var/mob/living/owner
@@ -47,14 +48,15 @@
if(duration != -1)
duration = world.time + duration
tick_interval = world.time + tick_interval
if(tick_interval != -1)
tick_interval = world.time + tick_interval
if(alert_type)
var/atom/movable/screen/alert/status_effect/new_alert = owner.throw_alert(id, alert_type)
new_alert.attached_effect = src //so the alert can reference us, if it needs to
linked_alert = new_alert //so we can reference the alert, if we need to
if(duration > 0 || initial(tick_interval) > 0) //don't process if we don't care
if(duration > world.time || tick_interval > world.time) //don't process if we don't care
switch(processing_speed)
if(STATUS_EFFECT_FAST_PROCESS)
START_PROCESSING(SSfastprocess, src)
@@ -81,14 +83,18 @@
// Status effect process. Handles adjusting its duration and ticks.
// If you're adding processed effects, put them in [proc/tick]
// instead of extending / overriding the process() proc.
/datum/status_effect/process(seconds_per_tick, times_fired)
/datum/status_effect/process(seconds_per_tick)
SHOULD_NOT_OVERRIDE(TRUE)
if(QDELETED(owner))
qdel(src)
return
if(tick_interval < world.time)
tick(seconds_per_tick, times_fired)
tick_interval = world.time + initial(tick_interval)
if(tick_interval != -1 && tick_interval < world.time)
var/tick_length = initial(tick_interval)
tick(tick_length / (1 SECONDS))
tick_interval = world.time + tick_length
if(QDELING(src))
// tick deleted us, no need to continue
return
if(duration != -1 && duration < world.time)
qdel(src)
@@ -102,8 +108,17 @@
/datum/status_effect/proc/get_examine_text()
return null
/// Called every tick from process().
/datum/status_effect/proc/tick(seconds_per_tick, times_fired)
/**
* Called every tick from process().
* This is only called of tick_interval is not -1.
*
* Note that every tick =/= every processing cycle.
*
* * seconds_between_ticks = This is how many SECONDS that elapse between ticks.
* This is a constant value based upon the initial tick interval set on the status effect.
* It is similar to seconds_per_tick, from processing itself, but adjusted to the status effect's tick interval.
*/
/datum/status_effect/proc/tick(seconds_between_ticks)
return
/// Called whenever the buff expires or is removed (qdeleted)
@@ -24,7 +24,7 @@
///The target we are pointing towards, refreshes every tick.
var/mob/scan_target
/datum/status_effect/agent_pinpointer/tick()
/datum/status_effect/agent_pinpointer/tick(seconds_between_ticks)
if(!owner)
qdel(src)
return
+12 -12
View File
@@ -3,7 +3,7 @@
/datum/status_effect/his_grace
id = "his_grace"
duration = -1
tick_interval = 4
tick_interval = 0.4 SECONDS
alert_type = /atom/movable/screen/alert/status_effect/his_grace
var/bloodlust = 0
@@ -32,7 +32,7 @@
/datum/status_effect/his_grace/on_remove()
owner.remove_stun_absorption(id)
/datum/status_effect/his_grace/tick()
/datum/status_effect/his_grace/tick(seconds_between_ticks)
bloodlust = 0
var/graces = 0
for(var/obj/item/his_grace/HG in owner.held_items)
@@ -75,7 +75,7 @@
/datum/status_effect/blooddrunk
id = "blooddrunk"
duration = 10
tick_interval = 0
tick_interval = -1
alert_type = /atom/movable/screen/alert/status_effect/blooddrunk
/atom/movable/screen/alert/status_effect/blooddrunk
@@ -136,7 +136,7 @@
/datum/status_effect/fleshmend/on_remove()
UnregisterSignal(owner, list(COMSIG_LIVING_IGNITED, COMSIG_LIVING_EXTINGUISHED))
/datum/status_effect/fleshmend/tick()
/datum/status_effect/fleshmend/tick(seconds_between_ticks)
if(owner.on_fire)
return
@@ -170,7 +170,7 @@
id = "Hippocratic Oath"
status_type = STATUS_EFFECT_UNIQUE
duration = -1
tick_interval = 25
tick_interval = 2.5 SECONDS
alert_type = null
var/datum/component/aura_healing/aura_healing
@@ -211,7 +211,7 @@
/datum/status_effect/hippocratic_oath/get_examine_text()
return span_notice("[owner.p_They()] seem[owner.p_s()] to have an aura of healing and helpfulness about [owner.p_them()].")
/datum/status_effect/hippocratic_oath/tick()
/datum/status_effect/hippocratic_oath/tick(seconds_between_ticks)
if(owner.stat == DEAD)
if(deathTick < 4)
deathTick += 1
@@ -282,7 +282,7 @@
tick_interval = 1 SECONDS
status_type = STATUS_EFFECT_REFRESH
/datum/status_effect/good_music/tick()
/datum/status_effect/good_music/tick(seconds_between_ticks)
if(owner.can_hear())
owner.adjust_dizzy(-4 SECONDS)
owner.adjust_jitter(-4 SECONDS)
@@ -436,17 +436,17 @@
tick_interval = 0.4 SECONDS
alert_type = /atom/movable/screen/alert/status_effect/nest_sustenance
/datum/status_effect/nest_sustenance/tick(seconds_per_tick, times_fired)
/datum/status_effect/nest_sustenance/tick(seconds_between_ticks)
. = ..()
if(owner.stat == DEAD) //If the victim has died due to complications in the nest
qdel(src)
return
owner.adjustBruteLoss(-2 * seconds_per_tick, updating_health = FALSE)
owner.adjustFireLoss(-2 * seconds_per_tick, updating_health = FALSE)
owner.adjustOxyLoss(-4 * seconds_per_tick, updating_health = FALSE)
owner.adjustStaminaLoss(-4 * seconds_per_tick, updating_stamina = FALSE)
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)
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
@@ -100,7 +100,7 @@
/datum/status_effect/temporary_blindness/on_remove()
owner.cure_blind(id)
/datum/status_effect/temporary_blindness/tick(seconds_per_tick, times_fired)
/datum/status_effect/temporary_blindness/tick(seconds_between_ticks)
if(owner.stat == DEAD)
return
@@ -116,7 +116,7 @@
return
// Otherwise add a chance to let them know that it's working
else if(SPT_PROB(5, seconds_per_tick))
else if(SPT_PROB(5, seconds_between_ticks))
var/obj/item/thing_covering_eyes = owner.is_eyes_covered()
// "Your blindfold soothes your eyes", for example
to_chat(owner, span_green("Your [thing_covering_eyes?.name || "eye covering"] soothes your eyes."))
+6 -6
View File
@@ -267,23 +267,23 @@
victim.adjustBruteLoss(0.2)
return TRUE
/datum/status_effect/choke/tick(seconds_per_tick)
/datum/status_effect/choke/tick(seconds_between_ticks)
if(!should_do_effects())
return
deal_damage(seconds_per_tick)
deal_damage(seconds_between_ticks)
var/client/client_owner = owner.client
if(client_owner)
do_vfx(client_owner)
/datum/status_effect/choke/proc/deal_damage(seconds_per_tick)
owner.losebreath += 1 * seconds_per_tick // 1 breath loss a second. This will deal additional breath damage, and prevent breathing
/datum/status_effect/choke/proc/deal_damage(seconds_between_ticks)
owner.losebreath += 1 * seconds_between_ticks // 1 breath loss a second. This will deal additional breath damage, and prevent breathing
if(flaming)
var/obj/item/bodypart/head = owner.get_bodypart(BODY_ZONE_HEAD)
if(head)
head.receive_damage(0, 2 * seconds_per_tick, damage_source = "choking")
owner.adjustStaminaLoss(2 * seconds_per_tick)
head.receive_damage(0, 2 * seconds_between_ticks, damage_source = "choking")
owner.adjustStaminaLoss(2 * seconds_between_ticks)
/datum/status_effect/choke/proc/do_vfx(client/vfx_on)
var/old_x = delta_x
+24 -24
View File
@@ -6,7 +6,7 @@
//Largely negative status effects go here, even if they have small benificial effects
//STUN EFFECTS
/datum/status_effect/incapacitating
tick_interval = 0
tick_interval = -1
status_type = STATUS_EFFECT_REPLACE
alert_type = null
remove_on_fullheal = TRUE
@@ -118,7 +118,7 @@
REMOVE_TRAIT(owner, TRAIT_KNOCKEDOUT, TRAIT_STATUS_EFFECT(id))
return ..()
/datum/status_effect/incapacitating/unconscious/tick()
/datum/status_effect/incapacitating/unconscious/tick(seconds_between_ticks)
if(owner.getStaminaLoss())
owner.adjustStaminaLoss(-0.3) //reduce stamina loss by 0.3 per tick, 6 per 2 seconds
@@ -159,7 +159,7 @@
ADD_TRAIT(owner, TRAIT_KNOCKEDOUT, TRAIT_STATUS_EFFECT(id))
tick_interval = initial(tick_interval)
/datum/status_effect/incapacitating/sleeping/tick()
/datum/status_effect/incapacitating/sleeping/tick(seconds_between_ticks)
if(owner.maxHealth)
var/health_ratio = owner.health / owner.maxHealth
var/healing = HEALING_SLEEP_DEFAULT
@@ -273,7 +273,7 @@
var/mob/living/carbon/carbon_owner = owner
carbon_owner.update_bodypart_bleed_overlays()
/datum/status_effect/grouped/stasis/tick()
/datum/status_effect/grouped/stasis/tick(seconds_between_ticks)
update_time_of_death()
/datum/status_effect/grouped/stasis/on_remove()
@@ -293,7 +293,7 @@
/datum/status_effect/his_wrath //does minor damage over time unless holding His Grace
id = "his_wrath"
duration = -1
tick_interval = 4
tick_interval = 0.4 SECONDS
alert_type = /atom/movable/screen/alert/status_effect/his_wrath
/atom/movable/screen/alert/status_effect/his_wrath
@@ -302,7 +302,7 @@
icon_state = "his_grace"
alerttooltipstyle = "hisgrace"
/datum/status_effect/his_wrath/tick()
/datum/status_effect/his_wrath/tick(seconds_between_ticks)
for(var/obj/item/his_grace/HG in owner.held_items)
qdel(src)
return
@@ -319,7 +319,7 @@
owner.set_invis_see(SEE_INVISIBLE_OBSERVER)
return TRUE
/datum/status_effect/cultghost/tick()
/datum/status_effect/cultghost/tick(seconds_between_ticks)
if(owner.reagents)
owner.reagents.del_reagent(/datum/reagent/water/holywater) //can't be deconverted
@@ -359,7 +359,7 @@
/datum/status_effect/stacking/saw_bleed
id = "saw_bleed"
tick_interval = 6
tick_interval = 0.6 SECONDS
delay_before_decay = 5
stack_threshold = 10
max_stacks = 10
@@ -399,7 +399,7 @@
return FALSE
return TRUE
/datum/status_effect/neck_slice/tick()
/datum/status_effect/neck_slice/tick(seconds_between_ticks)
var/obj/item/bodypart/throat = owner.get_bodypart(BODY_ZONE_HEAD)
if(owner.stat == DEAD || !throat) // they can lose their head while it's going.
qdel(src)
@@ -433,8 +433,8 @@
/datum/status_effect/necropolis_curse
id = "necrocurse"
duration = 6000 //you're cursed for 10 minutes have fun
tick_interval = 50
duration = 10 MINUTES //you're cursed for 10 minutes have fun
tick_interval = 5 SECONDS
alert_type = null
var/curse_flags = NONE
var/effect_last_activation = 0
@@ -465,7 +465,7 @@
owner.clear_fullscreen("curse", 50)
curse_flags &= ~remove_curse
/datum/status_effect/necropolis_curse/tick()
/datum/status_effect/necropolis_curse/tick(seconds_between_ticks)
if(owner.stat == DEAD)
return
if(curse_flags & CURSE_WASTING)
@@ -531,7 +531,7 @@
id = "trance"
status_type = STATUS_EFFECT_UNIQUE
duration = 300
tick_interval = 10
tick_interval = 1 SECONDS
var/stun = TRUE
alert_type = /atom/movable/screen/alert/status_effect/trance
@@ -540,7 +540,7 @@
desc = "Everything feels so distant, and you can feel your thoughts forming loops inside your head..."
icon_state = "high"
/datum/status_effect/trance/tick()
/datum/status_effect/trance/tick(seconds_between_ticks)
if(stun)
owner.Stun(6 SECONDS, TRUE)
owner.set_dizzy(40 SECONDS)
@@ -591,7 +591,7 @@
status_type = STATUS_EFFECT_MULTIPLE
alert_type = null
/datum/status_effect/spasms/tick()
/datum/status_effect/spasms/tick(seconds_between_ticks)
if(owner.stat >= UNCONSCIOUS)
return
if(!prob(15))
@@ -653,7 +653,7 @@
. = ..()
to_chat(zappy_boy, span_boldwarning("You feel a shock moving through your body! Your hands start shaking!"))
/datum/status_effect/convulsing/tick()
/datum/status_effect/convulsing/tick(seconds_between_ticks)
var/mob/living/carbon/H = owner
if(prob(40))
var/obj/item/I = H.get_active_held_item()
@@ -696,7 +696,7 @@
id = "go_away"
duration = 100
status_type = STATUS_EFFECT_REPLACE
tick_interval = 1
tick_interval = 0.2 SECONDS
alert_type = /atom/movable/screen/alert/status_effect/go_away
var/direction
@@ -705,7 +705,7 @@
direction = pick(NORTH, SOUTH, EAST, WEST)
new_owner.setDir(direction)
/datum/status_effect/go_away/tick()
/datum/status_effect/go_away/tick(seconds_between_ticks)
owner.AdjustStun(1, ignore_canstun = TRUE)
var/turf/T = get_step(owner, direction)
owner.forceMove(T)
@@ -717,13 +717,13 @@
/datum/status_effect/fake_virus
id = "fake_virus"
duration = 1800//3 minutes
duration = 3 MINUTES //3 minutes
status_type = STATUS_EFFECT_REPLACE
tick_interval = 1
tick_interval = 0.2 SECONDS
alert_type = null
var/msg_stage = 0//so you dont get the most intense messages immediately
/datum/status_effect/fake_virus/tick()
/datum/status_effect/fake_virus/tick(seconds_between_ticks)
var/fake_msg = ""
var/fake_emote = ""
switch(msg_stage)
@@ -813,7 +813,7 @@
/datum/status_effect/ants/get_examine_text()
return span_warning("[owner.p_They()] [owner.p_are()] covered in ants!")
/datum/status_effect/ants/tick()
/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.
if(victim.stat <= SOFT_CRIT) //Makes sure people don't scratch at themselves while they're in a critical condition
@@ -928,9 +928,9 @@
id = "teleport_madness"
duration = 10 SECONDS
status_type = STATUS_EFFECT_REPLACE
tick_interval = 0.1 SECONDS
tick_interval = 0.2 SECONDS
/datum/status_effect/teleport_madness/tick()
/datum/status_effect/teleport_madness/tick(seconds_between_ticks)
dump_in_space(owner)
/datum/status_effect/careful_driving
@@ -24,7 +24,7 @@
qdel(src)
/datum/status_effect/dizziness/tick()
/datum/status_effect/dizziness/tick(seconds_between_ticks)
// How much time is left, in seconds
var/amount = (duration - world.time) / 10
if(amount <= 0)
@@ -34,13 +34,12 @@
// If we're resting, the effect is 5x as strong, but also decays 5x fast.
// Meaning effectively, 1 tick is actually dizziness_strength ticks of duration
var/dizziness_strength = owner.resting ? 5 : 1
var/time_between_ticks = initial(tick_interval)
// How much time will be left, in seconds, next tick
var/next_amount = max((amount - (dizziness_strength * time_between_ticks * 0.1)), 0)
var/next_amount = max((amount - (dizziness_strength * seconds_between_ticks * 0.1)), 0)
// If we have a dizziness strength > 1, we will subtract ticks off of the total duration
if(remove_duration((dizziness_strength - 1) * time_between_ticks))
if(remove_duration((dizziness_strength - 1) * seconds_between_ticks))
return
// Now we can do the actual dizzy effects.
@@ -27,14 +27,14 @@
remove_duration(rand(4 SECONDS, 6 SECONDS))
/datum/status_effect/drowsiness/tick(seconds_per_tick)
/datum/status_effect/drowsiness/tick(seconds_between_ticks)
// You do not feel drowsy while unconscious or in stasis
if(owner.stat >= UNCONSCIOUS || IS_IN_STASIS(owner))
return
// Resting helps against drowsiness
// While resting, we lose 4 seconds of duration (2 additional ticks) per tick
if(owner.resting && remove_duration(2 * initial(tick_interval)))
if(owner.resting && remove_duration(2 * seconds_between_ticks))
return
owner.set_eye_blur_if_lower(4 SECONDS)
+1 -1
View File
@@ -61,7 +61,7 @@
if(drunk_value <= 0)
qdel(src)
/datum/status_effect/inebriated/tick()
/datum/status_effect/inebriated/tick(seconds_between_ticks)
// Drunk value does not decrease while dead or in stasis
if(owner.stat == DEAD || IS_IN_STASIS(owner))
return
@@ -159,7 +159,7 @@
/// Type of mob light emitter we use when on fire
var/moblight_type = /obj/effect/dummy/lighting_obj/moblight/fire
/datum/status_effect/fire_handler/fire_stacks/tick(seconds_per_tick, times_fired)
/datum/status_effect/fire_handler/fire_stacks/tick(seconds_between_ticks)
if(stacks <= 0)
qdel(src)
return TRUE
@@ -167,7 +167,7 @@
if(!on_fire)
return TRUE
adjust_stacks(owner.fire_stack_decay_rate * seconds_per_tick)
adjust_stacks(owner.fire_stack_decay_rate * seconds_between_ticks)
if(stacks <= 0)
qdel(src)
@@ -178,7 +178,7 @@
qdel(src)
return TRUE
deal_damage(seconds_per_tick, times_fired)
deal_damage(seconds_between_ticks)
update_overlay()
update_particles()
@@ -197,13 +197,12 @@
* Proc that handles damage dealing and all special effects
*
* Arguments:
* - seconds_per_tick
* - times_fired
* - seconds_between_ticks
*
*/
/datum/status_effect/fire_handler/fire_stacks/proc/deal_damage(seconds_per_tick, times_fired)
owner.on_fire_stack(seconds_per_tick, times_fired, src)
/datum/status_effect/fire_handler/fire_stacks/proc/deal_damage(seconds_per_tick)
owner.on_fire_stack(seconds_per_tick, src)
var/turf/location = get_turf(owner)
location.hotspot_expose(700, 25 * seconds_per_tick, TRUE)
@@ -212,13 +211,12 @@
* Used to deal damage to humans and count their protection.
*
* Arguments:
* - seconds_per_tick
* - times_fired
* - seconds_between_ticks
* - no_protection: When set to TRUE, fire will ignore any possible fire protection
*
*/
/datum/status_effect/fire_handler/fire_stacks/proc/harm_human(seconds_per_tick, times_fired, no_protection = FALSE)
/datum/status_effect/fire_handler/fire_stacks/proc/harm_human(seconds_per_tick, no_protection = FALSE)
var/mob/living/carbon/human/victim = owner
var/thermal_protection = victim.get_thermal_protection()
@@ -301,8 +299,8 @@
enemy_types = list(/datum/status_effect/fire_handler/fire_stacks)
stack_modifier = -1
/datum/status_effect/fire_handler/wet_stacks/tick(seconds_per_tick)
adjust_stacks(-0.5 * seconds_per_tick)
/datum/status_effect/fire_handler/wet_stacks/tick(seconds_between_ticks)
adjust_stacks(-0.5 * seconds_between_ticks)
if(stacks <= 0)
qdel(src)
@@ -31,17 +31,17 @@
. = ..()
src.total_damage += total_damage
/datum/status_effect/genetic_damage/tick(seconds_per_tick, times_fired)
if(ismonkey(owner) && total_damage >= GORILLA_MUTATION_MINIMUM_DAMAGE && SPT_PROB(GORILLA_MUTATION_CHANCE_PER_SECOND, seconds_per_tick))
/datum/status_effect/genetic_damage/tick(seconds_between_ticks)
if(ismonkey(owner) && total_damage >= GORILLA_MUTATION_MINIMUM_DAMAGE && SPT_PROB(GORILLA_MUTATION_CHANCE_PER_SECOND, seconds_between_ticks))
var/mob/living/carbon/carbon_owner = owner
carbon_owner.gorillize()
qdel(src)
return
if(total_damage >= minimum_before_tox_damage)
owner.adjustToxLoss(toxin_damage_per_second * seconds_per_tick)
owner.adjustToxLoss(toxin_damage_per_second * seconds_between_ticks)
total_damage -= remove_per_second * seconds_per_tick
total_damage -= remove_per_second * seconds_between_ticks
if(total_damage <= 0)
qdel(src)
return
@@ -68,7 +68,7 @@
source.cause_hallucination(/datum/hallucination/shock, "hallucinated shock from [bumped]",)
return STOP_BUMP
/datum/status_effect/hallucination/tick(seconds_per_tick, times_fired)
/datum/status_effect/hallucination/tick(seconds_between_ticks)
if(owner.stat == DEAD)
return
if(!COOLDOWN_FINISHED(src, hallucination_cooldown))
@@ -94,7 +94,7 @@
/datum/status_effect/hallucination/sanity/refresh(...)
update_intervals()
/datum/status_effect/hallucination/sanity/tick(seconds_per_tick, times_fired)
/datum/status_effect/hallucination/sanity/tick(seconds_between_ticks)
// Using psicodine / happiness / whatever to become fearless will stop sanity based hallucinations
if(HAS_TRAIT(owner, TRAIT_FEARLESS))
return
@@ -43,10 +43,10 @@
qdel(src)
/datum/status_effect/jitter/tick()
/datum/status_effect/jitter/tick(seconds_between_ticks)
// Resting helps against jitter
// While resting, we lose 8 seconds of duration (4 additional ticks) per tick
if(owner.resting && remove_duration(4 * initial(tick_interval)))
if(owner.resting && remove_duration(4 * seconds_between_ticks))
return
var/time_left_in_seconds = (duration - world.time) / 10
@@ -31,7 +31,7 @@
var/atom/movable/plane_master_controller/game_plane_master_controller = owner.hud_used.plane_master_controllers[PLANE_MASTERS_GAME]
game_plane_master_controller.remove_filter("eye_blur")
/datum/status_effect/eye_blur/tick(seconds_per_tick, times_fired)
/datum/status_effect/eye_blur/tick(seconds_between_ticks)
// Blur lessens the closer we are to expiring, so we update per tick.
update_blur()
+4 -4
View File
@@ -27,7 +27,7 @@
/// Tracks how long we've been in no gravity
VAR_FINAL/seconds_in_nograv = 0 SECONDS
/datum/status_effect/spacer/gravity_wellness/tick(seconds_per_tick, times_fired)
/datum/status_effect/spacer/gravity_wellness/tick(seconds_between_ticks)
var/in_nograv = !owner.has_gravity()
var/nograv_mod = in_nograv ? 1 : 0.5
owner.adjust_disgust(-1 * disgust_healing_per_tick * nograv_mod)
@@ -36,7 +36,7 @@
seconds_in_nograv = 0 SECONDS
return
seconds_in_nograv += (initial(tick_interval) * 0.1)
seconds_in_nograv += (seconds_between_ticks * 0.1)
if(seconds_in_nograv >= 3 MINUTES)
// This has some interesting side effects with gravitum or similar negating effects that may be worth nothing
@@ -56,12 +56,12 @@
/// Tracks how many seconds this has been active
VAR_FINAL/seconds_active = 0 SECONDS
/datum/status_effect/spacer/gravity_sickness/tick(seconds_per_tick, times_fired)
/datum/status_effect/spacer/gravity_sickness/tick(seconds_between_ticks)
if(owner.mob_negates_gravity())
// Might seem redundant but we can totally be on a planet but have an anti-gravity effect like gravitum
return
seconds_active += (initial(tick_interval) * 0.1)
seconds_active += (seconds_between_ticks * 0.1)
var/mob/living/carbon/the_spacer = owner
the_spacer.adjust_disgust(disgust_per_tick, max = max_disgust + 5)
@@ -38,7 +38,7 @@
UnregisterSignal(owner, COMSIG_CARBON_HELPED)
owner.remove_fov_trait(id, FOV_270_DEGREES)
/datum/status_effect/terrified/tick(seconds_per_tick, times_fired)
/datum/status_effect/terrified/tick(seconds_between_ticks)
if(check_surrounding_darkness())
if(terror_buildup < DARKNESS_TERROR_CAP)
terror_buildup += DARKNESS_TERROR_AMOUNT
@@ -50,14 +50,14 @@
return
if(terror_buildup >= TERROR_FEAR_THRESHOLD) //The onset, minor effects of terror buildup
owner.adjust_dizzy_up_to(10 SECONDS * seconds_per_tick, 10 SECONDS)
owner.adjust_stutter_up_to(10 SECONDS * seconds_per_tick, 10 SECONDS)
owner.adjust_jitter_up_to(10 SECONDS * seconds_per_tick, 10 SECONDS)
owner.adjust_dizzy_up_to(10 SECONDS * seconds_between_ticks, 10 SECONDS)
owner.adjust_stutter_up_to(10 SECONDS * seconds_between_ticks, 10 SECONDS)
owner.adjust_jitter_up_to(10 SECONDS * seconds_between_ticks, 10 SECONDS)
if(terror_buildup >= TERROR_PANIC_THRESHOLD) //If you reach this amount of buildup in an engagement, it's time to start looking for a way out.
owner.playsound_local(get_turf(owner), 'sound/health/slowbeat.ogg', 40, 0, channel = CHANNEL_HEARTBEAT, use_reverb = FALSE)
owner.add_fov_trait(id, FOV_270_DEGREES) //Terror induced tunnel vision
owner.adjust_eye_blur_up_to(10 SECONDS * seconds_per_tick, 10 SECONDS)
owner.adjust_eye_blur_up_to(10 SECONDS * seconds_between_ticks, 10 SECONDS)
if(prob(5)) //We have a little panic attack. Consider it GENTLE ENCOURAGEMENT to start running away.
freak_out(PANIC_ATTACK_TERROR_AMOUNT)
owner.visible_message(
+1 -1
View File
@@ -23,7 +23,7 @@
owner.add_overlay(cube)
/datum/status_effect/freon/tick()
/datum/status_effect/freon/tick(seconds_between_ticks)
if(can_melt && owner.bodytemperature >= owner.get_body_temp_normal())
qdel(src)
+4 -4
View File
@@ -30,7 +30,7 @@
if(!QDELETED(reward_target))
reward_target.get_kill(owner)
/datum/status_effect/syphon_mark/tick()
/datum/status_effect/syphon_mark/tick(seconds_between_ticks)
if(owner.stat == DEAD)
get_kill()
qdel(src)
@@ -96,7 +96,7 @@
playsound(owner, 'sound/weapons/gun/shotgun/rack.ogg', 75, FALSE)
return ..()
/datum/status_effect/bounty/tick()
/datum/status_effect/bounty/tick(seconds_between_ticks)
if(owner.stat == DEAD)
rewards()
qdel(src)
@@ -343,7 +343,7 @@
/datum/status_effect/caltropped
id = "caltropped"
duration = 1 SECONDS
tick_interval = INFINITY
tick_interval = -1
status_type = STATUS_EFFECT_REFRESH
alert_type = null
@@ -374,7 +374,7 @@
QDEL_NULL(alt_clone)
return ..()
/datum/status_effect/eigenstasium/tick()
/datum/status_effect/eigenstasium/tick(seconds_between_ticks)
. = ..()
//This stuff runs every cycle
if(prob(5))
@@ -75,7 +75,7 @@
/datum/status_effect/stacking/proc/can_gain_stacks()
return owner.stat != DEAD
/datum/status_effect/stacking/tick()
/datum/status_effect/stacking/tick(seconds_between_ticks)
if(!can_have_status())
qdel(src)
else
+1 -1
View File
@@ -28,7 +28,7 @@
/datum/status_effect/limp
id = "limp"
status_type = STATUS_EFFECT_REPLACE
tick_interval = 0
tick_interval = -1
alert_type = /atom/movable/screen/alert/status_effect/limp
var/msg_stage = 0//so you dont get the most intense messages immediately
/// The left leg of the limping person
@@ -25,7 +25,7 @@
/datum/status_effect/unholy_determination/on_remove()
owner.remove_traits(list(TRAIT_COAGULATING, TRAIT_NOCRITDAMAGE, TRAIT_NOSOFTCRIT), type)
/datum/status_effect/unholy_determination/tick()
/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)
@@ -33,7 +33,7 @@
/// Simple status effect for adding a ring of fire around a mob.
/datum/status_effect/fire_ring
id = "fire_ring"
tick_interval = 0.1 SECONDS
tick_interval = 0.2 SECONDS
status_type = STATUS_EFFECT_REFRESH
alert_type = null
/// The radius of the ring around us.
@@ -44,7 +44,7 @@
src.ring_radius = radius
return ..()
/datum/status_effect/fire_ring/tick(seconds_per_tick, times_fired)
/datum/status_effect/fire_ring/tick(seconds_between_ticks)
if(QDELETED(owner) || owner.stat == DEAD)
qdel(src)
return
@@ -54,9 +54,9 @@
for(var/turf/nearby_turf as anything in RANGE_TURFS(1, owner))
new /obj/effect/hotspot(nearby_turf)
nearby_turf.hotspot_expose(750, 25 * seconds_per_tick, 1)
nearby_turf.hotspot_expose(750, 25 * seconds_between_ticks, 1)
for(var/mob/living/fried_living in nearby_turf.contents - owner)
fried_living.apply_damage(2.5 * seconds_per_tick, BURN)
fried_living.apply_damage(2.5 * seconds_between_ticks, BURN)
/// Creates one, large, expanding ring of fire around the caster, which does not follow them.
/datum/action/cooldown/spell/fire_cascade
@@ -136,9 +136,9 @@
return TRUE
/datum/status_effect/fire_blasted/tick(seconds_per_tick, times_fired)
owner.adjustFireLoss(tick_damage)
owner.adjustStaminaLoss(2 * tick_damage)
/datum/status_effect/fire_blasted/tick(seconds_between_ticks)
owner.adjustFireLoss(tick_damage * seconds_between_ticks)
owner.adjustStaminaLoss(2 * tick_damage * seconds_between_ticks)
// The beam fireblast spits out, causes people to walk through it to be on fire
/obj/effect/ebeam/fire
@@ -69,7 +69,7 @@
REMOVE_TRAIT(owner, TRAIT_PACIFISM, id)
owner.remove_filter(id)
/datum/status_effect/realignment/tick(seconds_per_tick, times_fired)
/datum/status_effect/realignment/tick(seconds_between_ticks)
owner.adjustStaminaLoss(-5)
owner.AdjustAllImmobility(-0.5 SECONDS)
@@ -114,7 +114,7 @@
/datum/status_effect/cosmic_beam
id = "cosmic_beam"
tick_interval = 0.1 SECONDS
tick_interval = 0.2 SECONDS
duration = 1 MINUTES
status_type = STATUS_EFFECT_REPLACE
alert_type = null
@@ -142,7 +142,7 @@
active = FALSE
return ..()
/datum/status_effect/cosmic_beam/tick(seconds_per_tick, times_fired)
/datum/status_effect/cosmic_beam/tick(seconds_between_ticks)
if(!current_target)
lose_target()
return
@@ -56,7 +56,7 @@
/datum/status_effect/marshal/on_remove()
REMOVE_TRAIT(owner, TRAIT_IGNOREDAMAGESLOWDOWN, STATUS_EFFECT_TRAIT)
/datum/status_effect/marshal/tick()
/datum/status_effect/marshal/tick(seconds_between_ticks)
if(!iscarbon(owner))
return
var/mob/living/carbon/carbie = owner
@@ -22,7 +22,7 @@
owner.remove_atom_colour(TEMPORARY_COLOUR_PRIORITY, COLOR_BLUE_LIGHT)
owner.remove_movespeed_modifier(/datum/movespeed_modifier/void_chill, update = TRUE)
/datum/status_effect/void_chill/tick()
/datum/status_effect/void_chill/tick(seconds_between_ticks)
owner.adjust_bodytemperature(cooling_per_tick * TEMPERATURE_DAMAGE_COEFFICIENT)
/datum/status_effect/void_chill/major
@@ -48,7 +48,7 @@
to_chat(owner, span_boldwarning("You feel filled with a rage that is not your own!"))
return TRUE
/datum/status_effect/amok/tick()
/datum/status_effect/amok/tick(seconds_between_ticks)
var/prev_combat_mode = owner.combat_mode
owner.set_combat_mode(TRUE)
@@ -102,7 +102,7 @@
to_chat(owner, span_userdanger("Your body starts to break apart!"))
return TRUE
/datum/status_effect/corrosion_curse/tick()
/datum/status_effect/corrosion_curse/tick(seconds_between_ticks)
. = ..()
if(!ishuman(owner))
return
+1 -1
View File
@@ -222,7 +222,7 @@
/mob/living/basic/update_stamina()
set_varspeed(initial(speed) + (staminaloss * 0.06))
/mob/living/basic/on_fire_stack(seconds_per_tick, times_fired, datum/status_effect/fire_handler/fire_stacks/fire_handler)
/mob/living/basic/on_fire_stack(seconds_per_tick, datum/status_effect/fire_handler/fire_stacks/fire_handler)
adjust_bodytemperature((maximum_survivable_temperature + (fire_handler.stacks * 12)) * 0.5 * seconds_per_tick)
/mob/living/basic/update_fire_overlay(stacks, on_fire, last_icon_state, suffix = "")
@@ -126,5 +126,5 @@ In all, this is a lot like the monkey code. /N
/mob/living/carbon/alien/acid_act(acidpwr, acid_volume)
return FALSE//aliens are immune to acid.
/mob/living/carbon/alien/on_fire_stack(seconds_per_tick, times_fired, datum/status_effect/fire_handler/fire_stacks/fire_handler)
/mob/living/carbon/alien/on_fire_stack(seconds_per_tick, datum/status_effect/fire_handler/fire_stacks/fire_handler)
adjust_bodytemperature((BODYTEMP_HEATING_MAX + (fire_handler.stacks * 12)) * 0.5 * seconds_per_tick)
@@ -1732,7 +1732,7 @@ GLOBAL_LIST_EMPTY(features_by_species)
// FIRE //
//////////
/datum/species/proc/handle_fire(mob/living/carbon/human/H, seconds_per_tick, times_fired, no_protection = FALSE)
/datum/species/proc/handle_fire(mob/living/carbon/human/H, seconds_per_tick, no_protection = FALSE)
return no_protection
////////////
@@ -867,7 +867,7 @@
*
*/
/mob/living/carbon/human/proc/burn_clothing(seconds_per_tick, times_fired, stacks)
/mob/living/carbon/human/proc/burn_clothing(seconds_per_tick, stacks)
var/list/burning_items = list()
var/obscured = check_obscured_slots(TRUE)
//HEAD//
@@ -914,10 +914,10 @@
for(var/obj/item/burning in burning_items)
burning.fire_act((stacks * 25 * seconds_per_tick)) //damage taken is reduced to 2% of this value by fire_act()
/mob/living/carbon/human/on_fire_stack(seconds_per_tick, times_fired, datum/status_effect/fire_handler/fire_stacks/fire_handler)
/mob/living/carbon/human/on_fire_stack(seconds_per_tick, datum/status_effect/fire_handler/fire_stacks/fire_handler)
SEND_SIGNAL(src, COMSIG_HUMAN_BURNING)
burn_clothing(seconds_per_tick, times_fired, fire_handler.stacks)
burn_clothing(seconds_per_tick, fire_handler.stacks)
var/no_protection = FALSE
if(dna && dna.species)
no_protection = dna.species.handle_fire(src, seconds_per_tick, times_fired, no_protection)
fire_handler.harm_human(seconds_per_tick, times_fired, no_protection)
no_protection = dna.species.handle_fire(src, seconds_per_tick, no_protection)
fire_handler.harm_human(seconds_per_tick, no_protection)
@@ -109,7 +109,7 @@
H.update_fire()
/datum/species/plasmaman/handle_fire(mob/living/carbon/human/H, seconds_per_tick, times_fired, no_protection = FALSE)
/datum/species/plasmaman/handle_fire(mob/living/carbon/human/H, seconds_per_tick, no_protection = FALSE)
if(internal_fire)
no_protection = TRUE
. = ..()
+1 -1
View File
@@ -1658,7 +1658,7 @@ GLOBAL_LIST_EMPTY(fire_appearances)
* * fire_handler: Current fire status effect that called the proc
*/
/mob/living/proc/on_fire_stack(seconds_per_tick, times_fired, datum/status_effect/fire_handler/fire_stacks/fire_handler)
/mob/living/proc/on_fire_stack(seconds_per_tick, datum/status_effect/fire_handler/fire_stacks/fire_handler)
return
//Mobs on Fire end
@@ -65,10 +65,10 @@
/datum/status_effect/seedling_beam_indicator
id = "seedling beam indicator"
duration = 30
duration = 3 SECONDS
status_type = STATUS_EFFECT_MULTIPLE
alert_type = null
tick_interval = 1
tick_interval = 0.2 SECONDS
var/atom/movable/screen/seedling/seedling_screen_object
var/atom/target
@@ -92,7 +92,7 @@
owner.client.screen -= seedling_screen_object
return ..()
/datum/status_effect/seedling_beam_indicator/tick()
/datum/status_effect/seedling_beam_indicator/tick(seconds_between_ticks)
var/target_angle = get_angle(owner, target)
var/matrix/final = matrix()
final.Turn(target_angle)
+2 -2
View File
@@ -303,7 +303,7 @@
id = "psychic_projection"
alert_type = null
remove_on_fullheal = TRUE
tick_interval = 0.1 SECONDS
tick_interval = 0.2 SECONDS
/// Times the target has dry fired a weapon.
var/times_dry_fired = 0
/// Needs to reach times_dry_fired for the next dry fire to happen.
@@ -328,7 +328,7 @@
game_plane_master_controller.remove_filter("psychic_blur")
game_plane_master_controller.remove_filter("psychic_wave")
/datum/status_effect/psychic_projection/tick(seconds_per_tick, times_fired)
/datum/status_effect/psychic_projection/tick(seconds_between_ticks)
var/obj/item/gun/held_gun = owner?.is_holding_item_of_type(/obj/item/gun)
if(!held_gun)
return
@@ -17,7 +17,7 @@
originalcolor = owner.color
return ..()
/datum/status_effect/rainbow_protection/tick()
/datum/status_effect/rainbow_protection/tick(seconds_between_ticks)
owner.color = rgb(rand(0,255),rand(0,255),rand(0,255))
return ..()
@@ -107,7 +107,7 @@
owner.status_flags |= GODMODE
return ..()
/datum/status_effect/frozenstasis/tick()
/datum/status_effect/frozenstasis/tick(seconds_between_ticks)
if(!cube || owner.loc != cube)
owner.remove_status_effect(src)
@@ -145,7 +145,7 @@
clone.apply_status_effect(/datum/status_effect/slime_clone_decay)
return ..()
/datum/status_effect/slime_clone/tick()
/datum/status_effect/slime_clone/tick(seconds_between_ticks)
if(!istype(clone) || clone.stat != CONSCIOUS)
owner.remove_status_effect(src)
@@ -172,7 +172,7 @@
duration = -1
alert_type = /atom/movable/screen/alert/status_effect/clone_decay
/datum/status_effect/slime_clone_decay/tick()
/datum/status_effect/slime_clone_decay/tick(seconds_between_ticks)
owner.adjustToxLoss(1, 0)
owner.adjustOxyLoss(1, 0)
owner.adjustBruteLoss(1, 0)
@@ -193,7 +193,7 @@
owner.add_movespeed_modifier(/datum/movespeed_modifier/status_effect/bloodchill)
return ..()
/datum/status_effect/bloodchill/tick()
/datum/status_effect/bloodchill/tick(seconds_between_ticks)
if(prob(50))
owner.adjustFireLoss(2)
@@ -209,7 +209,7 @@
owner.add_movespeed_modifier(/datum/movespeed_modifier/status_effect/bonechill)
return ..()
/datum/status_effect/bonechill/tick()
/datum/status_effect/bonechill/tick(seconds_between_ticks)
if(prob(50))
owner.adjustFireLoss(1)
owner.set_jitter_if_lower(6 SECONDS)
@@ -230,7 +230,7 @@
duration = -1
alert_type = null
/datum/status_effect/rebreathing/tick()
/datum/status_effect/rebreathing/tick(seconds_between_ticks)
owner.adjustOxyLoss(-6, 0) //Just a bit more than normal breathing.
///////////////////////////////////////////////////////
@@ -261,7 +261,7 @@
ADD_TRAIT(owner, TRAIT_NO_SLIP_WATER,"watercookie")
return ..()
/datum/status_effect/watercookie/tick()
/datum/status_effect/watercookie/tick(seconds_between_ticks)
for(var/turf/open/T in range(get_turf(owner),1))
T.MakeSlippery(TURF_WET_WATER, min_wet_time = 10, wet_time_to_add = 5)
@@ -337,7 +337,7 @@
alert_type = null
duration = 300
/datum/status_effect/lovecookie/tick()
/datum/status_effect/lovecookie/tick(seconds_between_ticks)
if(owner.stat != CONSCIOUS)
return
if(iscarbon(owner))
@@ -358,7 +358,7 @@
alert_type = null
duration = 100
/datum/status_effect/tarcookie/tick()
/datum/status_effect/tarcookie/tick(seconds_between_ticks)
for(var/mob/living/carbon/human/L in range(get_turf(owner),1))
if(L != owner)
L.apply_status_effect(/datum/status_effect/tarfoot)
@@ -397,7 +397,7 @@
alert_type = null
duration = 100
/datum/status_effect/peacecookie/tick()
/datum/status_effect/peacecookie/tick(seconds_between_ticks)
for(var/mob/living/L in range(get_turf(owner),1))
L.apply_status_effect(/datum/status_effect/plur)
@@ -448,7 +448,7 @@
src.linked_extract = linked_extract
return ..()
/datum/status_effect/stabilized/tick()
/datum/status_effect/stabilized/tick(seconds_between_ticks)
if(isnull(linked_extract))
qdel(src)
return
@@ -469,7 +469,7 @@
id = "stabilizedgrey"
colour = "grey"
/datum/status_effect/stabilized/grey/tick()
/datum/status_effect/stabilized/grey/tick(seconds_between_ticks)
for(var/mob/living/simple_animal/slime/S in range(1, get_turf(owner)))
if(!(owner in S.Friends))
to_chat(owner, span_notice("[linked_extract] pulses gently as it communicates with [S]."))
@@ -480,7 +480,7 @@
id = "stabilizedorange"
colour = "orange"
/datum/status_effect/stabilized/orange/tick()
/datum/status_effect/stabilized/orange/tick(seconds_between_ticks)
var/body_temp_target = owner.get_body_temp_normal(apply_change = FALSE)
var/body_temp_actual = owner.bodytemperature
@@ -503,7 +503,7 @@
/// Whether we healed from our last tick
var/healed_last_tick = FALSE
/datum/status_effect/stabilized/purple/tick()
/datum/status_effect/stabilized/purple/tick(seconds_between_ticks)
healed_last_tick = FALSE
if(owner.getBruteLoss() > 0)
@@ -548,7 +548,7 @@
var/cooldown = 30
var/max_cooldown = 30
/datum/status_effect/stabilized/metal/tick()
/datum/status_effect/stabilized/metal/tick(seconds_between_ticks)
if(cooldown > 0)
cooldown--
else
@@ -574,7 +574,7 @@
/datum/status_effect/stabilized/yellow/get_examine_text()
return span_warning("Nearby electronics seem just a little more charged wherever [owner.p_they()] go[owner.p_es()].")
/datum/status_effect/stabilized/yellow/tick()
/datum/status_effect/stabilized/yellow/tick(seconds_between_ticks)
if(cooldown > 0)
cooldown--
return ..()
@@ -606,7 +606,7 @@
fire = new(owner)
return ..()
/datum/status_effect/stabilized/darkpurple/tick()
/datum/status_effect/stabilized/darkpurple/tick(seconds_between_ticks)
var/obj/item/item = owner.get_active_held_item()
if(item)
if(IS_EDIBLE(item) && (item.microwave_act(microwaver = owner) & COMPONENT_MICROWAVE_SUCCESS))
@@ -626,7 +626,7 @@
id = "stabilizeddarkblue"
colour = "dark blue"
/datum/status_effect/stabilized/darkblue/tick()
/datum/status_effect/stabilized/darkblue/tick(seconds_between_ticks)
if(owner.fire_stacks > 0 && prob(80))
owner.adjust_wet_stacks(1)
if(owner.fire_stacks <= 0)
@@ -686,7 +686,7 @@
alert_type = /atom/movable/screen/alert/status_effect/bluespaceslime
var/healthcheck
/datum/status_effect/stabilized/bluespace/tick()
/datum/status_effect/stabilized/bluespace/tick(seconds_between_ticks)
if(owner.has_status_effect(/datum/status_effect/bluespacestabilization))
linked_alert.desc = "The stabilized bluespace extract is still aligning you with the bluespace axis."
linked_alert.icon_state = "slime_bluespace_off"
@@ -715,7 +715,7 @@
colour = "sepia"
var/mod = 0
/datum/status_effect/stabilized/sepia/tick()
/datum/status_effect/stabilized/sepia/tick(seconds_between_ticks)
if(prob(50) && mod > -1)
mod--
owner.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/status_effect/sepia, multiplicative_slowdown = -0.5)
@@ -744,7 +744,7 @@
C.updateappearance(mutcolor_update=1)
return ..()
/datum/status_effect/stabilized/cerulean/tick()
/datum/status_effect/stabilized/cerulean/tick(seconds_between_ticks)
if(owner.stat == DEAD)
if(clone && clone.stat != DEAD)
owner.visible_message(span_warning("[owner] blazes with brilliant light, [linked_extract] whisking [owner.p_their()] soul away."),
@@ -773,7 +773,7 @@
originalcolor = owner.color
return ..()
/datum/status_effect/stabilized/pyrite/tick()
/datum/status_effect/stabilized/pyrite/tick(seconds_between_ticks)
owner.color = rgb(rand(0,255),rand(0,255),rand(0,255))
return ..()
@@ -835,7 +835,7 @@
var/damage = 0
var/lasthealth
/datum/status_effect/pinkdamagetracker/tick()
/datum/status_effect/pinkdamagetracker/tick(seconds_between_ticks)
if((lasthealth - owner.health) > 0)
damage += (lasthealth - owner.health)
lasthealth = owner.health
@@ -854,7 +854,7 @@
to_chat(owner, span_notice("[linked_extract] pulses, generating a fragile aura of peace."))
return ..()
/datum/status_effect/stabilized/pink/tick()
/datum/status_effect/stabilized/pink/tick(seconds_between_ticks)
update_nearby_mobs()
var/has_faction = FALSE
for (var/check_faction in owner.faction)
@@ -916,7 +916,7 @@
id = "stabilizedoil"
colour = "oil"
/datum/status_effect/stabilized/oil/tick()
/datum/status_effect/stabilized/oil/tick(seconds_between_ticks)
if(owner.stat == DEAD)
explosion(owner, devastation_range = 1, heavy_impact_range = 2, light_impact_range = 4, flame_range = 5, explosion_cause = src)
qdel(linked_extract)
@@ -968,7 +968,7 @@
return span_warning("[owner.p_They()] [owner.p_are()] draining health from [draining]!")
/datum/status_effect/stabilized/black/tick()
/datum/status_effect/stabilized/black/tick(seconds_between_ticks)
if(owner.grab_state < GRAB_KILL || !IS_WEAKREF_OF(owner.pulling, draining_ref))
return
@@ -1006,7 +1006,7 @@
ADD_TRAIT(owner, TRAIT_PACIFISM, STABILIZED_LIGHT_PINK_EXTRACT_TRAIT)
return ..()
/datum/status_effect/stabilized/lightpink/tick()
/datum/status_effect/stabilized/lightpink/tick(seconds_between_ticks)
for(var/mob/living/carbon/human/H in range(1, get_turf(owner)))
if(H != owner && H.stat != DEAD && H.health <= 0 && !H.reagents.has_reagent(/datum/reagent/medicine/epinephrine))
to_chat(owner, "[linked_extract] pulses in sync with [H]'s heartbeat, trying to keep [H.p_them()] alive.")
@@ -1029,7 +1029,7 @@
colour = "gold"
var/mob/living/simple_animal/familiar
/datum/status_effect/stabilized/gold/tick()
/datum/status_effect/stabilized/gold/tick(seconds_between_ticks)
var/obj/item/slimecross/stabilized/gold/linked = linked_extract
if(QDELETED(familiar))
familiar = new linked.mob_type(get_turf(owner.loc))
@@ -1068,7 +1068,7 @@
id = "stabilizedrainbow"
colour = "rainbow"
/datum/status_effect/stabilized/rainbow/tick()
/datum/status_effect/stabilized/rainbow/tick(seconds_between_ticks)
if(owner.health <= 0)
var/obj/item/slimecross/stabilized/rainbow/X = linked_extract
if(istype(X))
+2
View File
@@ -102,6 +102,7 @@
#include "blindness.dm"
#include "bloody_footprints.dm"
#include "breath.dm"
#include "burning.dm"
#include "cable_powernets.dm"
#include "card_mismatch.dm"
#include "cardboard_cutouts.dm"
@@ -233,6 +234,7 @@
#include "spritesheets.dm"
#include "stack_singular_name.dm"
#include "station_trait_tests.dm"
#include "status_effect_ticks.dm"
#include "stomach.dm"
#include "strange_reagent.dm"
#include "strippable.dm"
+17
View File
@@ -0,0 +1,17 @@
/// Tests that no runtimes are thrown when a mob is on fire
/datum/unit_test/burning
/datum/unit_test/burning/Run()
var/mob/living/carbon/human/dummy = allocate(/mob/living/carbon/human/consistent)
var/initial_temp = dummy.bodytemperature
// Light this baby up
dummy.set_fire_stacks(20)
dummy.ignite_mob()
TEST_ASSERT(dummy.on_fire, "Dummy is not on fire despite having 20 fire stacks and being ignited.")
// Manually tick it a few times
var/datum/status_effect/fire_handler/fire_stacks/handler = locate() in dummy.status_effects
for(var/i in 1 to 5)
handler.tick_interval = world.time - 1
handler.process()
TEST_ASSERT(dummy.fire_stacks < 20, "Dummy should have decayed firestacks, but did not. (Dummy stacks: [dummy.fire_stacks]).")
TEST_ASSERT(dummy.bodytemperature > initial_temp, "Dummy did not heat up despite being on fire. (Dummy temp: [dummy.bodytemperature], initial temp: [initial_temp])")
@@ -0,0 +1,23 @@
/// Validates status effect tick interval setup
/datum/unit_test/status_effect_ticks
/datum/unit_test/status_effect_ticks/Run()
for(var/datum/status_effect/checking as anything in subtypesof(/datum/status_effect))
var/checking_tick = initial(checking.tick_interval)
if(checking_tick == -1)
continue
if(checking_tick == INFINITY)
TEST_FAIL("Status effect [checking] has tick_interval set to INFINITY, this is not how you prevent ticks - use tick_interval = -1 instead.")
continue
if(checking_tick == 0)
TEST_FAIL("Status effect [checking] has tick_interval set to 0, this is not how you prevent ticks - use tick_interval = -1 instead.")
continue
switch(initial(checking.processing_speed))
if(STATUS_EFFECT_FAST_PROCESS)
if(checking_tick < SSfastprocess.wait)
TEST_FAIL("Status effect [checking] has tick_interval set to [checking_tick], which is faster than SSfastprocess can tick ([SSfastprocess.wait]).")
if(STATUS_EFFECT_NORMAL_PROCESS)
if(checking_tick < SSprocessing.wait)
TEST_FAIL("Status effect [checking] has tick_interval set to [checking_tick], which is faster than SSprocessing can tick ([SSprocessing.wait]).")
else
TEST_FAIL("Invalid processing speed for status effect [checking] : [initial(checking.processing_speed)]")