[MIRROR] Adds a new positive quirk, "Spacer Born". [MDB IGNORE] (#22520)

* Adds a new positive quirk, "Spacer Born".

* Update quirks.dm

* Update quirks.dm

oops

* No combining with oversized quirk

* Update quirks.dm

this is why I don't edit in the web app

* Removes HUMAN_ONLY flag

---------

Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com>
Co-authored-by: Bloop <vinylspiders@gmail.com>
Co-authored-by: Giz <13398309+vinylspiders@users.noreply.github.com>
This commit is contained in:
SkyratBot
2023-07-21 00:57:28 -04:00
committed by GitHub
co-authored by MrMelbert Bloop Giz
parent f031bac85c
commit 032f45f939
14 changed files with 418 additions and 6 deletions
+41
View File
@@ -17,3 +17,44 @@
if(source_loc.z == checking_loc.z)
return TRUE
return FALSE
/**
* Checks if the passed non-area atom is on a "planet".
*
* A planet is defined as anything with planetary atmos that has gravity, with some hardcoded exceptions.
*
* * Nullspace counts as "not a planet", so you may want to check that separately.
* * The mining z-level (Lavaland) is always considered a planet.
* * The station z-level is considered a planet if the map config says so.
* * Central Command is always not a planet.
* * Syndicate recon outpost is always on a planet.
*
* Returns TRUE if we are on a planet.
* Returns FALSE if we are not in a planet, or otherwise, "in space".
*/
/proc/is_on_a_planet(atom/what)
ASSERT(!isarea(what))
var/turf/open/what_turf = get_turf(what)
if(isnull(what_turf))
// Nullspace is, well, not a planet?
return FALSE
if(is_mining_level(what_turf.z))
// Always assume Lavaland / mining level is a planet. (Astroid mining crying right now)
return TRUE
if(is_station_level(what_turf.z))
// Station levels rely on the map config, I.E. Icebox is planetary but Meta is not
return SSmapping.is_planetary()
if(is_centcom_level(what_turf.z))
// Central Command is definitely in space
return FALSE
if(what.onSyndieBase())
// Syndicate recon outpost is on some moon or something
return TRUE
// Finally, more specific checks are ran for edge cases, such as lazyily loaded map templates or away missions. Not perfect.
return istype(what_turf) && what_turf.planetary_atmos && what_turf.has_gravity()
@@ -39,7 +39,8 @@ PROCESSING_SUBSYSTEM_DEF(quirks)
list("Nerve Stapled", "Pacifist"),
list("Nerve Stapled", "Nearsighted"),
list("No Guns", "Big Hands", "Stormtrooper Aim"),
list("No Guns", "Pacifist")
list("No Guns", "Pacifist"),
list("Spacer", "Oversized"),
//SKYRAT EDIT ADDITION END
)
@@ -0,0 +1,199 @@
#define LAST_STATE_PLANET "on_planet"
#define LAST_STATE_SPACE "in_space"
/datum/quirk/spacer_born
name = "Spacer"
desc = "You were born in space, and have never known the comfort of a planet's gravity. Your body has adapted to this. \
You are more comfortable in zero and artifical gravity and are more resistant to the effects of space, \
but travelling to a planet's surface for an extended period of time will make you feel sick."
gain_text = span_notice("You feel at home in space.")
lose_text = span_danger("You feel homesick.")
icon = FA_ICON_USER_ASTRONAUT
value = 7
quirk_flags = QUIRK_CHANGES_APPEARANCE //SKYRAT EDIT CHANGE - ORIGINAL: quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_CHANGES_APPEARANCE
mail_goodies = list(
/obj/item/storage/pill_bottle/ondansetron,
/obj/item/reagent_containers/pill/gravitum,
)
/// How long on a planet before we get averse effects
var/planet_period = 3 MINUTES
/// TimerID for time spend on a planet
VAR_FINAL/planetside_timer
/// How long in space before we get beneficial effects
var/recover_period = 1 MINUTES
/// TimerID for time spend in space
VAR_FINAL/recovering_timer
/// Determines the last state we were in ([LAST_STATE_PLANET] or [LAST_STATE_SPACE])
VAR_FINAL/last_state
/datum/quirk/spacer_born/add(client/client_source)
if(isdummy(quirk_holder))
return
// Using Z moved because we don't urgently need to check on every single turf movement for planetary status.
// If you've arrived at a "planet", the entire Z is gonna be a "planet".
// It won't really make sense to walk 3 feet and then suddenly gain / lose gravity sickness.
// If I'm proven wrong, swap this to use Moved.
RegisterSignal(quirk_holder, COMSIG_MOVABLE_Z_CHANGED, PROC_REF(spacer_moved))
// Yes, it's assumed for planetary maps that you start at gravity sickness.
check_z(quirk_holder, skip_timers = TRUE)
/datum/quirk/spacer_born/add_unique(client/client_source)
// drift slightly faster through zero G
quirk_holder.inertia_move_delay *= 0.8
var/mob/living/carbon/human/human_quirker = quirk_holder
human_quirker.set_mob_height(HUMAN_HEIGHT_TALLER)
human_quirker.physiology.pressure_mod *= 0.8
human_quirker.physiology.cold_mod *= 0.8
/datum/quirk/spacer_born/post_add()
var/on_a_planet = SSmapping.is_planetary()
var/planet_job = istype(quirk_holder.mind?.assigned_role, /datum/job/shaft_miner)
if(!on_a_planet && !planet_job)
return
var/datum/bank_account/spacer_account = quirk_holder.get_bank_account()
if(!isnull(spacer_account))
spacer_account.payday_modifier *= 1.25
to_chat(quirk_holder, span_info("Given your background as a Spacer, \
you are awarded with a 25% hazard pay bonus due to your [on_a_planet ? "station" : "occupational"] assignment."))
// Supply them with some patches to help out on their new assignment
var/obj/item/storage/pill_bottle/ondansetron/disgust_killers = new()
disgust_killers.desc += " Best to take one when travelling to a planet's surface."
if(quirk_holder.equip_to_slot_if_possible(disgust_killers, ITEM_SLOT_BACKPACK, qdel_on_fail = TRUE, initial = TRUE, indirect_action = TRUE))
to_chat(quirk_holder, span_info("You have[isnull(spacer_account) ? " " : " also "]been given some anti-emetic patches to assist in adjusting to planetary gravity."))
/datum/quirk/spacer_born/remove()
UnregisterSignal(quirk_holder, COMSIG_MOVABLE_Z_CHANGED)
if(QDELING(quirk_holder))
return
quirk_holder.inertia_move_delay /= 0.8
quirk_holder.clear_mood_event("spacer")
quirk_holder.remove_movespeed_modifier(/datum/movespeed_modifier/spacer)
quirk_holder.remove_status_effect(/datum/status_effect/spacer)
var/mob/living/carbon/human/human_quirker = quirk_holder
human_quirker.set_mob_height(HUMAN_HEIGHT_MEDIUM)
human_quirker.physiology.pressure_mod /= 0.8
human_quirker.physiology.cold_mod /= 0.8
/// Check on Z change whether we should start or stop timers
/datum/quirk/spacer_born/proc/spacer_moved(mob/living/source, turf/old_turf, turf/new_turf, same_z_layer)
SIGNAL_HANDLER
check_z(source)
/**
* Used to check if we should start or stop timers based on the quirk holder's location.
*
* * afflicted - the mob arriving / same as quirk holder
* * skip_timers - if TRUE, this is being done instantly / should not have feedback (such as in init)
*/
/datum/quirk/spacer_born/proc/check_z(mob/living/spacer, skip_timers = FALSE)
if(is_on_a_planet(spacer))
on_planet(spacer, skip_timers)
else
in_space(spacer, skip_timers)
// Going to a planet
/**
* Ran when we arrive on a planet.
*
* * afflicted - the mob arriving / same as quirk holder
* * skip_timers - if TRUE, this is being done instantly / should not have feedback (such as in init)
*/
/datum/quirk/spacer_born/proc/on_planet(mob/living/afflicted, skip_timers = FALSE)
if(planetside_timer || last_state == LAST_STATE_PLANET)
return
if(recovering_timer)
deltimer(recovering_timer)
recovering_timer = null
last_state = LAST_STATE_PLANET
if(skip_timers)
on_planet_for_too_long(afflicted, TRUE)
return
// Recently exercising lets us last longer under heavy strain
var/exercise_bonus = afflicted.has_status_effect(/datum/status_effect/exercised) ? 2 : 1
planetside_timer = addtimer(CALLBACK(src, PROC_REF(on_planet_for_too_long), afflicted), planet_period * exercise_bonus, TIMER_STOPPABLE)
afflicted.add_mood_event("spacer", /datum/mood_event/spacer/on_planet)
afflicted.add_movespeed_modifier(/datum/movespeed_modifier/spacer/on_planet)
afflicted.remove_status_effect(/datum/status_effect/spacer) // removes the wellness effect.
to_chat(afflicted, span_danger("You feel a bit sick under the gravity here."))
/**
* Ran after remaining on a planet for too long.
*
* * afflicted - the mob arriving / same as quirk holder
* * skip_timers - if TRUE, this is being done instantly / should not have feedback (such as in init)
*/
/datum/quirk/spacer_born/proc/on_planet_for_too_long(mob/living/afflicted, skip_timers = FALSE)
if(QDELETED(src) || QDELETED(afflicted))
return
// Slightly reduced effects if we're on a planetary map to make it a bit more bearable
var/nerfed_effects_because_planetary = SSmapping.is_planetary()
var/moodlet_picked = nerfed_effects_because_planetary ? /datum/mood_event/spacer/on_planet/nerfed : /datum/mood_event/spacer/on_planet/too_long
var/movespeed_mod_picked = nerfed_effects_because_planetary ? /datum/movespeed_modifier/spacer/on_planet/nerfed : /datum/movespeed_modifier/spacer/on_planet/too_long
planetside_timer = null
afflicted.apply_status_effect(/datum/status_effect/spacer/gravity_sickness)
afflicted.add_mood_event("spacer", moodlet_picked)
afflicted.add_movespeed_modifier(movespeed_mod_picked)
if(!skip_timers)
to_chat(afflicted, span_danger("You've been here for too long. The gravity really starts getting to you."))
// Going back into space
/**
* Ran when returning to space / somewhere with low gravity.
*
* * afflicted - the mob arriving / same as quirk holder
* * skip_timers - if TRUE, this is being done instantly / should not have feedback (such as in init)
*/
/datum/quirk/spacer_born/proc/in_space(mob/living/afflicted, skip_timers = FALSE)
if(recovering_timer || last_state == LAST_STATE_SPACE)
return
if(planetside_timer)
deltimer(planetside_timer)
planetside_timer = null
last_state = LAST_STATE_SPACE
if(skip_timers)
comfortably_in_space(afflicted, TRUE)
return
recovering_timer = addtimer(CALLBACK(src, PROC_REF(comfortably_in_space), afflicted), recover_period, TIMER_STOPPABLE)
afflicted.remove_status_effect(/datum/status_effect/spacer)
afflicted.clear_mood_event("spacer")
// Does not remove the movement modifier yet, it lingers until you fully recover
to_chat(afflicted, span_green("You start feeling better now that you're back in space."))
/**
* Ran when living back in space for a long enough period.
*
* * afflicted - the mob arriving / same as quirk holder
* * skip_timers - if TRUE, this is being done instantly / should not have feedback (such as in init)
*/
/datum/quirk/spacer_born/proc/comfortably_in_space(mob/living/afflicted, skip_timers = FALSE)
if(QDELETED(src) || QDELETED(afflicted))
return
recovering_timer = null
afflicted.apply_status_effect(/datum/status_effect/spacer/gravity_wellness)
afflicted.add_mood_event("spacer", /datum/mood_event/spacer/in_space)
afflicted.add_movespeed_modifier(/datum/movespeed_modifier/spacer/in_space)
if(!skip_timers)
to_chat(afflicted, span_green("You feel better."))
#undef LAST_STATE_PLANET
#undef LAST_STATE_SPACE
@@ -0,0 +1,124 @@
// Effects given by the spacer quirk
/datum/status_effect/spacer
id = "spacer_gravity_effects"
status_type = STATUS_EFFECT_REPLACE
/// Essentially, tracks whether this is a planetary map.
/// It'd be pretty miserable if you're playing a planetary map and getting the worse of all effects, so we handwave it a bit.
VAR_FINAL/nerfed_effects_because_planetary = FALSE
/datum/status_effect/spacer/on_apply()
return iscarbon(owner)
/datum/status_effect/spacer/on_creation(mob/living/new_owner, ...)
. = ..()
nerfed_effects_because_planetary = SSmapping.is_planetary()
// The good side (being in space)
/datum/status_effect/spacer/gravity_wellness
alert_type = null
tick_interval = 3 SECONDS
/// How much disgust to heal per tick
var/disgust_healing_per_tick = 1.5
/// How much of stamina damage to heal per tick when we've been in nograv for a while
var/stamina_heal_per_tick = 3
/// How many seconds of stuns to reduce per tick when we've been in nograv for a while
var/stun_heal_per_tick = 3 SECONDS
/// 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)
var/in_nograv = !owner.has_gravity()
var/nograv_mod = in_nograv ? 1 : 0.5
owner.adjust_disgust(-1 * disgust_healing_per_tick * nograv_mod)
if(!in_nograv)
seconds_in_nograv = 0 SECONDS
return
seconds_in_nograv += (initial(tick_interval) * 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
owner.adjustStaminaLoss(-1 * stamina_heal_per_tick)
owner.AdjustAllImmobility(-1 * stun_heal_per_tick)
// For comparison: Ephedrine heals 1 stamina per tick / 0.5 per second
// and Nicotine heals 5 seconds of stun per tick / 2.5 per second
// The bad side (being on a planet)
/datum/status_effect/spacer/gravity_sickness
alert_type = /atom/movable/screen/alert/status_effect/gravity_sickness
tick_interval = 1 SECONDS
/// How much disgust to gain per tick
var/disgust_per_tick = 1
/// The cap to which we can apply disgust
var/max_disgust = DISGUST_LEVEL_GROSS + 5
/// 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)
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)
var/mob/living/carbon/the_spacer = owner
the_spacer.adjust_disgust(disgust_per_tick, max = max_disgust + 5)
if(nerfed_effects_because_planetary)
return
if(seconds_active < 2 MINUTES)
return
var/minutes_active = round(seconds_active / (1 MINUTES))
// Sit at a passive amount of stamina damage depending on how long it's been
if(!the_spacer.getStaminaLoss())
the_spacer.adjustStaminaLoss(min(25, 5 * minutes_active))
// Max disgust increases over time as well
max_disgust = min(DISGUST_LEVEL_VERYGROSS + 5, initial(max_disgust) + 5 * minutes_active)
// And your lungs can't really handle it good
if(!the_spacer.internal && seconds_active % 10 == 0)
the_spacer.losebreath = min(the_spacer.losebreath++, minutes_active, 8)
/atom/movable/screen/alert/status_effect/gravity_sickness
name = "Gravity Sickness"
desc = "The gravity of the planet around you is making you feel sick and tired."
icon_state = "paralysis"
/datum/mood_event/spacer
category = "spacer"
/datum/mood_event/spacer/in_space
description = "Space is long and dark and empty, but it's my home."
/datum/mood_event/spacer/on_planet
description = "I'm on a planet. The gravity here makes me uncomfotable."
mood_change = -2
/datum/mood_event/spacer/on_planet/too_long
description = "I've been on this planet for too long. I need to get back to space."
mood_change = -4
/datum/mood_event/spacer/on_planet/nerfed
description = "I'm stationed on a planet. I'd love to be back in space."
mood_change = -3
/datum/movespeed_modifier/spacer
id = "spacer"
/datum/movespeed_modifier/spacer/in_space
movetypes = FLOATING
blacklisted_movetypes = FLYING
multiplicative_slowdown = -0.1
/datum/movespeed_modifier/spacer/on_planet
movetypes = GROUND|FLYING
blacklisted_movetypes = FLOATING
multiplicative_slowdown = 0.2
/datum/movespeed_modifier/spacer/on_planet/too_long
multiplicative_slowdown = 0.5
/datum/movespeed_modifier/spacer/on_planet/nerfed
multiplicative_slowdown = 0.25
@@ -662,6 +662,14 @@
for(var/i in 1 to 7)
new /obj/item/food/bait/natural(src)
/obj/item/storage/pill_bottle/ondansetron
name = "ondansetron patches"
desc = "A bottle containing patches of ondansetron, a drug used to treat nausea and vomiting. May cause drowsiness."
/obj/item/storage/pill_bottle/ondansetron/PopulateContents()
for(var/i in 1 to 5)
new /obj/item/reagent_containers/pill/patch/ondansetron(src)
/// A box which takes in coolant and uses it to preserve organs and body parts
/obj/item/storage/organbox
name = "organ transport box"
@@ -16,8 +16,8 @@
if(getStaminaLoss() < 162) // Puts you a little further into the initial stamcrit, makes stamcrit harder to outright counter with chems. //SKYRAT EDIT CHANGE
adjustStaminaLoss(30, FALSE)
/mob/living/carbon/adjust_disgust(amount)
disgust = clamp(disgust+amount, 0, DISGUST_LEVEL_MAXEDOUT)
/mob/living/carbon/adjust_disgust(amount, max = DISGUST_LEVEL_MAXEDOUT)
disgust = clamp(disgust + amount, 0, max)
/mob/living/carbon/set_disgust(amount)
disgust = clamp(amount, 0, DISGUST_LEVEL_MAXEDOUT)
@@ -1715,3 +1715,20 @@
required_drink_type = /datum/reagent/medicine/coagulant/seraka_extract
name = "glass of seraka extract"
desc = "Deeply savoury, bitter, and makes your blood clot up in your veins. A great drink, all things considered."
/datum/reagent/medicine/ondansetron
name = "Ondansetron"
description = "Prevents nausea and vomiting. May cause drowsiness and wear."
reagent_state = LIQUID
color = "#74d3ff"
metabolization_rate = 0.5 * REAGENTS_METABOLISM
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)
. = ..()
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)
M.adjust_disgust(-10 * REM * seconds_per_tick)
@@ -385,3 +385,10 @@
results = list(/datum/reagent/consumable/sugar = 1)
required_reagents = list(/datum/reagent/medicine/coagulant/seraka_extract = 1, /datum/reagent/lye = 1)
reaction_tags = REACTION_TAG_EASY
/datum/chemical_reaction/medicine/ondansetron
results = list(/datum/reagent/medicine/ondansetron = 3)
required_reagents = list(/datum/reagent/fuel/oil = 1, /datum/reagent/nitrogen = 1, /datum/reagent/oxygen = 1)
required_catalysts = list(/datum/reagent/consumable/ethanol = 3)
optimal_ph_max = 11
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_HEALING | REACTION_TAG_OTHER | REACTION_TAG_DRUG
@@ -45,6 +45,12 @@
list_reagents = list(/datum/reagent/medicine/c2/synthflesh = 20)
icon_state = "bandaid_both"
/obj/item/reagent_containers/pill/patch/ondansetron
name = "ondansetron patch"
desc = "Alleviates nausea. May cause drowsiness."
list_reagents = list(/datum/reagent/medicine/ondansetron = 10)
icon_state = "bandaid_toxin"
// Patch styles for chem master
/obj/item/reagent_containers/pill/patch/style
@@ -306,6 +306,13 @@
list_reagents = list(/datum/reagent/iron = 30)
rename_with_volume = TRUE
/obj/item/reagent_containers/pill/gravitum
name = "gravitum pill"
desc = "Used in weight loss. In a way."
icon_state = "pill8"
list_reagents = list(/datum/reagent/gravitum = 5)
rename_with_volume = TRUE
// Pill styles for chem master
/obj/item/reagent_containers/pill/style
+5 -3
View File
@@ -1520,9 +1520,10 @@
#include "code\datums\proximity_monitor\fields\projectile_dampener.dm"
#include "code\datums\proximity_monitor\fields\timestop.dm"
#include "code\datums\quirks\_quirk.dm"
#include "code\datums\quirks\negative_quirks.dm"
#include "code\datums\quirks\neutral_quirks.dm"
#include "code\datums\quirks\positive_quirks.dm"
#include "code\datums\quirks\negative_quirks\negative_quirks.dm"
#include "code\datums\quirks\neutral_quirks\neutral_quirks.dm"
#include "code\datums\quirks\positive_quirks\positive_quirks.dm"
#include "code\datums\quirks\positive_quirks\spacer.dm"
#include "code\datums\records\crime.dm"
#include "code\datums\records\data.dm"
#include "code\datums\records\manifest.dm"
@@ -1571,6 +1572,7 @@
#include "code\datums\status_effects\debuffs\screen_blur.dm"
#include "code\datums\status_effects\debuffs\screwy_hud.dm"
#include "code\datums\status_effects\debuffs\silenced.dm"
#include "code\datums\status_effects\debuffs\spacer.dm"
#include "code\datums\status_effects\debuffs\speech_debuffs.dm"
#include "code\datums\status_effects\debuffs\strandling.dm"
#include "code\datums\status_effects\debuffs\terrified.dm"