-
Notifications
You must be signed in to change notification settings - Fork 67
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[MODULAR] Oh God The Zipper's Stuck: Entombed quirk granting unremova…
…ble roundstart MODsuit (#656) * Initial pass of Entombed quirk * Fix incorrect preference path * Fix improper preferences path * Add entombed damage processing & toggle prefs for forced no-deploy * Sort tgui imports and use the not broken text input * Simplify toxin damage from entombed and remove fused MODsuit indestructible flag * Handle custom stripping behavior on entombed MODsuits with storage modules * Improve messaging on strip override * Replace CMO modsuit w/ corpsman reskin & add infiltrator entombed skin * Apply suggestions from code review Co-authored-by: Bloop <[email protected]> * Stack trace and qdel on null modsuit in add_unique(), code formatting improvements * Extend equipping quirks to record what items they force-drop, and make Entombed transfer old bag contents into its MODsuit storage * Apply suggestions from code review Co-authored-by: Bloop <[email protected]> * Add foley jitter to the life support failure process (makes it clearer what's killing the user) * Handle dropped force-equipped items qdels gracefully Co-authored-by: Bloop <[email protected]> * Ensure customizations are applied to the entombed MODsuit * Force deployed MODsuits give the no dismember trait, increase max chars on name customization to 48 & remove broken colonist skin * Remove entombed MODsuit activation to post_add() to avoid loadout shenanigans --------- Co-authored-by: Bloop <[email protected]>
- Loading branch information
1 parent
747f07b
commit 047104c
Showing
5 changed files
with
418 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
273 changes: 273 additions & 0 deletions
273
modular_nova/master_files/code/modules/entombed_quirk/code/entombed.dm
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,273 @@ | ||
/// How much damage should we be taking when the suit's been disabled a while? | ||
#define ENTOMBED_TICK_DAMAGE 1.5 | ||
|
||
/datum/quirk/equipping/entombed | ||
name = "Entombed" | ||
desc = "You are permanently fused to (or otherwise reliant on) a single MOD unit that can never be removed from your person. If it runs out of charge or is turned off, you'll start to die!" | ||
gain_text = span_warning("Your exosuit is both prison and home.") | ||
lose_text = span_notice("At last, you're finally free from that horrible exosuit.") | ||
medical_record_text = "Patient is physiologically reliant on a MOD unit for homeostasis. Do not attempt removal." | ||
value = 0 | ||
icon = FA_ICON_ARROW_CIRCLE_DOWN | ||
forced_items = list(/obj/item/mod/control/pre_equipped/entombed = list(ITEM_SLOT_BACK)) | ||
quirk_flags = QUIRK_HUMAN_ONLY | QUIRK_PROCESSES | ||
/// The modsuit we're stuck in | ||
var/obj/item/mod/control/pre_equipped/entombed/modsuit | ||
/// Has the player chosen to deploy-lock? | ||
var/deploy_locked = FALSE | ||
/// How long before they start taking damage when the suit's not active? | ||
var/life_support_failure_threshold = 1.5 MINUTES | ||
/// TimerID for our timeframe tracker | ||
var/life_support_timer | ||
/// Are we taking damage? | ||
var/life_support_failed = FALSE | ||
|
||
/datum/quirk/equipping/entombed/process(seconds_per_tick) | ||
var/mob/living/carbon/human/human_holder = quirk_holder | ||
if (!modsuit || life_support_failed) | ||
// we've got no modsuit or life support. take damage ow | ||
human_holder.adjustToxLoss(ENTOMBED_TICK_DAMAGE * seconds_per_tick, updating_health = TRUE, forced = TRUE) | ||
human_holder.set_jitter_if_lower(10 SECONDS) | ||
|
||
if (!modsuit.active) | ||
if (!life_support_timer) | ||
//start the timer and let the player know | ||
life_support_timer = addtimer(CALLBACK(src, PROC_REF(life_support_failure), human_holder), life_support_failure_threshold, TIMER_STOPPABLE | TIMER_DELETE_ME) | ||
|
||
to_chat(human_holder, span_danger("Your physiology begins to erratically seize and twitch, bereft of your MODsuit's vital support. <b>Turn it back on as soon as you can!</b>")) | ||
human_holder.balloon_alert(human_holder, "suit life support warning!") | ||
human_holder.set_jitter_if_lower(life_support_failure_threshold) //give us some foley jitter | ||
return | ||
else | ||
if (life_support_timer) | ||
// clear our timer and let the player know everything's back to normal | ||
deltimer(life_support_timer) | ||
life_support_timer = null | ||
life_support_failed = FALSE | ||
|
||
to_chat(human_holder, span_notice("Relief floods your frame as your suit begins sustaining your life once more.")) | ||
human_holder.balloon_alert(human_holder, "suit life support restored!") | ||
human_holder.adjust_jitter(-(life_support_failure_threshold / 2)) // clear half of it, wow, that was unpleasant | ||
|
||
/datum/quirk/equipping/entombed/proc/life_support_failure() | ||
// Warn the player and begin the gradual dying process. | ||
var/mob/living/carbon/human/human_holder = quirk_holder | ||
|
||
human_holder.visible_message(span_danger("[human_holder] suddenly staggers, a dire pallor overtaking [human_holder.p_their()] features as a feeble 'breep' emanates from their suit..."), span_userdanger("Terror descends as your suit's life support system breeps feebly, and then goes horrifyingly silent.")) | ||
human_holder.balloon_alert(human_holder, "SUIT LIFE SUPPORT FAILING!") | ||
playsound(human_holder, 'sound/effects/alert.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) // OH GOD THE STRESS NOISE | ||
life_support_failed = TRUE | ||
|
||
/datum/quirk/equipping/entombed/add_unique(client/client_source) | ||
. = ..() | ||
var/mob/living/carbon/human/human_holder = quirk_holder | ||
if (istype(human_holder.back, /obj/item/mod/control/pre_equipped/entombed)) | ||
modsuit = human_holder.back // link this up to the quirk for easy access | ||
|
||
if (isnull(modsuit)) | ||
stack_trace("Entombed quirk couldn't create a fused MODsuit on [quirk_holder] and was force-removed.") | ||
qdel(src) | ||
return | ||
|
||
var/lock_deploy = client_source?.prefs.read_preference(/datum/preference/toggle/entombed_deploy_lock) | ||
if (!isnull(lock_deploy)) | ||
deploy_locked = lock_deploy | ||
|
||
// set no dismember trait for deploy-locked dudes, i'm sorry, there's basically no better way to do this. | ||
// it's a pretty ample buff but i dunno what else to do... | ||
if (deploy_locked) | ||
ADD_TRAIT(human_holder, TRAIT_NODISMEMBER, QUIRK_TRAIT) | ||
|
||
// set all of our customization stuff from prefs, if we have it | ||
var/modsuit_skin = client_source?.prefs.read_preference(/datum/preference/choiced/entombed_skin) | ||
|
||
if (modsuit_skin == NONE) | ||
modsuit_skin = "civilian" | ||
|
||
modsuit.skin = lowertext(modsuit_skin) | ||
|
||
var/modsuit_name = client_source?.prefs.read_preference(/datum/preference/text/entombed_mod_name) | ||
if (modsuit_name) | ||
modsuit.name = modsuit_name | ||
|
||
var/modsuit_desc = client_source?.prefs.read_preference(/datum/preference/text/entombed_mod_desc) | ||
if (modsuit_desc) | ||
modsuit.desc = modsuit_desc | ||
|
||
var/modsuit_skin_prefix = client_source?.prefs.read_preference(/datum/preference/text/entombed_mod_prefix) | ||
if (modsuit_skin_prefix) | ||
modsuit.theme.name = lowertext(modsuit_skin_prefix) | ||
|
||
// ensure we're applying our config theme changes, just in case | ||
for(var/obj/item/part as anything in modsuit.mod_parts) | ||
part.name = "[modsuit.theme.name] [initial(part.name)]" | ||
part.desc = "[initial(part.desc)] [modsuit.theme.desc]" | ||
|
||
install_racial_features() | ||
|
||
//transfer as many items across from our dropped backslot as we can. do this last incase something breaks | ||
if (force_dropped_items) | ||
var/obj/item/old_bag = locate() in force_dropped_items | ||
if (old_bag.atom_storage) | ||
old_bag.atom_storage.dump_content_at(modsuit, human_holder) | ||
|
||
/datum/quirk/equipping/entombed/post_add() | ||
. = ..() | ||
// quickly deploy it on roundstart. we can't do this in add_unique because that gets called in the preview screen, which overwrites people's loadout stuff in suit/shoes/gloves slot. very unfun for them | ||
modsuit.quick_activation() | ||
|
||
/datum/quirk/equipping/entombed/remove() | ||
var/mob/living/carbon/human/human_holder = quirk_holder | ||
if (deploy_locked && HAS_TRAIT_FROM(human_holder, TRAIT_NODISMEMBER, QUIRK_TRAIT)) | ||
REMOVE_TRAIT(human_holder, TRAIT_NODISMEMBER, QUIRK_TRAIT) | ||
QDEL_NULL(modsuit) | ||
|
||
/datum/quirk/equipping/entombed/proc/install_racial_features() | ||
// deploy specific racial features - ethereals get ethereal cores, plasmamen get free plasma stabilizer module | ||
if (!modsuit) // really don't know how this could ever happen but it's better than runtimes | ||
return | ||
var/mob/living/carbon/human/human_holder = quirk_holder | ||
if (isethereal(human_holder)) | ||
var/obj/item/mod/core/ethereal/eth_core = new | ||
eth_core.install(modsuit) | ||
else if (isplasmaman(human_holder)) | ||
var/obj/item/mod/module/plasma_stabilizer/entombed/plasma_stab = new | ||
modsuit.install(plasma_stab, human_holder) | ||
|
||
/datum/quirk_constant_data/entombed | ||
associated_typepath = /datum/quirk/equipping/entombed | ||
customization_options = list( | ||
/datum/preference/choiced/entombed_skin, | ||
/datum/preference/text/entombed_mod_desc, | ||
/datum/preference/text/entombed_mod_name, | ||
/datum/preference/text/entombed_mod_prefix, | ||
/datum/preference/toggle/entombed_deploy_lock, | ||
) | ||
|
||
/datum/preference/choiced/entombed_skin | ||
category = PREFERENCE_CATEGORY_MANUALLY_RENDERED | ||
savefile_key = "entombed_skin" | ||
savefile_identifier = PREFERENCE_CHARACTER | ||
can_randomize = FALSE | ||
|
||
/datum/preference/choiced/entombed_skin/init_possible_values() | ||
return list( | ||
"Standard", | ||
"Civilian", | ||
"Advanced", | ||
"Atmospheric", | ||
"Corpsman", | ||
"Cosmohonk", | ||
"Engineering", | ||
"Infiltrator", | ||
"Interdyne", | ||
"Loader", | ||
"Medical", | ||
"Mining", | ||
"Prototype", | ||
"Security", | ||
) | ||
|
||
/datum/preference/choiced/entombed_skin/create_default_value() | ||
return "Civilian" | ||
|
||
/datum/preference/choiced/entombed_skin/is_accessible(datum/preferences/preferences) | ||
if (!..()) | ||
return FALSE | ||
|
||
return "Entombed" in preferences.all_quirks | ||
|
||
/datum/preference/choiced/entombed_skin/apply_to_human(mob/living/carbon/human/target, value) | ||
return | ||
|
||
/datum/preference/text/entombed_mod_name | ||
category = PREFERENCE_CATEGORY_MANUALLY_RENDERED | ||
savefile_key = "entombed_mod_name" | ||
savefile_identifier = PREFERENCE_CHARACTER | ||
can_randomize = FALSE | ||
maximum_value_length = 48 | ||
|
||
/datum/preference/text/entombed_mod_name/is_accessible(datum/preferences/preferences) | ||
if (!..()) | ||
return FALSE | ||
|
||
return "Entombed" in preferences.all_quirks | ||
|
||
/datum/preference/text/entombed_mod_name/serialize(input) | ||
return htmlrendertext(input) | ||
|
||
/datum/preference/text/entombed_mod_name/deserialize(input, datum/preferences/preferences) | ||
var/sanitized_input = htmlrendertext(input) | ||
if(!isnull(sanitized_input)) | ||
return sanitized_input | ||
else | ||
return "" | ||
|
||
/datum/preference/text/entombed_mod_name/apply_to_human(mob/living/carbon/human/target, value) | ||
return | ||
|
||
/datum/preference/text/entombed_mod_desc | ||
category = PREFERENCE_CATEGORY_MANUALLY_RENDERED | ||
savefile_key = "entombed_mod_desc" | ||
savefile_identifier = PREFERENCE_CHARACTER | ||
can_randomize = FALSE | ||
|
||
/datum/preference/text/entombed_mod_desc/is_accessible(datum/preferences/preferences) | ||
if (!..()) | ||
return FALSE | ||
|
||
return "Entombed" in preferences.all_quirks | ||
|
||
/datum/preference/text/entombed_mod_desc/serialize(input) | ||
return htmlrendertext(input) | ||
|
||
/datum/preference/text/entombed_mod_desc/deserialize(input, datum/preferences/preferences) | ||
var/sanitized_input = htmlrendertext(input) | ||
if(!isnull(sanitized_input)) | ||
return sanitized_input | ||
else | ||
return "" | ||
|
||
/datum/preference/text/entombed_mod_desc/apply_to_human(mob/living/carbon/human/target, value) | ||
return | ||
|
||
/datum/preference/text/entombed_mod_prefix | ||
category = PREFERENCE_CATEGORY_MANUALLY_RENDERED | ||
savefile_key = "entombed_mod_prefix" | ||
savefile_identifier = PREFERENCE_CHARACTER | ||
can_randomize = FALSE | ||
maximum_value_length = 16 | ||
|
||
/datum/preference/text/entombed_mod_prefix/is_accessible(datum/preferences/preferences) | ||
if (!..()) | ||
return FALSE | ||
|
||
return "Entombed" in preferences.all_quirks | ||
|
||
/datum/preference/text/entombed_mod_prefix/serialize(input) | ||
return htmlrendertext(input) | ||
|
||
/datum/preference/text/entombed_mod_prefix/deserialize(input, datum/preferences/preferences) | ||
return htmlrendertext(input) | ||
|
||
/datum/preference/text/entombed_mod_prefix/create_default_value() | ||
return "Fused" | ||
|
||
/datum/preference/text/entombed_mod_prefix/apply_to_human(mob/living/carbon/human/target, value) | ||
return | ||
|
||
/datum/preference/toggle/entombed_deploy_lock | ||
category = PREFERENCE_CATEGORY_MANUALLY_RENDERED | ||
savefile_key = "entombed_deploy_lock" | ||
savefile_identifier = PREFERENCE_CHARACTER | ||
|
||
/datum/preference/toggle/entombed_deploy_lock/is_accessible(datum/preferences/preferences) | ||
if (!..(preferences)) | ||
return FALSE | ||
|
||
return "Entombed" in preferences.all_quirks | ||
|
||
/datum/preference/toggle/entombed_deploy_lock/apply_to_human(mob/living/carbon/human/target, value) | ||
return | ||
|
||
#undef ENTOMBED_TICK_DAMAGE |
95 changes: 95 additions & 0 deletions
95
modular_nova/master_files/code/modules/entombed_quirk/code/entombed_mod.dm
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
/datum/mod_theme/entombed | ||
name = "fused" | ||
desc = "Circumstances have rendered this protective suit into someone's second skin. Literally." | ||
extended_desc = "Some great aspect of someone's past has permanently bound them to this device, for better or worse." | ||
|
||
default_skin = "civilian" | ||
armor_type = /datum/armor/mod_entombed | ||
resistance_flags = FIRE_PROOF | ACID_PROOF // It is better to die for the Emperor than live for yourself. | ||
max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT | ||
siemens_coefficient = 0 | ||
complexity_max = DEFAULT_MAX_COMPLEXITY - 5 | ||
charge_drain = DEFAULT_CHARGE_DRAIN | ||
slowdown_inactive = 2.5 // very slow because the quirk infers you rely on this to move/exist | ||
slowdown_active = 0.95 | ||
inbuilt_modules = list( | ||
/obj/item/mod/module/joint_torsion/entombed, | ||
/obj/item/mod/module/storage, | ||
) | ||
allowed_suit_storage = list( | ||
/obj/item/tank/internals, | ||
/obj/item/flashlight, | ||
) | ||
|
||
/datum/armor/mod_entombed | ||
melee = ARMOR_LEVEL_WEAK | ||
bullet = ARMOR_LEVEL_WEAK | ||
laser = ARMOR_LEVEL_WEAK | ||
energy = ARMOR_LEVEL_WEAK | ||
bomb = ARMOR_LEVEL_WEAK | ||
bio = ARMOR_LEVEL_WEAK | ||
fire = ARMOR_LEVEL_WEAK | ||
acid = ARMOR_LEVEL_WEAK | ||
wound = WOUND_ARMOR_WEAK | ||
|
||
/obj/item/mod/module/joint_torsion/entombed | ||
name = "internal joint torsion adaptation" | ||
desc = "Your adaptation to life in this MODsuit shell allows you to ambulate in such a way that your movements recharge the suit's internal batteries slightly, but only while under the effect of gravity." | ||
removable = FALSE | ||
complexity = 0 | ||
power_per_step = DEFAULT_CHARGE_DRAIN * 0.4 | ||
|
||
/obj/item/mod/module/plasma_stabilizer/entombed | ||
name = "colony-stabilized interior seal" | ||
desc = "Your colony has fully integrated the internal segments of your suit's plate into your skeleton, forming a hermetic seal between you and the outside world from which none of your atmosphere can escape. This is enough to allow your head to view the world with your helmet retracted." | ||
complexity = 0 | ||
idle_power_cost = 0 | ||
removable = FALSE | ||
|
||
/obj/item/mod/control/pre_equipped/entombed | ||
theme = /datum/mod_theme/entombed | ||
applied_cell = /obj/item/stock_parts/cell/high | ||
|
||
/obj/item/mod/control/pre_equipped/entombed/canStrip(mob/who) | ||
return TRUE //you can always try, and it'll hit doStrip below | ||
|
||
/obj/item/mod/control/pre_equipped/entombed/doStrip(mob/who) | ||
// attempt to handle custom stripping behavior - if we have a storage module of some kind | ||
var/obj/item/mod/module/storage/inventory = locate() in src.modules | ||
if (!isnull(inventory)) | ||
src.atom_storage.remove_all() | ||
to_chat(who, span_notice("You empty out all the items from the MODsuit's storage module!")) | ||
who.balloon_alert(who, "emptied out MOD storage items!") | ||
return TRUE | ||
|
||
to_chat(who, span_warning("The suit seems permanently fused to their frame - you can't remove it!")) | ||
who.balloon_alert(who, "can't strip a fused MODsuit!") | ||
return ..() | ||
|
||
/obj/item/mod/control/pre_equipped/entombed/retract(mob/user, obj/item/part) | ||
if (ishuman(user)) | ||
var/mob/living/carbon/human/human_user = user | ||
var/datum/quirk/equipping/entombed/tomb_quirk = human_user.get_quirk(/datum/quirk/equipping/entombed) | ||
//check to make sure we're not retracting something we shouldn't be able to | ||
if (tomb_quirk && tomb_quirk.deploy_locked) | ||
if (istype(part, /obj/item/clothing)) // make sure it's a modsuit piece and not a module, we retract those too | ||
if (!istype(part, /obj/item/clothing/head/mod)) // they can only retract the helmet, them's the sticks | ||
human_user.balloon_alert(human_user, "part is fused to you - can't retract!") | ||
playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) | ||
return | ||
return ..() | ||
|
||
/obj/item/mod/control/pre_equipped/entombed/quick_deploy(mob/user) | ||
if (ishuman(user)) | ||
var/mob/living/carbon/human/human_user = user | ||
var/datum/quirk/equipping/entombed/tomb_quirk = human_user.get_quirk(/datum/quirk/equipping/entombed) | ||
//if we're deploy_locked, just disable this functionality entirely | ||
if (tomb_quirk && tomb_quirk.deploy_locked) | ||
human_user.balloon_alert(human_user, "you can only retract your helmet, and only manually!") | ||
playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) | ||
return | ||
return ..() | ||
|
||
/obj/item/mod/control/pre_equipped/entombed/Initialize(mapload, new_theme, new_skin, new_core) | ||
. = ..() | ||
ADD_TRAIT(src, TRAIT_NODROP, QUIRK_TRAIT) |
Oops, something went wrong.