Files
Bubberstation/code/modules/unit_tests/strange_reagent.dm
Ghom 5409570e01 Upgrades GODMODE from a flag to a trait. (#86596)
## About The Pull Request
GODMODE has a lot of sources that toggle it. From admin-stuff to status
effects, components, actions and mobs which are supposed to be
invincible. It's better off as a trait than a flag, so we can manage
these sources.

## Why It's Good For The Game
See above.

## Changelog

🆑
admin: godmode is now a datum trait instead of a bitflag. This means the
process for toggling it is a little different now.
/🆑
2024-09-15 13:40:19 +00:00

159 lines
6.3 KiB
Plaintext

/// Checks to ensure strange reagent works as expected
/datum/unit_test/strange_reagent
priority = TEST_LONGER
var/datum/reagent/medicine/strange_reagent/instant/strange_reagent
var/target_max_health
var/amount_needed_to_full_heal
var/amount_needed_to_revive
/datum/unit_test/strange_reagent/Run()
strange_reagent = new
var/list/types_to_check = typecacheof(list(
/mob/living/carbon/human/consistent,
/mob/living/simple_animal,
/mob/living/basic,
))
types_to_check -= typesof(/mob/living/simple_animal/hostile/megafauna) // no
types_to_check -= typesof(/mob/living/basic/mouse) // qdel themselves on death; why dont they use DEL_ON_DEATH you might ask. I-unno
types_to_check -= typesof(/mob/living/basic/slime) // if they roll the 50% chance to spawn as an adult, they can just at random split and qdel themselves
for(var/mob/living/type as anything in types_to_check)
var/mob/living/target = allocate_new_target(type)
var/is_basic = istype(target, /mob/living/basic)
var/is_simple = istype(target, /mob/living/simple_animal)
// check some basic stuff
if(HAS_TRAIT(target, TRAIT_GODMODE))
continue
if(!(target.mob_biotypes & MOB_ORGANIC))
continue
if(is_simple)
var/mob/living/simple_animal/simple_animal = target
if(simple_animal.del_on_death)
continue
simple_animal.loot?.Cut()
if(is_basic)
var/mob/living/basic/basic = target
if(basic.basic_mob_flags & DEL_ON_DEATH)
continue
test_damage_but_no_death(type)
test_death_no_damage(type)
test_death_with_damage(type)
test_death_with_damage_but_not_enough_reagent(type)
if(!is_basic && !is_simple) // simple/basic mobs cannot have negative health
test_death_with_full_heal(type)
test_death_from_damage(type)
test_death_from_too_much_damage(type)
// cleanup our vars
QDEL_NULL(strange_reagent)
allocate_new_target(null)
/datum/unit_test/strange_reagent/proc/allocate_new_target(type)
// cache the last one created so that we don't create N instances of the exact same mob
var/static/mob/living/pre_allocated
if(!type)
pre_allocated = null
return
if(pre_allocated?.type == type)
pre_allocated.revive(ALL) // for some reason HEAL_ADMIN doesn't work?
return pre_allocated
pre_allocated = allocate(type)
target_max_health = pre_allocated.getMaxHealth()
update_amounts(pre_allocated)
return pre_allocated
/datum/unit_test/strange_reagent/proc/update_amounts(mob/living/target)
amount_needed_to_full_heal = strange_reagent.calculate_amount_needed_to_full_heal(target)
amount_needed_to_revive = strange_reagent.calculate_amount_needed_to_revive(target)
/datum/unit_test/strange_reagent/proc/damage_target_to_percentage(mob/living/target, percent)
var/damage = target_max_health * percent * 0.5
target.setBruteLoss(damage, updating_health=FALSE) // no point running health update logic here
target.setFireLoss(damage, updating_health=TRUE) // since we do it here
update_amounts(target)
if(percent >= 1)
target.death()
return TRUE
/datum/unit_test/strange_reagent/proc/get_target_organic_health_manual(mob/living/target)
return target.getMaxHealth() - (target.getBruteLoss() + target.getFireLoss())
/datum/unit_test/strange_reagent/proc/test_damage_but_no_death(target_type)
var/mob/living/target = allocate_new_target(target_type)
if(!damage_target_to_percentage(target, 0.8))
return
var/health = get_target_organic_health_manual(target)
strange_reagent.expose_mob(target, INGEST, 20)
TEST_ASSERT_EQUAL(health, get_target_organic_health_manual(target), "Strange Reagent healed a target type [target.type] that was not dead.")
/datum/unit_test/strange_reagent/proc/test_death_no_damage(target_type)
var/mob/living/target = allocate_new_target(target_type)
target.death()
if(QDELETED(target))
return
update_amounts(target)
strange_reagent.expose_mob(target, INGEST, amount_needed_to_revive)
TEST_ASSERT_NOTEQUAL(target.stat, DEAD, "Strange Reagent did not revive a dead target type [target.type].")
/datum/unit_test/strange_reagent/proc/test_death_with_damage(target_type)
var/mob/living/target = allocate_new_target(target_type)
if(!damage_target_to_percentage(target, 0.8))
return
target.death()
if(QDELETED(target))
return
update_amounts(target)
strange_reagent.expose_mob(target, INGEST, amount_needed_to_revive)
TEST_ASSERT_NOTEQUAL(target.stat, DEAD, "Strange Reagent did not revive a dead target type [target.type].")
/datum/unit_test/strange_reagent/proc/test_death_with_damage_but_not_enough_reagent(target_type)
var/mob/living/target = allocate_new_target(target_type)
if(!damage_target_to_percentage(target, 1.2))
return
update_amounts(target)
strange_reagent.expose_mob(target, INGEST, amount_needed_to_revive - 1)
TEST_ASSERT_EQUAL(target.stat, DEAD, "Strange Reagent revived a dead target type [target.type] without enough reagent.")
/datum/unit_test/strange_reagent/proc/test_death_with_full_heal(target_type)
var/mob/living/target = allocate_new_target(target_type)
if(!damage_target_to_percentage(target, 0.8))
return
target.death()
if(QDELETED(target))
return
update_amounts(target)
strange_reagent.expose_mob(target, INGEST, amount_needed_to_full_heal)
TEST_ASSERT_EQUAL(target_max_health, get_target_organic_health_manual(target), "Strange Reagent did not fully heal a dead target type [target.type] with the expected amount.")
/datum/unit_test/strange_reagent/proc/test_death_from_damage(target_type)
var/mob/living/target = allocate_new_target(target_type)
if(!damage_target_to_percentage(target, strange_reagent.max_revive_damage_ratio * 0.9)) // 10% under the damage cap
return
if(QDELETED(target))
return
update_amounts(target)
strange_reagent.expose_mob(target, INGEST, amount_needed_to_revive)
TEST_ASSERT_NOTEQUAL(target.stat, DEAD, "Strange Reagent did not revive a target type [target.type] who died from damage.")
/datum/unit_test/strange_reagent/proc/test_death_from_too_much_damage(target_type)
var/mob/living/target = allocate_new_target(target_type)
if(!damage_target_to_percentage(target, strange_reagent.max_revive_damage_ratio * 1.1)) // 10% over the damage cap
return
if(QDELETED(target))
return
update_amounts(target)
strange_reagent.expose_mob(target, INGEST, amount_needed_to_revive)
TEST_ASSERT_EQUAL(target.stat, DEAD, "Strange Reagent revived a target type [target.type] with more than double their max health in damage.")