diff --git a/modular_zubbers/code/modules/customization/species/lycans/lycan_status.dm b/modular_zubbers/code/modules/customization/species/lycans/lycan_status.dm new file mode 100644 index 00000000000..8674359b705 --- /dev/null +++ b/modular_zubbers/code/modules/customization/species/lycans/lycan_status.dm @@ -0,0 +1,134 @@ +#define BEAST_FORM_EXPOSITION_LINK "beast_form_exposition_link" + +/datum/status_effect/beast_form + id = "lycan_beast_form" + alert_type = null // TODO - maybe add an alert?? + var/datum/species/initial_species + +/datum/status_effect/beast_form/on_apply() + . = ..() + if (!.) + return FALSE + + var/mob/living/carbon/human_owner = owner + if (!istype(human_owner)) + return FALSE + + var/obj/item/organ/brain/lycan/lycan_brain = human_owner.get_organ_by_type(/obj/item/organ/brain/lycan) + if (!istype(lycan_brain)) + return FALSE + + initial_species = human_owner.dna.species + + var/datum/species/human/cursekin/current_wolf = human_owner.dna.species + if(!istype(current_wolf)) + return FALSE + + human_owner.visible_message(span_warning("[human_owner] turns [human_owner.p_their()] head to the sky and howls, rapidly growing and transforming into a horrible beast!")) + + var/client/target_client = human_owner.client + if (!isnull(target_client)) + var/name = human_owner.real_name + var/slot = target_client.prefs.read_preference(/datum/preference/numeric/cursekin_char_slot) + var/transfer = TRUE + if (isnull(lycan_brain.last_slot)) + lycan_brain.last_slot = target_client.prefs.savefile.get_entry("default_slot") + target_client.prefs.load_character(slot) + if (!ispath(target_client.prefs.read_preference(/datum.preference/choiced/species), current_wolf.lycanthropy_species)) + to_chat(human_owner, span_warning("Your selected slot is not a lycan! Defaulting to simply changing your species...")) + target_client.prefs.load_character(lycan_brain.last_slot) + human_owner.set_species(current_wolf.lycanthropy_species, TRUE, TRUE, FALSE) + lycan_brain.last_slot = null // allows for easier switching in later procs + transfer = FALSE + + if (transfer) + target_client.prefs.safe_transfer_prefs_to_with_damage(human_owner) + human_owner.real_name = name + human_owner.name = name + SSquirks.OverrideQuirks(human_owner, target_client) + human_owner.dna.update_dna_identity() + + target_client.prefs.load_character(lycan_brain.last_slot) + + ADD_TRAIT(human_owner, TRAIT_BEAST_FORM, SPECIES_TRAIT) + playsound(human_owner, 'modular_zubbers/code/modules/customization/species/lycans/transform.ogg', 50) + +/datum/status_effect/beast_form/on_remove() + . = ..() + + var/mob/living/carbon/human_owner = owner + if (!istype(human_owner)) + return + + var/obj/item/organ/brain/lycan/lycan_brain = human_owner.get_organ_by_type(/obj/item/organ/brain/lycan) + if (!istype(lycan_brain)) + return + + human_owner.visible_message(span_warning("[human_owner] shrinks down, their fur receding!")) + + if (lycan_brain.last_slot) + var/client/target_client = human_owner.client + if (isnull(target_client)) + human_owner.set_species(initial_species, TRUE, TRUE, FALSE) + else + target_client.prefs.load_character(lycan_brain.last_slot) + target_client.prefs.safe_transfer_prefs_to_with_damage(human_owner) + SSquirks.OverrideQuirks(human_owner, target_client) + human_owner.dna.update_dna_identity() + else + human_owner.set_species(initial_species, TRUE, TRUE, FALSE) + + REMOVE_TRAIT(human_owner, TRAIT_BEAST_FORM, SPECIES_TRAIT) + playsound(human_owner, 'modular_zubbers/code/modules/customization/species/lycans/transform.ogg', 50) + +/datum/status_effect/beast_form/tick(seconds_between_ticks) + . = ..() + + var/mob/living/carbon/human_owner = owner + if (!istype(human_owner)) + qdel(src) + return + + if (human_owner.stat >= HARD_CRIT || human_owner.dna.species.id != SPECIES_LYCAN) + qdel(src) + return + +/datum/status_effect/beast_form/get_examine_text() + return span_notice("The NT employee manual has a entry on this species... Recall what you read?") + +/datum/status_effect/beast_form/Topic(href, list/href_list) + . = ..() + + if (href_list[BEAST_FORM_EXPOSITION_LINK]) + print_exposition(usr) + +/datum/status_effect/beast_form/proc/print_exposition(mob/user) + var/list/render_list = list() + + render_list += "Legends of lycanthropy and animalistic shapeshifters have always existed, but were not confirmed until a century ago when the Cursekin species was \ + officially recognized by most polities across the orion arm. The origin for their curse may vary by Cursekin - some from a god, some from genetics - but each \ + has the ability to transform into a terrifying beast with claws like razors." + render_list += "
" + render_list += span_notice("Lycans and related may come in various forms, but each have similarities in how they function.") + render_list += span_notice("\nLycans possess [EXAMINE_HINT("exceptionally strong claws")], about as strong as a [EXAMINE_HINT("circular saw")] without the armor penetration.") + render_list += span_notice("\nLycans also have [EXAMINE_HINT("significant damage resistance")] to brute, and to a lesser extent, burn.") + render_list += span_notice("\nHowever, Lycans [EXAMINE_HINT("cannot wear any clothes")] and cannot have synthetic organs.") + render_list += span_notice("\nAdditionally, each Lycan possesses a [EXAMINE_HINT("marked weakness to silver")], taking [EXAMINE_HINT("increased damage")] from weapons comprised of it.") + render_list += span_notice("\nFinally, Lycans [EXAMINE_HINT("cannot use batons")] nor [EXAMINE_HINT("most firearms")] due to the size of their fingers.") + render_list += span_notice("\nThe Lycan form can be [EXAMINE_HINT("toggled at will")], or [EXAMINE_HINT("forcefully removed")] by [EXAMINE_HINT("knocking them into hard-crit")].") + render_list += "
" + render_list += span_warning("While mostly docile, tamed, and relatively weak, it is rumored that some Lycans harbor a [EXAMINE_HINT("exceptionally capable")] form of the curse. Keep an eye out for any of the following:") + render_list += span_warning("\n * Extremely powerful claws") + render_list += span_warning("\n * Aggressive health regeneration") + render_list += span_warning("\n * Immunity to shoves and resistance to pain/stunning") + render_list += span_warning("\n * The ability to shrug off any amount of pain and keep sprinting") + render_list += span_boldwarning("\nIf you find yourself facing a Lycan with these traits, take these precautions.") + render_list += span_warning("\n * Avoid physical weaponry and stamina weapons - their regeneration rapidly heals brute and stamina drain") + render_list += span_warning("\n * Use silver weaponry - they deal extra burn damage") + render_list += span_warning("\n * Use aerosolized silver - they cannot use internals and will burn on contact with it") + + var/output = jointext(render_list, "") + + to_chat(user, custom_boxed_message("blue_box", output), trailing_newline = FALSE, type = MESSAGE_TYPE_INFO) + +#undef BEAST_FORM_EXPOSITION_LINK diff --git a/modular_zubbers/code/modules/customization/species/lycans/organs/lycan_brain.dm b/modular_zubbers/code/modules/customization/species/lycans/organs/lycan_brain.dm index 2827c232a31..709bb14154d 100644 --- a/modular_zubbers/code/modules/customization/species/lycans/organs/lycan_brain.dm +++ b/modular_zubbers/code/modules/customization/species/lycans/organs/lycan_brain.dm @@ -21,68 +21,19 @@ last_slot = target_client.prefs.savefile.get_entry("default_slot") /obj/item/organ/brain/lycan/proc/enter_beast_form() - var/datum/species/human/cursekin/current_wolf = owner.dna.species - if(!istype(current_wolf) && HAS_TRAIT_FROM(owner, TRAIT_BEAST_FORM, SPECIES_TRAIT)) - return - var/client/target_client = owner.client - if (!isnull(target_client)) - var/name = owner.real_name - var/slot = target_client.prefs.read_preference(/datum/preference/numeric/cursekin_char_slot) - var/transfer = TRUE - if (isnull(last_slot)) - last_slot = target_client.prefs.savefile.get_entry("default_slot") - target_client.prefs.load_character(slot) - if (!ispath(target_client.prefs.read_preference(/datum.preference/choiced/species), current_wolf.lycanthropy_species)) - to_chat(owner, span_warning("Your selected slot is not a lycan! Defaulting to simply changing your species...")) - target_client.prefs.load_character(last_slot) - owner.set_species(current_wolf.lycanthropy_species, TRUE, TRUE, FALSE) - last_slot = null // allows for easier switching in later procs - transfer = FALSE - - if (transfer) - target_client.prefs.safe_transfer_prefs_to_with_damage(owner) - owner.real_name = name - owner.name = name - SSquirks.OverrideQuirks(owner, target_client) - owner.dna.update_dna_identity() - - target_client.prefs.load_character(last_slot) - - ADD_TRAIT(owner, TRAIT_BEAST_FORM, SPECIES_TRAIT) - playsound(owner, 'modular_zubbers/code/modules/customization/species/lycans/transform.ogg', 50) + owner.apply_status_effect(/datum/status_effect/beast_form) /obj/item/organ/brain/lycan/proc/leave_beast_form() - var/datum/species/current_wolf = owner.dna.species - if(isnull(current_wolf) && !HAS_TRAIT_FROM(owner, TRAIT_BEAST_FORM, SPECIES_TRAIT)) - return - owner.visible_message(span_warning("[owner] shrinks down, their fur receding!")) - - if (last_slot) - var/client/target_client = owner.client - if (!isnull(target_client)) - target_client.prefs.load_character(last_slot) - target_client.prefs.safe_transfer_prefs_to_with_damage(owner) - SSquirks.OverrideQuirks(owner, target_client) - owner.dna.update_dna_identity() - else - owner.set_species(/datum/species/human/cursekin, TRUE, TRUE, FALSE) - REMOVE_TRAIT(owner, TRAIT_BEAST_FORM, SPECIES_TRAIT) - playsound(owner, 'modular_zubbers/code/modules/customization/species/lycans/transform.ogg', 50) + owner.remove_status_effect(/datum/status_effect/beast_form) /obj/item/organ/brain/lycan/proc/toggle_beast_form(mob/user) set name = "Enter/Leave Lycan Form" set desc = "Succumb to the rage and turn into a lycan." set category = "Lycan" + if(!user) return - if(!HAS_TRAIT(user, TRAIT_BEAST_FORM)) + if(user.has_status_effect(/datum/status_effect/beast_form)) + leave_beast_form() + else enter_beast_form() - else if(HAS_TRAIT(user, TRAIT_BEAST_FORM)) - leave_beast_form() - -/obj/item/organ/brain/lycan/on_death(seconds_per_tick, times_fired) - . = ..() - if(!owner) - return - if(HAS_TRAIT(owner, TRAIT_BEAST_FORM)) - leave_beast_form() diff --git a/tgstation.dme b/tgstation.dme index f874d399173..96fa82084a1 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -9503,6 +9503,7 @@ #include "modular_zubbers\code\modules\customization\species\lycans\_lycan_species.dm" #include "modular_zubbers\code\modules\customization\species\lycans\cursekin_blacklisted_quirks.dm" #include "modular_zubbers\code\modules\customization\species\lycans\cursekin_prefs.dm" +#include "modular_zubbers\code\modules\customization\species\lycans\lycan_status.dm" #include "modular_zubbers\code\modules\customization\species\lycans\lycan_verbs.dm" #include "modular_zubbers\code\modules\customization\species\lycans\martial_arts.dm" #include "modular_zubbers\code\modules\customization\species\lycans\bodyparts\lycan_bodyparts.dm"