From 5b98094ba08394e247e9d0c4e31b427062ecee19 Mon Sep 17 00:00:00 2001 From: Jacquerel Date: Wed, 6 Mar 2024 20:37:05 +0000 Subject: [PATCH 01/33] wow its goku --- code/__DEFINES/mobs.dm | 1 + .../mutant_bodypart_overlay.dm | 1 + code/datums/dna.dm | 6 ++ code/datums/sprite_accessories.dm | 8 +++ .../preferences/species_features/saiyan.dm | 15 ++++ .../carbon/human/species_types/saiyan.dm | 68 ++++++++++++++++++ code/modules/surgery/organs/external/tails.dm | 13 ++++ .../surgery/organs/internal/heart/_heart.dm | 3 + .../mob/human/species/monkey/monkey_tail.dmi | Bin 369 -> 376 bytes tgstation.dme | 2 + 10 files changed, 117 insertions(+) create mode 100644 code/modules/client/preferences/species_features/saiyan.dm create mode 100644 code/modules/mob/living/carbon/human/species_types/saiyan.dm diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index bca8c9002e2..64c4577fc5b 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -133,6 +133,7 @@ #define SPECIES_MUSHROOM "mush" #define SPECIES_PLASMAMAN "plasmaman" #define SPECIES_PODPERSON "pod" +#define SPECIES_SAIYAN "saiyan" #define SPECIES_SHADOW "shadow" #define SPECIES_SKELETON "skeleton" #define SPECIES_SNAIL "snail" diff --git a/code/datums/bodypart_overlays/mutant_bodypart_overlay.dm b/code/datums/bodypart_overlays/mutant_bodypart_overlay.dm index a96a13f991a..f7902c18d88 100644 --- a/code/datums/bodypart_overlays/mutant_bodypart_overlay.dm +++ b/code/datums/bodypart_overlays/mutant_bodypart_overlay.dm @@ -81,6 +81,7 @@ icon_state_builder += mutant_bodyparts_layertext(image_layer) var/finished_icon_state = icon_state_builder.Join("_") + to_chat(world, "icon state [finished_icon_state]") var/mutable_appearance/appearance = mutable_appearance(sprite_datum.icon, finished_icon_state, layer = image_layer) diff --git a/code/datums/dna.dm b/code/datums/dna.dm index a423c7243ae..d1edd29bdd6 100644 --- a/code/datums/dna.dm +++ b/code/datums/dna.dm @@ -248,6 +248,8 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block()) L[DNA_TAIL_BLOCK] = construct_block(SSaccessories.tails_list_felinid.Find(features["tail_cat"]), length(SSaccessories.tails_list_felinid)) if(features["tail_lizard"]) L[DNA_LIZARD_TAIL_BLOCK] = construct_block(SSaccessories.tails_list_lizard.Find(features["tail_lizard"]), length(SSaccessories.tails_list_lizard)) + if(features["tail_saiyan"]) + L[DNA_SAIYAN_TAIL_BLOCK] = construct_block(GLOB.tails_list_human.Find(features["tail_saiyan"]), GLOB.tails_list_human.len) if(features["snout"]) L[DNA_SNOUT_BLOCK] = construct_block(SSaccessories.snouts_list.Find(features["snout"]), length(SSaccessories.snouts_list)) if(features["horns"]) @@ -404,6 +406,8 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block()) set_uni_feature_block(blocknumber, construct_block(SSaccessories.tails_list_felinid.Find(features["tail_cat"]), length(SSaccessories.tails_list_felinid))) if(DNA_LIZARD_TAIL_BLOCK) set_uni_feature_block(blocknumber, construct_block(SSaccessories.tails_list_lizard.Find(features["tail_lizard"]), length(SSaccessories.tails_list_lizard))) + if(DNA_SAIYAN_TAIL_BLOCK) + set_uni_feature_block(blocknumber, construct_block(GLOB.tails_list_human.Find(features["tail_saiyan"]), GLOB.tails_list_saiyan.len)) if(DNA_SNOUT_BLOCK) set_uni_feature_block(blocknumber, construct_block(SSaccessories.snouts_list.Find(features["snout"]), length(SSaccessories.snouts_list))) if(DNA_HORNS_BLOCK) @@ -723,6 +727,8 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block()) dna.features["tail_cat"] = SSaccessories.tails_list_felinid[deconstruct_block(get_uni_feature_block(features, DNA_TAIL_BLOCK), length(SSaccessories.tails_list_felinid))] if(dna.features["tail_lizard"]) dna.features["tail_lizard"] = SSaccessories.tails_list_lizard[deconstruct_block(get_uni_feature_block(features, DNA_LIZARD_TAIL_BLOCK), length(SSaccessories.tails_list_lizard))] + if(dna.features["tail_saiyan"]) + dna.features["tail_saiyan"] = GLOB.tails_list_lizard[deconstruct_block(get_uni_feature_block(features, DNA_SAIYAN_TAIL_BLOCK), GLOB.tails_list_saiyan.len)] if(dna.features["ears"]) dna.features["ears"] = SSaccessories.ears_list[deconstruct_block(get_uni_feature_block(features, DNA_EARS_BLOCK), length(SSaccessories.ears_list))] if(dna.features["moth_wings"]) diff --git a/code/datums/sprite_accessories.dm b/code/datums/sprite_accessories.dm index 50409d51126..132f35a06f9 100644 --- a/code/datums/sprite_accessories.dm +++ b/code/datums/sprite_accessories.dm @@ -1811,6 +1811,14 @@ icon_state = "default" color_src = FALSE +/datum/sprite_accessory/tails/saiyan + icon = 'icons/mob/human/species/monkey/monkey_tail.dmi' + color_src = FALSE + +/datum/sprite_accessory/tails/saiyan/standard + name = "Monkey" + icon_state = "monkey" + /datum/sprite_accessory/pod_hair icon = 'icons/mob/human/species/podperson_hair.dmi' em_block = TRUE diff --git a/code/modules/client/preferences/species_features/saiyan.dm b/code/modules/client/preferences/species_features/saiyan.dm new file mode 100644 index 00000000000..e77222ec815 --- /dev/null +++ b/code/modules/client/preferences/species_features/saiyan.dm @@ -0,0 +1,15 @@ +/datum/preference/choiced/saiyan_tail + savefile_key = "feature_saiyan_tail" + savefile_identifier = PREFERENCE_CHARACTER + category = PREFERENCE_CATEGORY_SECONDARY_FEATURES + relevant_external_organ = /obj/item/organ/external/tail/monkey/saiyan + +/datum/preference/choiced/saiyan_tail/init_possible_values() + return assoc_to_keys_features(GLOB.tails_list_saiyan) + +/datum/preference/choiced/saiyan_tail/apply_to_human(mob/living/carbon/human/target, value) + target.dna.features["tail_saiyan"] = value + +/datum/preference/choiced/saiyan_tail/create_default_value() + var/datum/sprite_accessory/tails/saiyan/tail = /datum/sprite_accessory/tails/saiyan + return initial(tail.name) diff --git a/code/modules/mob/living/carbon/human/species_types/saiyan.dm b/code/modules/mob/living/carbon/human/species_types/saiyan.dm new file mode 100644 index 00000000000..7310ed0c9f0 --- /dev/null +++ b/code/modules/mob/living/carbon/human/species_types/saiyan.dm @@ -0,0 +1,68 @@ +/datum/species/saiyan + name = "\improper Saiyan" + id = SPECIES_SAIYAN + mutantheart = /obj/item/organ/internal/heart/saiyan + payday_modifier = 2.0 + inherent_traits = list( + TRAIT_CATLIKE_GRACE, + TRAIT_CHUNKYFINGERS, + TRAIT_USES_SKINTONES, + ) + changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_PRIDE | MIRROR_MAGIC | RACE_SWAP | ERT_SPAWN | SLIME_EXTRACT + species_language_holder = /datum/language_holder/monkey + + external_organs = list( + /obj/item/organ/external/tail/monkey/saiyan = "Monkey", + ) + +/datum/species/saiyan/check_roundstart_eligible() + return TRUE + // if(check_holidays(APRIL_FOOLS)) + // return TRUE + // return ..() + +/datum/species/saiyan/get_physical_attributes() + return "While they appear superficially similar to humans, Saiyans are universally specimens of toned and perfect health with \ + the honed physique of warriors. They can be distinguished from inferior Human stock by their simian tails, and expressive haircuts." + +/datum/species/saiyan/get_species_description() + return "Martially-inclined space warriors who live for battle and carnage. Have a tendency to lose it when exposed to moonlight." + +/datum/species/saiyan/get_species_lore() + return list( + "Saiyans were once native to the planet Vegeta, which they shared with another species that they annihilated utterly. \ + Saiyans are natural warriors with an instinctive understanding of martial arts and love of violence, \ + their predominant reputation in the galaxy is as conquerors who clear planets of life before selling them to the highest bidder.", + ) + +/datum/species/saiyan/create_pref_unique_perks() + var/list/to_add = list() + + to_add += list( + list( + SPECIES_PERK_TYPE = SPECIES_POSITIVE_PERK, + SPECIES_PERK_ICON = "fist-raised", + SPECIES_PERK_NAME = "Strong", + SPECIES_PERK_DESC = "Saiyans build muscle quickly and easily, and have a natural understanding of fighting unarmed.", + ), + list( + SPECIES_PERK_TYPE = SPECIES_POSITIVE_PERK, + SPECIES_PERK_ICON = "bolt", + SPECIES_PERK_NAME = "Ki Mastery", + SPECIES_PERK_DESC = "Mastery of martial arts grants Saiyans many useful abilities such as the ability to fire Ki Blasts, and flight.", + ), + list( + SPECIES_PERK_TYPE = SPECIES_NEUTRAL_PERK, + SPECIES_PERK_ICON = "moon", + SPECIES_PERK_NAME = "Going Ape", + SPECIES_PERK_DESC = "Saiyans uncontrollably revert into the form of powerful giant apes when exposed to moonlight.", + ), + list( + SPECIES_PERK_TYPE = SPECIES_NEGATIVE_PERK, + SPECIES_PERK_ICON = "warning", + SPECIES_PERK_NAME = "Achilles' Tail", + SPECIES_PERK_DESC = "Saiyans are significantly weakened if their tail is harmed or removed.", + ), + ) + + return to_add diff --git a/code/modules/surgery/organs/external/tails.dm b/code/modules/surgery/organs/external/tails.dm index e6c382387a2..0349e5e6daa 100644 --- a/code/modules/surgery/organs/external/tails.dm +++ b/code/modules/surgery/organs/external/tails.dm @@ -187,6 +187,19 @@ /datum/bodypart_overlay/mutant/tail/monkey/get_global_feature_list() return SSaccessories.tails_list_monkey + +/obj/item/organ/tail/monkey/saiyan + name = "saiyan tail" + desc = "The severed tail of a mighty Saiyan warrior, the ultimate humiliation." + preference = "feature_saiyan_tail" + bodypart_overlay = /datum/bodypart_overlay/mutant/tail/monkey/saiyan + +/datum/bodypart_overlay/mutant/tail/monkey/saiyan + feature_key = "tail_saiyan" + +/datum/bodypart_overlay/mutant/tail/monkey/saiyan/get_global_feature_list() + return GLOB.tails_list_saiyan + /obj/item/organ/tail/lizard name = "lizard tail" desc = "A severed lizard tail. Somewhere, no doubt, a lizard hater is very pleased with themselves." diff --git a/code/modules/surgery/organs/internal/heart/_heart.dm b/code/modules/surgery/organs/internal/heart/_heart.dm index c1ebed9afbf..c695294024e 100644 --- a/code/modules/surgery/organs/internal/heart/_heart.dm +++ b/code/modules/surgery/organs/internal/heart/_heart.dm @@ -302,3 +302,6 @@ owner.heal_overall_damage(brute = 15, burn = 15, required_bodytype = BODYTYPE_ORGANIC) if(owner.reagents.get_reagent_amount(/datum/reagent/medicine/ephedrine) < 20) owner.reagents.add_reagent(/datum/reagent/medicine/ephedrine, 10) + +/obj/item/organ/internal/heart/saiyan + maxHealth = STANDARD_ORGAN_THRESHOLD*0.5 // Vulnerable to heart disease diff --git a/icons/mob/human/species/monkey/monkey_tail.dmi b/icons/mob/human/species/monkey/monkey_tail.dmi index ffebf714f9aa9ae03c3ecbd70ace87c7964ab6b3..5d21803de4263e65ca109dbb54c017520511bcdc 100644 GIT binary patch delta 300 zcmey!^n=N(Gr-TCmrII^fq{Y7)59eQNH>5m6El$97tk32q<8{+LR=3VI55$Jp~9G9 zrZK~uDKC!$#TiS2{DK)Ap4~_Ta{4FwhSlFYdG+w+^RAuU#;TiFNTjfdr$+@QjXA)`#1P38YOS(+(o>*8^`0({ArY;~ z2@gTe~DWM4f5>{sq delta 293 zcmeyt^pVN8Gr-TCmrII^fq{Y7)59eQNGE_W3p0=u*p|f&r1%4TLR=3VI55$Jp~9G9 zrZEGMeaY`AFHnlHB*-tA!Qt7BG$5yIqE}eGovNwsMw8_#_fB3teEGaI?zzdcQj;Ty{>n%5abdb(`bM(j)d;f30J^h_n7~+HGK40S$a%lI49}hP!Xa1|$ z&3e(yUq#oT`)Y-P&E6@?rS`|`GcX*;{u;-6{#MhA;@#nnK?ahaldi8ik)LpThPb>z mq|V#@_n)3-1zP-Lx9|=n*0?2y&Yb}A7(8A5T-G@yGywqG%yGg1 diff --git a/tgstation.dme b/tgstation.dme index 4f1e579be74..745dac51f7b 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -3890,6 +3890,7 @@ #include "code\modules\client\preferences\species_features\mushperson.dm" #include "code\modules\client\preferences\species_features\mutants.dm" #include "code\modules\client\preferences\species_features\pod.dm" +#include "code\modules\client\preferences\species_features\saiyan.dm" #include "code\modules\client\preferences\species_features\vampire.dm" #include "code\modules\client\verbs\ooc.dm" #include "code\modules\client\verbs\ping.dm" @@ -5276,6 +5277,7 @@ #include "code\modules\mob\living\carbon\human\species_types\mushpeople.dm" #include "code\modules\mob\living\carbon\human\species_types\plasmamen.dm" #include "code\modules\mob\living\carbon\human\species_types\podpeople.dm" +#include "code\modules\mob\living\carbon\human\species_types\saiyan.dm" #include "code\modules\mob\living\carbon\human\species_types\shadowpeople.dm" #include "code\modules\mob\living\carbon\human\species_types\skeletons.dm" #include "code\modules\mob\living\carbon\human\species_types\snail.dm" From 878966a9612e95f91b57327265b5ed21a6d38f2e Mon Sep 17 00:00:00 2001 From: Jacquerel Date: Thu, 7 Mar 2024 00:19:42 +0000 Subject: [PATCH 02/33] become ape --- code/__DEFINES/traits/declarations.dm | 2 + .../mutant_bodypart_overlay.dm | 1 - .../basic/farm_animals/gorilla/gorilla.dm | 18 ++++++ .../spell_types/shapeshift/_shape_status.dm | 2 + code/modules/surgery/organs/external/tails.dm | 58 +++++++++++++++++++ 5 files changed, 80 insertions(+), 1 deletion(-) diff --git a/code/__DEFINES/traits/declarations.dm b/code/__DEFINES/traits/declarations.dm index b96fe2025b3..bc47ffe39bf 100644 --- a/code/__DEFINES/traits/declarations.dm +++ b/code/__DEFINES/traits/declarations.dm @@ -89,6 +89,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai /// "Magic" trait that blocks the mob from moving or interacting with anything. Used for transient stuff like mob transformations or incorporality in special cases. /// Will block movement, `Life()` (!!!), and other stuff based on the mob. #define TRAIT_NO_TRANSFORM "block_transformations" +/// I've been turned into something else +#define TRAIT_SHAPESHIFTED "shapeshifted" /// Tracks whether we're gonna be a baby alien's mummy. #define TRAIT_XENO_HOST "xeno_host" /// This parrot is currently perched diff --git a/code/datums/bodypart_overlays/mutant_bodypart_overlay.dm b/code/datums/bodypart_overlays/mutant_bodypart_overlay.dm index f7902c18d88..a96a13f991a 100644 --- a/code/datums/bodypart_overlays/mutant_bodypart_overlay.dm +++ b/code/datums/bodypart_overlays/mutant_bodypart_overlay.dm @@ -81,7 +81,6 @@ icon_state_builder += mutant_bodyparts_layertext(image_layer) var/finished_icon_state = icon_state_builder.Join("_") - to_chat(world, "icon state [finished_icon_state]") var/mutable_appearance/appearance = mutable_appearance(sprite_datum.icon, finished_icon_state, layer = image_layer) diff --git a/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm b/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm index 997447aaa04..095e75dfb5b 100644 --- a/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm +++ b/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm @@ -197,4 +197,22 @@ . = ..() qdel(GetComponent(/datum/component/amputating_limbs)) +/// A terrifyingly powerful ape from space +/mob/living/basic/gorilla/saiyan + name = "Saiyan Great Ape" + desc = "A large and destructive ape-like creature, capable of surviving the depths of space and discharging energy beams." + ai_controller = null + unsuitable_atmos_damage = 0 + unsuitable_cold_damage = 0 + +/mob/living/basic/gorilla/saiyan/Initialize(mapload) + . = ..() + ADD_TRAIT(src, TRAIT_SPACEWALK, INNATE_TRAIT) + AddComponent(\ + /datum/component/ranged_attacks,\ + projectile_type = /obj/projectile/beam/emitter/hitscan,\ + projectile_sound = 'sound/items/weapons/emitter.ogg',\ + cooldown_time = 0.5 SECONDS, \ + ) + #undef GORILLA_HANDS_LAYER diff --git a/code/modules/spells/spell_types/shapeshift/_shape_status.dm b/code/modules/spells/spell_types/shapeshift/_shape_status.dm index a42cd97542c..ff5f6a55024 100644 --- a/code/modules/spells/spell_types/shapeshift/_shape_status.dm +++ b/code/modules/spells/spell_types/shapeshift/_shape_status.dm @@ -30,6 +30,7 @@ return ..() /datum/status_effect/shapechange_mob/on_apply() + ADD_TRAIT(caster_mob, TRAIT_SHAPESHIFTED, REF(src)) caster_mob.mind?.transfer_to(owner) caster_mob.forceMove(owner) ADD_TRAIT(caster_mob, TRAIT_NO_TRANSFORM, REF(src)) @@ -87,6 +88,7 @@ UnregisterSignal(caster_mob, list(COMSIG_QDELETING, COMSIG_LIVING_DEATH)) REMOVE_TRAIT(caster_mob, TRAIT_NO_TRANSFORM, REF(src)) + REMOVE_TRAIT(caster_mob, TRAIT_SHAPESHIFTED, REF(src)) caster_mob.remove_status_effect(/datum/status_effect/grouped/stasis, STASIS_SHAPECHANGE_EFFECT) var/atom/former_loc = owner.loc diff --git a/code/modules/surgery/organs/external/tails.dm b/code/modules/surgery/organs/external/tails.dm index 0349e5e6daa..e758fa07588 100644 --- a/code/modules/surgery/organs/external/tails.dm +++ b/code/modules/surgery/organs/external/tails.dm @@ -194,6 +194,64 @@ preference = "feature_saiyan_tail" bodypart_overlay = /datum/bodypart_overlay/mutant/tail/monkey/saiyan +/obj/item/organ/external/tail/monkey/saiyan/on_mob_insert(mob/living/carbon/organ_owner, special, movement_flags) + . = ..() + var/static/list/loc_connections = list( + COMSIG_MOVABLE_MOVED = PROC_REF(on_moved), + ) + AddComponent(/datum/component/connect_containers, src, loc_connections) + +/obj/item/organ/external/tail/monkey/saiyan/on_mob_remove(mob/living/carbon/organ_owner, special) + . = ..() + qdel(GetComponent(/datum/component/connect_containers)) + +/// When we move check if we are exposed to space +/obj/item/organ/external/tail/monkey/saiyan/proc/on_moved() + SIGNAL_HANDLER + if (isnull(owner)) + return + if (is_space_exposed_turf(get_turf(src))) + go_ape(owner) + else + escape_ape(owner) + +/// Check if the passed turf can see space +/obj/item/organ/external/tail/monkey/saiyan/proc/is_space_exposed_turf(turf/turf_to_check) + if (isnull(turf_to_check)) + return FALSE + var/area/area_to_check = get_area(turf_to_check) + if (isspaceturf(turf_to_check) || area_to_check.outdoors) + return TRUE + var/turf/turf_above = GET_TURF_ABOVE(turf_to_check) + if (!isnull(turf_above) && istransparentturf(turf_above)) + return is_space_exposed_turf(turf_above) + if (!istransparentturf(turf_to_check)) + return FALSE + while (!isnull(turf_to_check) && istransparentturf(turf_to_check)) + turf_to_check = GET_TURF_BELOW(turf_to_check) + return isnull(turf_to_check) || isspaceturf(turf_to_check) + +/// Start being an ape +/obj/item/organ/external/tail/monkey/saiyan/proc/go_ape() + if (HAS_TRAIT(owner, TRAIT_SHAPESHIFTED)) + return + owner.visible_message(span_warning("[owner] transforms into a huge, ape-like creature!")) + var/mob/living/basic/gorilla/saiyan/monkie = new(owner.loc) + monkie.dir = owner.dir + monkie.name = owner.real_name + monkie.real_name = owner.real_name + monkie.apply_status_effect(/datum/status_effect/shapechange_mob, owner) + +/// Stop being an ape +/obj/item/organ/external/tail/monkey/saiyan/proc/escape_ape() + if (!HAS_TRAIT(owner, TRAIT_SHAPESHIFTED)) + return + var/mob/living/ape_form = owner.loc + if (!istype(ape_form)) + return // Uh oh + owner.visible_message(span_warning("[owner] returns to [owner.p_their()] normal form.")) + ape_form.remove_status_effect(/datum/status_effect/shapechange_mob) + /datum/bodypart_overlay/mutant/tail/monkey/saiyan feature_key = "tail_saiyan" From 6ac3177a918e4da114ae600904d794620b627682 Mon Sep 17 00:00:00 2001 From: Jacquerel Date: Thu, 7 Mar 2024 01:03:52 +0000 Subject: [PATCH 03/33] Remove some stuff I didn't need actually, organ placeholders --- code/datums/dna.dm | 6 ------ code/modules/mob/living/brain/brain_item.dm | 6 +++++- .../carbon/human/species_types/saiyan.dm | 20 ++++++++++++++++++- code/modules/surgery/organs/external/tails.dm | 1 - .../organs/internal/stomach/_stomach.dm | 5 +++++ tgstation.dme | 1 - 6 files changed, 29 insertions(+), 10 deletions(-) diff --git a/code/datums/dna.dm b/code/datums/dna.dm index d1edd29bdd6..a423c7243ae 100644 --- a/code/datums/dna.dm +++ b/code/datums/dna.dm @@ -248,8 +248,6 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block()) L[DNA_TAIL_BLOCK] = construct_block(SSaccessories.tails_list_felinid.Find(features["tail_cat"]), length(SSaccessories.tails_list_felinid)) if(features["tail_lizard"]) L[DNA_LIZARD_TAIL_BLOCK] = construct_block(SSaccessories.tails_list_lizard.Find(features["tail_lizard"]), length(SSaccessories.tails_list_lizard)) - if(features["tail_saiyan"]) - L[DNA_SAIYAN_TAIL_BLOCK] = construct_block(GLOB.tails_list_human.Find(features["tail_saiyan"]), GLOB.tails_list_human.len) if(features["snout"]) L[DNA_SNOUT_BLOCK] = construct_block(SSaccessories.snouts_list.Find(features["snout"]), length(SSaccessories.snouts_list)) if(features["horns"]) @@ -406,8 +404,6 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block()) set_uni_feature_block(blocknumber, construct_block(SSaccessories.tails_list_felinid.Find(features["tail_cat"]), length(SSaccessories.tails_list_felinid))) if(DNA_LIZARD_TAIL_BLOCK) set_uni_feature_block(blocknumber, construct_block(SSaccessories.tails_list_lizard.Find(features["tail_lizard"]), length(SSaccessories.tails_list_lizard))) - if(DNA_SAIYAN_TAIL_BLOCK) - set_uni_feature_block(blocknumber, construct_block(GLOB.tails_list_human.Find(features["tail_saiyan"]), GLOB.tails_list_saiyan.len)) if(DNA_SNOUT_BLOCK) set_uni_feature_block(blocknumber, construct_block(SSaccessories.snouts_list.Find(features["snout"]), length(SSaccessories.snouts_list))) if(DNA_HORNS_BLOCK) @@ -727,8 +723,6 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block()) dna.features["tail_cat"] = SSaccessories.tails_list_felinid[deconstruct_block(get_uni_feature_block(features, DNA_TAIL_BLOCK), length(SSaccessories.tails_list_felinid))] if(dna.features["tail_lizard"]) dna.features["tail_lizard"] = SSaccessories.tails_list_lizard[deconstruct_block(get_uni_feature_block(features, DNA_LIZARD_TAIL_BLOCK), length(SSaccessories.tails_list_lizard))] - if(dna.features["tail_saiyan"]) - dna.features["tail_saiyan"] = GLOB.tails_list_lizard[deconstruct_block(get_uni_feature_block(features, DNA_SAIYAN_TAIL_BLOCK), GLOB.tails_list_saiyan.len)] if(dna.features["ears"]) dna.features["ears"] = SSaccessories.ears_list[deconstruct_block(get_uni_feature_block(features, DNA_EARS_BLOCK), length(SSaccessories.ears_list))] if(dna.features["moth_wings"]) diff --git a/code/modules/mob/living/brain/brain_item.dm b/code/modules/mob/living/brain/brain_item.dm index 9daa88a51a3..910a8cc2ebe 100644 --- a/code/modules/mob/living/brain/brain_item.dm +++ b/code/modules/mob/living/brain/brain_item.dm @@ -462,7 +462,11 @@ /obj/item/organ/brain/lustrous/on_mob_insert(mob/living/carbon/organ_owner, special, movement_flags) . = ..() organ_owner.gain_trauma(/datum/brain_trauma/special/bluespace_prophet, TRAUMA_RESILIENCE_ABSOLUTE) - organ_owner.AddElement(/datum/element/tenacious) + +/obj/item/organ/brain/saiyan + name = "saiyan brain" + desc = "The brain of a mighty saiyan warrior. Guess they don't work out at the library..." + brain_size = 0.5 /obj/item/organ/brain/felinid //A bit smaller than average brain_size = 0.8 diff --git a/code/modules/mob/living/carbon/human/species_types/saiyan.dm b/code/modules/mob/living/carbon/human/species_types/saiyan.dm index 7310ed0c9f0..2bd40026d42 100644 --- a/code/modules/mob/living/carbon/human/species_types/saiyan.dm +++ b/code/modules/mob/living/carbon/human/species_types/saiyan.dm @@ -1,7 +1,9 @@ /datum/species/saiyan name = "\improper Saiyan" id = SPECIES_SAIYAN + mutantbrain = /obj/item/organ/internal/brain/saiyan mutantheart = /obj/item/organ/internal/heart/saiyan + mutantstomach = /obj/item/organ/internal/stomach/saiyan payday_modifier = 2.0 inherent_traits = list( TRAIT_CATLIKE_GRACE, @@ -9,12 +11,16 @@ TRAIT_USES_SKINTONES, ) changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_PRIDE | MIRROR_MAGIC | RACE_SWAP | ERT_SPAWN | SLIME_EXTRACT - species_language_holder = /datum/language_holder/monkey + species_language_holder = /datum/language_holder/clown external_organs = list( /obj/item/organ/external/tail/monkey/saiyan = "Monkey", ) +/datum/species/saiyan/prepare_human_for_preview(mob/living/carbon/human/human) + human.set_haircolor("#292929", update = FALSE) + human.set_hairstyle("Spiky 2", update = TRUE) + /datum/species/saiyan/check_roundstart_eligible() return TRUE // if(check_holidays(APRIL_FOOLS)) @@ -51,6 +57,12 @@ SPECIES_PERK_NAME = "Ki Mastery", SPECIES_PERK_DESC = "Mastery of martial arts grants Saiyans many useful abilities such as the ability to fire Ki Blasts, and flight.", ), + list( + SPECIES_PERK_TYPE = SPECIES_POSITIVE_PERK, + SPECIES_PERK_ICON = "first-aid", + SPECIES_PERK_NAME = "Full Throttle", + SPECIES_PERK_DESC = "A Saiyan who recovers from grievous injury (but not death) often becomes more powerful.", + ), list( SPECIES_PERK_TYPE = SPECIES_NEUTRAL_PERK, SPECIES_PERK_ICON = "moon", @@ -63,6 +75,12 @@ SPECIES_PERK_NAME = "Achilles' Tail", SPECIES_PERK_DESC = "Saiyans are significantly weakened if their tail is harmed or removed.", ), + list( + SPECIES_PERK_TYPE = SPECIES_NEGATIVE_PERK, + SPECIES_PERK_ICON = "bowl-rice", + SPECIES_PERK_NAME = "Warrior's Appetite", + SPECIES_PERK_DESC = "Maintaining fighting fitness sure makes you awfully hungry.", + ), ) return to_add diff --git a/code/modules/surgery/organs/external/tails.dm b/code/modules/surgery/organs/external/tails.dm index e758fa07588..329d8d58bd7 100644 --- a/code/modules/surgery/organs/external/tails.dm +++ b/code/modules/surgery/organs/external/tails.dm @@ -191,7 +191,6 @@ /obj/item/organ/tail/monkey/saiyan name = "saiyan tail" desc = "The severed tail of a mighty Saiyan warrior, the ultimate humiliation." - preference = "feature_saiyan_tail" bodypart_overlay = /datum/bodypart_overlay/mutant/tail/monkey/saiyan /obj/item/organ/external/tail/monkey/saiyan/on_mob_insert(mob/living/carbon/organ_owner, special, movement_flags) diff --git a/code/modules/surgery/organs/internal/stomach/_stomach.dm b/code/modules/surgery/organs/internal/stomach/_stomach.dm index 40d3265684d..49704688316 100644 --- a/code/modules/surgery/organs/internal/stomach/_stomach.dm +++ b/code/modules/surgery/organs/internal/stomach/_stomach.dm @@ -325,4 +325,9 @@ . = ..() AddElement(/datum/element/dangerous_organ_removal, /*surgical = */ TRUE) +/obj/item/organ/internal/stomach/saiyan + disgust_metabolism = 2 + hunger_modifier = 3 + desc = "The Saiyan stomach can handle a wide range of foods, but burns it fast to power their energetic lifestyle." + #undef STOMACH_METABOLISM_CONSTANT diff --git a/tgstation.dme b/tgstation.dme index 745dac51f7b..937e28e3150 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -3890,7 +3890,6 @@ #include "code\modules\client\preferences\species_features\mushperson.dm" #include "code\modules\client\preferences\species_features\mutants.dm" #include "code\modules\client\preferences\species_features\pod.dm" -#include "code\modules\client\preferences\species_features\saiyan.dm" #include "code\modules\client\preferences\species_features\vampire.dm" #include "code\modules\client\verbs\ooc.dm" #include "code\modules\client\verbs\ping.dm" From e89ea969b9a7261dd58c0fd12e38b94095813102 Mon Sep 17 00:00:00 2001 From: Jacquerel Date: Thu, 7 Mar 2024 01:35:16 +0000 Subject: [PATCH 04/33] don't need this either --- .../client/preferences/species_features/saiyan.dm | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 code/modules/client/preferences/species_features/saiyan.dm diff --git a/code/modules/client/preferences/species_features/saiyan.dm b/code/modules/client/preferences/species_features/saiyan.dm deleted file mode 100644 index e77222ec815..00000000000 --- a/code/modules/client/preferences/species_features/saiyan.dm +++ /dev/null @@ -1,15 +0,0 @@ -/datum/preference/choiced/saiyan_tail - savefile_key = "feature_saiyan_tail" - savefile_identifier = PREFERENCE_CHARACTER - category = PREFERENCE_CATEGORY_SECONDARY_FEATURES - relevant_external_organ = /obj/item/organ/external/tail/monkey/saiyan - -/datum/preference/choiced/saiyan_tail/init_possible_values() - return assoc_to_keys_features(GLOB.tails_list_saiyan) - -/datum/preference/choiced/saiyan_tail/apply_to_human(mob/living/carbon/human/target, value) - target.dna.features["tail_saiyan"] = value - -/datum/preference/choiced/saiyan_tail/create_default_value() - var/datum/sprite_accessory/tails/saiyan/tail = /datum/sprite_accessory/tails/saiyan - return initial(tail.name) From fc9f718548394d446ea66eff3a9045a86f72fb86 Mon Sep 17 00:00:00 2001 From: Jacquerel Date: Tue, 12 Mar 2024 01:35:36 +0000 Subject: [PATCH 05/33] miracle zenkai power --- code/__DEFINES/traits/declarations.dm | 2 + .../carbon/human/species_types/saiyan.dm | 14 ++++ .../species_parts/saiyan_bodyparts.dm | 53 +++++++++++++++ code/modules/surgery/organs/external/tails.dm | 3 + .../surgery/organs/internal/heart/_heart.dm | 3 - .../organs/internal/heart/heart_saiyan.dm | 64 +++++++++++++++++++ tgstation.dme | 2 + 7 files changed, 138 insertions(+), 3 deletions(-) create mode 100644 code/modules/surgery/bodyparts/species_parts/saiyan_bodyparts.dm create mode 100644 code/modules/surgery/organs/internal/heart/heart_saiyan.dm diff --git a/code/__DEFINES/traits/declarations.dm b/code/__DEFINES/traits/declarations.dm index bc47ffe39bf..62df14aec84 100644 --- a/code/__DEFINES/traits/declarations.dm +++ b/code/__DEFINES/traits/declarations.dm @@ -864,6 +864,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_CONTRABAND_BLOCKER "contraband_blocker" /// For edible items that cannot be composted inside hydro trays #define TRAIT_UNCOMPOSTABLE "uncompostable" +/// limbs with this trait can be empowered by a saiyan heart +#define TRAIT_SAIYAN_STRENGTH "saiyan_strength" //quirk traits #define TRAIT_ALCOHOL_TOLERANCE "alcohol_tolerance" diff --git a/code/modules/mob/living/carbon/human/species_types/saiyan.dm b/code/modules/mob/living/carbon/human/species_types/saiyan.dm index 2bd40026d42..ba7ad24e758 100644 --- a/code/modules/mob/living/carbon/human/species_types/saiyan.dm +++ b/code/modules/mob/living/carbon/human/species_types/saiyan.dm @@ -13,6 +13,14 @@ changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_PRIDE | MIRROR_MAGIC | RACE_SWAP | ERT_SPAWN | SLIME_EXTRACT species_language_holder = /datum/language_holder/clown + bodypart_overrides = list( + BODY_ZONE_HEAD = /obj/item/bodypart/head/saiyan, + BODY_ZONE_CHEST = /obj/item/bodypart/chest/saiyan, + BODY_ZONE_L_ARM = /obj/item/bodypart/arm/left/saiyan, + BODY_ZONE_R_ARM = /obj/item/bodypart/arm/right/saiyan, + BODY_ZONE_L_LEG = /obj/item/bodypart/leg/left/saiyan, + BODY_ZONE_R_LEG = /obj/item/bodypart/leg/right/saiyan, + ) external_organs = list( /obj/item/organ/external/tail/monkey/saiyan = "Monkey", ) @@ -81,6 +89,12 @@ SPECIES_PERK_NAME = "Warrior's Appetite", SPECIES_PERK_DESC = "Maintaining fighting fitness sure makes you awfully hungry.", ), + list( + SPECIES_PERK_TYPE = SPECIES_NEGATIVE_PERK, + SPECIES_PERK_ICON = "paw", + SPECIES_PERK_NAME = "Melee Fixation", + SPECIES_PERK_DESC = "Saiyans mostly disavow the use of projectile weaponry on the grounds of honour, although some say it's simply that their big hands mean that they're not very good at using it.", + ), ) return to_add diff --git a/code/modules/surgery/bodyparts/species_parts/saiyan_bodyparts.dm b/code/modules/surgery/bodyparts/species_parts/saiyan_bodyparts.dm new file mode 100644 index 00000000000..ae02905d070 --- /dev/null +++ b/code/modules/surgery/bodyparts/species_parts/saiyan_bodyparts.dm @@ -0,0 +1,53 @@ +/obj/item/bodypart/head/saiyan + unarmed_damage_low = 5 + unarmed_damage_high = 7 + unarmed_effectiveness = 15 + +/obj/item/bodypart/head/saiyan/Initialize(mapload) + . = ..() + ADD_TRAIT(src, TRAIT_SAIYAN_STRENGTH, INNATE_TRAIT) + +/obj/item/bodypart/chest/saiyan + unarmed_damage_low = 5 // Good luck actually dealing damage with your chest + unarmed_damage_high = 7 + unarmed_effectiveness = 15 + +/obj/item/bodypart/chest/saiyan/Initialize(mapload) + . = ..() + ADD_TRAIT(src, TRAIT_SAIYAN_STRENGTH, INNATE_TRAIT) + +/obj/item/bodypart/arm/left/saiyan + unarmed_damage_low = 8 + unarmed_damage_high = 12 + unarmed_effectiveness = 15 + +/obj/item/bodypart/arm/left/saiyan/Initialize(mapload) + . = ..() + ADD_TRAIT(src, TRAIT_SAIYAN_STRENGTH, INNATE_TRAIT) + +/obj/item/bodypart/arm/right/saiyan + unarmed_damage_low = 8 + unarmed_damage_high = 12 + unarmed_effectiveness = 15 + +/obj/item/bodypart/arm/right/saiyan/Initialize(mapload) + . = ..() + ADD_TRAIT(src, TRAIT_SAIYAN_STRENGTH, INNATE_TRAIT) + +/obj/item/bodypart/leg/left/saiyan + unarmed_damage_low = 12 + unarmed_damage_high = 18 + unarmed_effectiveness = 15 + +/obj/item/bodypart/leg/left/saiyan/Initialize(mapload) + . = ..() + ADD_TRAIT(src, TRAIT_SAIYAN_STRENGTH, INNATE_TRAIT) + +/obj/item/bodypart/leg/right/saiyan + unarmed_damage_low = 12 + unarmed_damage_high = 18 + unarmed_effectiveness = 15 + +/obj/item/bodypart/leg/right/saiyan/Initialize(mapload) + . = ..() + ADD_TRAIT(src, TRAIT_SAIYAN_STRENGTH, INNATE_TRAIT) diff --git a/code/modules/surgery/organs/external/tails.dm b/code/modules/surgery/organs/external/tails.dm index 329d8d58bd7..87b8672d932 100644 --- a/code/modules/surgery/organs/external/tails.dm +++ b/code/modules/surgery/organs/external/tails.dm @@ -204,6 +204,9 @@ . = ..() qdel(GetComponent(/datum/component/connect_containers)) +/obj/item/organ/external/tail/monkey/saiyan/get_butt_sprite() + return BUTT_SPRITE_CAT // how don't we have a monkey one... + /// When we move check if we are exposed to space /obj/item/organ/external/tail/monkey/saiyan/proc/on_moved() SIGNAL_HANDLER diff --git a/code/modules/surgery/organs/internal/heart/_heart.dm b/code/modules/surgery/organs/internal/heart/_heart.dm index c695294024e..c1ebed9afbf 100644 --- a/code/modules/surgery/organs/internal/heart/_heart.dm +++ b/code/modules/surgery/organs/internal/heart/_heart.dm @@ -302,6 +302,3 @@ owner.heal_overall_damage(brute = 15, burn = 15, required_bodytype = BODYTYPE_ORGANIC) if(owner.reagents.get_reagent_amount(/datum/reagent/medicine/ephedrine) < 20) owner.reagents.add_reagent(/datum/reagent/medicine/ephedrine, 10) - -/obj/item/organ/internal/heart/saiyan - maxHealth = STANDARD_ORGAN_THRESHOLD*0.5 // Vulnerable to heart disease diff --git a/code/modules/surgery/organs/internal/heart/heart_saiyan.dm b/code/modules/surgery/organs/internal/heart/heart_saiyan.dm new file mode 100644 index 00000000000..24c41c87924 --- /dev/null +++ b/code/modules/surgery/organs/internal/heart/heart_saiyan.dm @@ -0,0 +1,64 @@ +/// A warrior's heart which gains experience from fighting (and losing) +/obj/item/organ/internal/heart/saiyan + maxHealth = STANDARD_ORGAN_THRESHOLD*0.5 // Vulnerable to heart disease + +/obj/item/organ/internal/heart/saiyan/on_mob_insert(mob/living/carbon/organ_owner, special, movement_flags) + . = ..() + RegisterSignal(organ_owner, COMSIG_MOB_STATCHANGE, PROC_REF(on_stat_changed)) + +/obj/item/organ/internal/heart/saiyan/on_mob_remove(mob/living/carbon/organ_owner, special) + . = ..() + UnregisterSignal(organ_owner, COMSIG_MOB_STATCHANGE) + +/// When we enter crit, prepare for a zenkai boost +/obj/item/organ/internal/heart/saiyan/proc/on_stat_changed(mob/living/source, new_stat) + SIGNAL_HANDLER + if (new_stat != UNCONSCIOUS) + return + source.apply_status_effect(/datum/status_effect/full_throttle_boost) + +/// Removes itself if you die, buffs your saiyan limbs if you do not +/datum/status_effect/full_throttle_boost + id = "full_throttle_boost" + alert_type = null + +/datum/status_effect/full_throttle_boost/on_apply() + . = ..() + if (!.) + return FALSE + + RegisterSignal(owner, COMSIG_MOB_STATCHANGE, PROC_REF(on_stat_changed)) + RegisterSignal(owner, COMSIG_LIVING_DEATH, PROC_REF(on_died)) + return TRUE + +/datum/status_effect/full_throttle_boost/on_remove() + . = ..() + UnregisterSignal(owner, list(COMSIG_MOB_STATCHANGE, COMSIG_LIVING_DEATH)) + +/// Upgrade all of your limb stats if you recovered, wow +/datum/status_effect/full_throttle_boost/proc/on_stat_changed(mob/living/source, new_stat) + SIGNAL_HANDLER + if (new_stat != CONSCIOUS || !iscarbon(source)) + return + + var/mob/living/carbon/limb_haver = owner + var/upgraded = 0 + for (var/obj/item/bodypart/part as anything in limb_haver.bodyparts) + if (!HAS_TRAIT(part, TRAIT_SAIYAN_STRENGTH)) + continue + part.unarmed_damage_high += 2 + part.unarmed_damage_low += 2 + part.unarmed_effectiveness += 2 // This is maybe stronger than increasing the damage tbqh + part.brute_modifier = max(0, part.brute_modifier - 0.05) + part.burn_modifier = max(0, part.burn_modifier - 0.05) + upgraded++ + + if (upgraded > 0) + to_chat(owner, span_notice("Your near-death experience grants you more strength!")) + owner.maxHealth += 5 // Fuck knows if this actually does anything + + qdel(src) + +/datum/status_effect/full_throttle_boost/proc/on_died(mob/living/source) + SIGNAL_HANDLER + qdel(src) diff --git a/tgstation.dme b/tgstation.dme index 937e28e3150..3ba2f045923 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -6146,6 +6146,7 @@ #include "code\modules\surgery\bodyparts\species_parts\misc_bodyparts.dm" #include "code\modules\surgery\bodyparts\species_parts\moth_bodyparts.dm" #include "code\modules\surgery\bodyparts\species_parts\plasmaman_bodyparts.dm" +#include "code\modules\surgery\bodyparts\species_parts\saiyan_bodyparts.dm" #include "code\modules\surgery\organs\_organ.dm" #include "code\modules\surgery\organs\autosurgeon.dm" #include "code\modules\surgery\organs\helpers.dm" @@ -6168,6 +6169,7 @@ #include "code\modules\surgery\organs\internal\heart\_heart.dm" #include "code\modules\surgery\organs\internal\heart\heart_anomalock.dm" #include "code\modules\surgery\organs\internal\heart\heart_ethereal.dm" +#include "code\modules\surgery\organs\internal\heart\heart_saiyan.dm" #include "code\modules\surgery\organs\internal\liver\_liver.dm" #include "code\modules\surgery\organs\internal\liver\liver_golem.dm" #include "code\modules\surgery\organs\internal\liver\liver_plasmaman.dm" From 946739a05628f6d904e47fcfd3c8cf9eca22aac3 Mon Sep 17 00:00:00 2001 From: Jacquerel Date: Tue, 12 Mar 2024 22:51:02 +0000 Subject: [PATCH 06/33] What does the scouter say? --- code/__DEFINES/traits/declarations.dm | 2 ++ code/_globalvars/traits/_traits.dm | 1 + code/game/atom/atom_examine.dm | 5 +++++ .../living/basic/farm_animals/gorilla/gorilla.dm | 2 +- code/modules/mob/living/carbon/carbon.dm | 14 ++++++++++++++ code/modules/mob/living/carbon/examine.dm | 3 +++ .../living/carbon/human/species_types/saiyan.dm | 1 + code/modules/mob/living/living.dm | 11 +++++++++++ code/modules/surgery/organs/external/tails.dm | 1 + code/modules/surgery/organs/internal/eyes/_eyes.dm | 12 ++++++++++++ 10 files changed, 51 insertions(+), 1 deletion(-) diff --git a/code/__DEFINES/traits/declarations.dm b/code/__DEFINES/traits/declarations.dm index 62df14aec84..e752731d3e1 100644 --- a/code/__DEFINES/traits/declarations.dm +++ b/code/__DEFINES/traits/declarations.dm @@ -866,6 +866,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_UNCOMPOSTABLE "uncompostable" /// limbs with this trait can be empowered by a saiyan heart #define TRAIT_SAIYAN_STRENGTH "saiyan_strength" +/// Allows you to detect power levels +#define TRAIT_MARTIAL_VISION "martial_vision" //quirk traits #define TRAIT_ALCOHOL_TOLERANCE "alcohol_tolerance" diff --git a/code/_globalvars/traits/_traits.dm b/code/_globalvars/traits/_traits.dm index f3988082b16..304198cece3 100644 --- a/code/_globalvars/traits/_traits.dm +++ b/code/_globalvars/traits/_traits.dm @@ -330,6 +330,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_MAGICALLY_PHASED" = TRAIT_MAGICALLY_PHASED, "TRAIT_MARTIAL_ARTS_IMMUNE" = TRAIT_MARTIAL_ARTS_IMMUNE, "TRAIT_MANSUS_TOUCHED" = TRAIT_MANSUS_TOUCHED, + "TRAIT_MARTIAL_VISION" = TRAIT_MARTIAL_VISION, "TRAIT_MEDIBOTCOMINGTHROUGH" = TRAIT_MEDIBOTCOMINGTHROUGH, "TRAIT_MEDICAL_HUD" = TRAIT_MEDICAL_HUD, "TRAIT_MESON_VISION" = TRAIT_MESON_VISION, diff --git a/code/game/atom/atom_examine.dm b/code/game/atom/atom_examine.dm index 2151e3927b9..968b66f4498 100644 --- a/code/game/atom/atom_examine.dm +++ b/code/game/atom/atom_examine.dm @@ -165,3 +165,8 @@ /// force_real_name will always return real_name and add (as face_name/id_name) if it doesn't match their appearance /atom/proc/get_visible_name(add_id_name, force_real_name) return name + +/mob/living/examine(mob/user) + . = ..() + if(HAS_TRAIT(user, TRAIT_MARTIAL_VISION)) + . += report_power_level() diff --git a/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm b/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm index 095e75dfb5b..29c1f484fbd 100644 --- a/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm +++ b/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm @@ -207,7 +207,7 @@ /mob/living/basic/gorilla/saiyan/Initialize(mapload) . = ..() - ADD_TRAIT(src, TRAIT_SPACEWALK, INNATE_TRAIT) + add_traits(list(TRAIT_MARTIAL_VISION, TRAIT_SPACEWALK), INNATE_TRAIT) AddComponent(\ /datum/component/ranged_attacks,\ projectile_type = /obj/projectile/beam/emitter/hitscan,\ diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 533da926326..5ad609a3286 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -1469,6 +1469,20 @@ return FALSE return unwagged.stop_wag(src) +/mob/living/carbon/calculate_power_level() + var/min_damage = 0 + var/max_damage = 0 + var/part_count = 0 + for (var/obj/item/bodypart/part as anything in bodyparts) + if (part.unarmed_damage_high <= 0) + continue + min_damage += part.unarmed_damage_low + max_damage += part.unarmed_damage_high + part_count++ + + var/damage = ((min_damage / part_count) + (max_damage / part_count)) / 2 + return maxHealth * max(damage, 0.1) + /mob/living/carbon/itch(obj/item/bodypart/target_part = null, damage = 0.5, can_scratch = TRUE, silent = FALSE) if (isnull(target_part)) target_part = get_bodypart(get_random_valid_zone(even_weights = TRUE)) diff --git a/code/modules/mob/living/carbon/examine.dm b/code/modules/mob/living/carbon/examine.dm index faff5411a7c..d33d65ac6ef 100644 --- a/code/modules/mob/living/carbon/examine.dm +++ b/code/modules/mob/living/carbon/examine.dm @@ -298,6 +298,9 @@ ADD_NEWLINE_IF_NECESSARY(.) . += "Quirks: [get_quirk_string(FALSE, CAT_QUIRK_ALL)]" + if(HAS_TRAIT(user, TRAIT_MARTIAL_VISION)) + . += "[t_His] power level is [report_power_level()]." + SEND_SIGNAL(src, COMSIG_ATOM_EXAMINE, user, .) if(length(.)) .[1] = "" + .[1] diff --git a/code/modules/mob/living/carbon/human/species_types/saiyan.dm b/code/modules/mob/living/carbon/human/species_types/saiyan.dm index ba7ad24e758..a7ba148025e 100644 --- a/code/modules/mob/living/carbon/human/species_types/saiyan.dm +++ b/code/modules/mob/living/carbon/human/species_types/saiyan.dm @@ -1,6 +1,7 @@ /datum/species/saiyan name = "\improper Saiyan" id = SPECIES_SAIYAN + mutanteyes = /obj/item/organ/internal/eyes/saiyan mutantbrain = /obj/item/organ/internal/brain/saiyan mutantheart = /obj/item/organ/internal/heart/saiyan mutantstomach = /obj/item/organ/internal/stomach/saiyan diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index fa32d5eff6f..3938af7c696 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -2971,6 +2971,17 @@ GLOBAL_LIST_EMPTY(fire_appearances) counted_money += counted_credit return round(physical_cash_total) +/// Returns the approximate power level of this creature +/mob/living/proc/calculate_power_level() + return maxHealth * max((melee_damage_lower + melee_damage_upper) / 2, 0.1) + +/// Formats the above as a string +/mob/living/proc/report_power_level() + var/power_level = floor(calculate_power_level()) + if (power_level >= 9000) + return span_boldwarning("[p_Their()] power level is... What?! [power_level]?!?!") + return span_notice("[p_Their()] power level is [power_level].") + /// Returns an arbitrary number which very roughly correlates with how buff you look /mob/living/proc/calculate_fitness() var/athletics_level = mind?.get_skill_level(/datum/skill/athletics) || 1 diff --git a/code/modules/surgery/organs/external/tails.dm b/code/modules/surgery/organs/external/tails.dm index 87b8672d932..ca866d9d8cc 100644 --- a/code/modules/surgery/organs/external/tails.dm +++ b/code/modules/surgery/organs/external/tails.dm @@ -240,6 +240,7 @@ owner.visible_message(span_warning("[owner] transforms into a huge, ape-like creature!")) var/mob/living/basic/gorilla/saiyan/monkie = new(owner.loc) monkie.dir = owner.dir + monkie.faction = owner.faction.Copy() monkie.name = owner.real_name monkie.real_name = owner.real_name monkie.apply_status_effect(/datum/status_effect/shapechange_mob, owner) diff --git a/code/modules/surgery/organs/internal/eyes/_eyes.dm b/code/modules/surgery/organs/internal/eyes/_eyes.dm index daf0b0b060c..c530e2f91a4 100644 --- a/code/modules/surgery/organs/internal/eyes/_eyes.dm +++ b/code/modules/surgery/organs/internal/eyes/_eyes.dm @@ -820,6 +820,18 @@ eye_icon_state = "motheyes" icon_state = "eyeballs-cybermoth" +/obj/item/organ/eyes/saiyan + name = "saiyan eyes" + desc = "The incisive eyes of a warrior. Special cells allow the detection of power levels." + +/obj/item/organ/eyes/saiyan/on_mob_insert(mob/living/carbon/organ_owner, special, movement_flags) + . = ..() + ADD_TRAIT(organ_owner, TRAIT_MARTIAL_VISION, ORGAN_TRAIT) + +/obj/item/organ/eyes/saiyan/on_mob_remove(mob/living/carbon/organ_owner, special) + . = ..() + REMOVE_TRAIT(organ_owner, TRAIT_MARTIAL_VISION, ORGAN_TRAIT) + /obj/item/organ/eyes/snail name = "snail eyes" desc = "These eyes seem to have a large range, but might be cumbersome with glasses." From 3510499754833b5002ea2b750216ffec4bd89bf1 Mon Sep 17 00:00:00 2001 From: Jacquerel Date: Fri, 15 Mar 2024 23:07:55 +0000 Subject: [PATCH 07/33] Base powers --- code/modules/mob/living/brain/brain_item.dm | 5 - code/modules/mob/living/brain/brain_saiyan.dm | 111 ++++++++++++++++++ tgstation.dme | 1 + 3 files changed, 112 insertions(+), 5 deletions(-) create mode 100644 code/modules/mob/living/brain/brain_saiyan.dm diff --git a/code/modules/mob/living/brain/brain_item.dm b/code/modules/mob/living/brain/brain_item.dm index 910a8cc2ebe..d47894d807d 100644 --- a/code/modules/mob/living/brain/brain_item.dm +++ b/code/modules/mob/living/brain/brain_item.dm @@ -463,11 +463,6 @@ . = ..() organ_owner.gain_trauma(/datum/brain_trauma/special/bluespace_prophet, TRAUMA_RESILIENCE_ABSOLUTE) -/obj/item/organ/brain/saiyan - name = "saiyan brain" - desc = "The brain of a mighty saiyan warrior. Guess they don't work out at the library..." - brain_size = 0.5 - /obj/item/organ/brain/felinid //A bit smaller than average brain_size = 0.8 diff --git a/code/modules/mob/living/brain/brain_saiyan.dm b/code/modules/mob/living/brain/brain_saiyan.dm new file mode 100644 index 00000000000..f604fb7ac7e --- /dev/null +++ b/code/modules/mob/living/brain/brain_saiyan.dm @@ -0,0 +1,111 @@ +/// The Saiyan brain contains knowledge of powerful martial arts +/obj/item/organ/internal/brain/saiyan + name = "saiyan brain" + desc = "The brain of a mighty saiyan warrior. Guess they don't work out at the library..." + brain_size = 0.5 + /// What buttons did we give out + var/list/granted_abilities = list() + +/obj/item/organ/internal/brain/saiyan/on_mob_insert(mob/living/carbon/organ_owner, special, movement_flags) + . = ..() + var/datum/action/cooldown/mob_cooldown/ki_blast/blast = new(organ_owner) + blast.Grant(organ_owner) + granted_abilities += blast + + var/datum/action/cooldown/mob_cooldown/saiyan_flight/flight = new(organ_owner) + flight.Grant(organ_owner) + granted_abilities += flight + +/obj/item/organ/internal/brain/saiyan/on_mob_remove(mob/living/carbon/organ_owner, special) + . = ..() + QDEL_LIST(granted_abilities) + +/// Shoot power from your hands, wow +/datum/action/cooldown/mob_cooldown/ki_blast + name = "Ki Blast" + desc = "Channel your ki into your hands and out into the world as rapid projectiles. Drains your fighting spirit." + button_icon = 'icons/obj/weapons/guns/projectiles.dmi' + button_icon_state = "pulse1" + background_icon_state = "bg_demon" + click_to_activate = FALSE + check_flags = AB_CHECK_CONSCIOUS|AB_CHECK_INCAPACITATED|AB_CHECK_HANDS_BLOCKED + +/datum/action/cooldown/mob_cooldown/ki_blast/Activate(atom/target) + var/mob/living/mob_caster = target + if (!istype(mob_caster)) + return FALSE + var/obj/item/gun/ki_blast/ki_gun = new(mob_caster.loc) + if (!mob_caster.put_in_hands(ki_gun, del_on_fail = TRUE)) + mob_caster.balloon_alert(mob_caster, "no free hands!") + return TRUE + +/obj/item/gun/ki_blast + name = "concentrated ki" + desc = "The power of your lifeforce converted into a deadly weapon. Fire it at someone." + fire_sound = 'sound/magic/wand_teleport.ogg' + icon = 'icons/obj/weapons/guns/projectiles.dmi' + icon_state = "pulse1" + inhand_icon_state = "arcane_barrage" + base_icon_state = "arcane_barrage" + lefthand_file = 'icons/mob/inhands/weapons/guns_lefthand.dmi' + righthand_file = 'icons/mob/inhands/weapons/guns_righthand.dmi' + slot_flags = null + item_flags = NEEDS_PERMIT | DROPDEL | ABSTRACT | NOBLUDGEON + flags_1 = NONE + trigger_guard = TRIGGER_GUARD_ALLOW_ALL + +/obj/item/gun/ki_blast/Initialize(mapload) + . = ..() + AddComponent(/datum/component/automatic_fire, 0.15 SECONDS) + chambered = new /obj/item/ammo_casing/ki(src) + +/obj/item/gun/ki_blast/process_fire(atom/target, mob/living/user, message, params, zone_override, bonus_spread) + . = ..() + if (!.) + return FALSE + user.apply_damage(3, STAMINA) + return TRUE + +/obj/item/gun/ki_blast/handle_chamber(empty_chamber, from_firing, chamber_next_round) + chambered.newshot() + +/obj/item/ammo_casing/ki + slot_flags = null + projectile_type = /obj/projectile/ki + firing_effect_type = /obj/effect/temp_visual/dir_setting/firing_effect/blue + +/obj/projectile/ki + name = "ki blast" + icon_state = "pulse1_bl" + damage = 3 + damage_type = BRUTE + hitsound = 'sound/weapons/sear_disabler.ogg' + hitsound_wall = 'sound/weapons/sear_disabler.ogg' + +/// Saiyans can fly +/datum/action/cooldown/mob_cooldown/saiyan_flight + name = "Flight" + button_icon = 'icons/mob/actions/actions_items.dmi' + button_icon_state = "flight" + background_icon_state = "bg_demon" + desc = "Focus your energy and lift into the air, or alternately stop doing that if you are doing it already." + check_flags = AB_CHECK_CONSCIOUS|AB_CHECK_IMMOBILE|AB_CHECK_INCAPACITATED|AB_CHECK_LYING + click_to_activate = FALSE + cooldown_time = 3 SECONDS + +/datum/action/cooldown/mob_cooldown/saiyan_flight/Activate(atom/target) + var/mob/living/mob_caster = target + if (!istype(mob_caster)) + return FALSE + + StartCooldown() + if(!HAS_TRAIT_FROM(mob_caster, TRAIT_MOVE_FLYING, REF(src))) + mob_caster.balloon_alert(mob_caster, "flying") + ADD_TRAIT(mob_caster, TRAIT_MOVE_FLYING, REF(src)) + passtable_on(mob_caster, REF(src)) + return TRUE + + mob_caster.balloon_alert(mob_caster, "landed") + REMOVE_TRAIT(mob_caster, TRAIT_MOVE_FLYING, REF(src)) + passtable_off(mob_caster, REF(src)) + return TRUE diff --git a/tgstation.dme b/tgstation.dme index 3ba2f045923..5c6348b8252 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -5182,6 +5182,7 @@ #include "code\modules\mob\living\brain\brain.dm" #include "code\modules\mob\living\brain\brain_cybernetic.dm" #include "code\modules\mob\living\brain\brain_item.dm" +#include "code\modules\mob\living\brain\brain_saiyan.dm" #include "code\modules\mob\living\brain\brain_say.dm" #include "code\modules\mob\living\brain\death.dm" #include "code\modules\mob\living\brain\emote.dm" From 8a4543fb0096f474983afdc8e90e852798e938a0 Mon Sep 17 00:00:00 2001 From: Jacquerel Date: Sat, 16 Mar 2024 01:33:58 +0000 Subject: [PATCH 08/33] kamehameha --- .../basic/lavaland/brimdemon/brimbeam.dm | 25 ++++--- code/modules/mob/living/brain/brain_saiyan.dm | 67 ++++++++++++++++++ .../organs/internal/heart/heart_saiyan.dm | 3 + icons/effects/saiyan_effects.dmi | Bin 0 -> 6560 bytes 4 files changed, 87 insertions(+), 8 deletions(-) create mode 100644 icons/effects/saiyan_effects.dmi diff --git a/code/modules/mob/living/basic/lavaland/brimdemon/brimbeam.dm b/code/modules/mob/living/basic/lavaland/brimdemon/brimbeam.dm index 5900289cae5..dcb07daa828 100644 --- a/code/modules/mob/living/basic/lavaland/brimdemon/brimbeam.dm +++ b/code/modules/mob/living/basic/lavaland/brimdemon/brimbeam.dm @@ -9,6 +9,8 @@ click_to_activate = TRUE cooldown_time = 5 SECONDS melee_cooldown_time = 0 + /// How long to go on cooldown when interrupted? + var/fail_cooldown = 5 SECONDS /// How far does our beam go? var/beam_range = 10 /// How long does our beam last? @@ -19,6 +21,8 @@ var/static/image/direction_overlay = image('icons/mob/simple/lavaland/lavaland_monsters.dmi', "brimdemon_telegraph_dir") /// A list of all the beam parts. var/list/beam_parts = list() + /// If this isn't a child of /obj/effect/brimbeam it will likely runtime + var/created_type = /obj/effect/brimbeam /datum/action/cooldown/mob_cooldown/brimbeam/Destroy() extinguish_laser() @@ -35,13 +39,12 @@ var/fully_charged = do_after(owner, delay = charge_duration, target = owner) owner.cut_overlay(direction_overlay) if (!fully_charged) - StartCooldown() + StartCooldown(fail_cooldown) return TRUE if (!fire_laser()) - var/static/list/fail_emotes = list("coughs.", "wheezes.", "belches out a puff of black smoke.") - owner.manual_emote(pick(fail_emotes)) - StartCooldown() + on_fail() + StartCooldown(fail_cooldown) return TRUE do_after(owner, delay = beam_duration, target = owner, hidden = TRUE) @@ -49,6 +52,11 @@ StartCooldown() return TRUE +/// Emote if fired directly into a wall +/datum/action/cooldown/mob_cooldown/brimbeam/proc/on_fail() + var/static/list/fail_emotes = list("coughs.", "wheezes.", "belches out a puff of black smoke.") + owner.manual_emote(pick(fail_emotes)) + /// Create a laser in the direction we are facing /datum/action/cooldown/mob_cooldown/brimbeam/proc/fire_laser() owner.visible_message(span_danger("[owner] fires a brimbeam!")) @@ -66,20 +74,20 @@ break if(blocked) break - var/obj/effect/brimbeam/new_brimbeam = new(affected_turf) + var/obj/effect/brimbeam/new_brimbeam = new created_type(affected_turf) new_brimbeam.dir = owner.dir beam_parts += new_brimbeam new_brimbeam.assign_creator(owner) for(var/mob/living/hit_mob in affected_turf.contents) hit_mob.apply_damage(damage = 25, damagetype = BURN) - to_chat(hit_mob, span_userdanger("You're blasted by [owner]'s brimbeam!")) + to_chat(hit_mob, span_userdanger("You're blasted by [owner]'s beam!")) RegisterSignal(new_brimbeam, COMSIG_QDELETING, PROC_REF(extinguish_laser)) // In case idk a singularity eats it or something if(!length(beam_parts)) return FALSE var/atom/last_brimbeam = beam_parts[length(beam_parts)] - last_brimbeam.icon_state = "brimbeam_end" + last_brimbeam.icon_state = "[last_brimbeam.base_icon_state]_end" var/atom/first_brimbeam = beam_parts[1] - first_brimbeam.icon_state = "brimbeam_start" + first_brimbeam.icon_state = "[last_brimbeam.base_icon_state]_start" return TRUE /// Get rid of our laser when we are done with it @@ -96,6 +104,7 @@ name = "brimbeam" icon = 'icons/mob/simple/lavaland/lavaland_monsters.dmi' icon_state = "brimbeam_mid" + base_icon_state = "brimbeam" layer = ABOVE_MOB_LAYER plane = ABOVE_GAME_PLANE mouse_opacity = MOUSE_OPACITY_TRANSPARENT diff --git a/code/modules/mob/living/brain/brain_saiyan.dm b/code/modules/mob/living/brain/brain_saiyan.dm index f604fb7ac7e..525f3630e37 100644 --- a/code/modules/mob/living/brain/brain_saiyan.dm +++ b/code/modules/mob/living/brain/brain_saiyan.dm @@ -29,12 +29,16 @@ background_icon_state = "bg_demon" click_to_activate = FALSE check_flags = AB_CHECK_CONSCIOUS|AB_CHECK_INCAPACITATED|AB_CHECK_HANDS_BLOCKED + shared_cooldown = NONE + /// Extra damage to do + var/damage_modifier = 1 /datum/action/cooldown/mob_cooldown/ki_blast/Activate(atom/target) var/mob/living/mob_caster = target if (!istype(mob_caster)) return FALSE var/obj/item/gun/ki_blast/ki_gun = new(mob_caster.loc) + ki_gun.projectile_damage_multiplier = damage_modifier if (!mob_caster.put_in_hands(ki_gun, del_on_fail = TRUE)) mob_caster.balloon_alert(mob_caster, "no free hands!") return TRUE @@ -92,6 +96,7 @@ check_flags = AB_CHECK_CONSCIOUS|AB_CHECK_IMMOBILE|AB_CHECK_INCAPACITATED|AB_CHECK_LYING click_to_activate = FALSE cooldown_time = 3 SECONDS + shared_cooldown = NONE /datum/action/cooldown/mob_cooldown/saiyan_flight/Activate(atom/target) var/mob/living/mob_caster = target @@ -109,3 +114,65 @@ REMOVE_TRAIT(mob_caster, TRAIT_MOVE_FLYING, REF(src)) passtable_off(mob_caster, REF(src)) return TRUE + + +#define GOKU_FILTER "goku_filter" + +/// Charge up a big beam +/datum/action/cooldown/mob_cooldown/brimbeam/kamehameha + name = "Kamehameha" + desc = "The signature technique of the turtle school, a devastating charged beam attack!" + button_icon = 'icons/effects/saiyan_effects.dmi' + button_icon_state = "kamehameha_start" + created_type = /obj/effect/brimbeam/kamehameha + charge_duration = 5 SECONDS + beam_duration = 12 SECONDS + cooldown_time = 90 SECONDS + shared_cooldown = NONE + /// Things we still need to say, before it's too late + var/speech_timers = list() + +/datum/action/cooldown/mob_cooldown/brimbeam/kamehameha/Activate(atom/target) + owner.add_filter(GOKU_FILTER, 2, list("type" = "outline", "color" = COLOR_CYAN, "alpha" = 0, "size" = 1)) + var/filter = owner.get_filter(GOKU_FILTER) + animate(filter, alpha = 200, time = 0.5 SECONDS, loop = -1) + animate(alpha = 0, time = 0.5 SECONDS) + owner.say("Ka...") + var/queued_speech = list("...me...", "...ha...", "...me...") + var/speech_interval = charge_duration/4 + var/current_interval = speech_interval + while(length(queued_speech)) + var/timer = addtimer(CALLBACK(owner, TYPE_PROC_REF(/atom/movable, say), pop(queued_speech)), current_interval, TIMER_STOPPABLE | TIMER_DELETE_ME) + current_interval += speech_interval + speech_timers += timer + playsound(owner, 'sound/items/modsuit/loader_charge.ogg', 75, TRUE) + return ..() + +/datum/action/cooldown/mob_cooldown/brimbeam/kamehameha/fire_laser() + . = ..() + if (.) + owner.say("...HA!!!!!") + +/datum/action/cooldown/mob_cooldown/brimbeam/kamehameha/StartCooldown(override_cooldown_time, override_melee_cooldown_time) + . = ..() + if (override_cooldown_time == 360 SECONDS) // Ignore the one we set while the ability is processing + return + for (var/timer as anything in speech_timers) + deltimer(timer) + speech_timers = list() + var/filter = owner.get_filter(GOKU_FILTER) + animate(filter) + owner.remove_filter(GOKU_FILTER) + +/datum/action/cooldown/mob_cooldown/brimbeam/kamehameha/on_fail() + owner.visible_message(span_notice("...and launches it straight into a wall, wasting their energy.")) + +/// It's blue now! +/obj/effect/brimbeam/kamehameha + name = "kamehameha" + light_color = LIGHT_COLOR_CYAN + icon = 'icons/effects/saiyan_effects.dmi' + icon_state = "kamehameha" + base_icon_state = "kamehameha" + +#undef GOKU_FILTER diff --git a/code/modules/surgery/organs/internal/heart/heart_saiyan.dm b/code/modules/surgery/organs/internal/heart/heart_saiyan.dm index 24c41c87924..c716c077b2f 100644 --- a/code/modules/surgery/organs/internal/heart/heart_saiyan.dm +++ b/code/modules/surgery/organs/internal/heart/heart_saiyan.dm @@ -56,6 +56,9 @@ if (upgraded > 0) to_chat(owner, span_notice("Your near-death experience grants you more strength!")) owner.maxHealth += 5 // Fuck knows if this actually does anything + var/datum/action/cooldown/mob_cooldown/ki_blast/blast = locate() in owner.actions + if (!isnull(blast)) + blast.damage_modifier += 0.1 qdel(src) diff --git a/icons/effects/saiyan_effects.dmi b/icons/effects/saiyan_effects.dmi new file mode 100644 index 0000000000000000000000000000000000000000..e8f2a81f5f45e4eedabbd88bf686715119ddea0d GIT binary patch literal 6560 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 F{|BW3mJI*^ literal 0 HcmV?d00001 From b9ebcea27ac9d4baee2e4530eaaf8c00e6ab060a Mon Sep 17 00:00:00 2001 From: Jacquerel Date: Sat, 16 Mar 2024 20:50:26 +0000 Subject: [PATCH 09/33] Yajirobe's time to shine --- .../signals/signals_mob/signals_mob_carbon.dm | 5 + .../basic/farm_animals/gorilla/gorilla.dm | 30 +++++- code/modules/mob/living/carbon/human/human.dm | 3 + .../carbon/human/species_types/saiyan.dm | 102 +++++++++++++++++- .../organs/internal/heart/heart_saiyan.dm | 35 ++---- 5 files changed, 146 insertions(+), 29 deletions(-) diff --git a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_carbon.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_carbon.dm index 5d9ce528c65..e1665a8e7fb 100644 --- a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_carbon.dm +++ b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_carbon.dm @@ -152,6 +152,11 @@ ///from /atom/movable/screen/alert/give/proc/handle_transfer(): (taker, item) #define COMSIG_CARBON_ITEM_GIVEN "carbon_item_given" +/// Saiyan survived a near-death encounter +#define COMSIG_SAIYAN_SURVIVOR "miracle_zenkai_power" +/// Saiyan just lost their tail +#define COMSIG_SAIYAN_TAIL_REMOVED "saiyan_tail_removed" + /// Sent from /mob/living/carbon/human/handle_blood(): (seconds_per_tick, times_fired) #define COMSIG_HUMAN_ON_HANDLE_BLOOD "human_on_handle_blood" /// Return to prevent all default blood handling diff --git a/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm b/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm index 29c1f484fbd..b706e10b816 100644 --- a/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm +++ b/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm @@ -201,7 +201,6 @@ /mob/living/basic/gorilla/saiyan name = "Saiyan Great Ape" desc = "A large and destructive ape-like creature, capable of surviving the depths of space and discharging energy beams." - ai_controller = null unsuitable_atmos_damage = 0 unsuitable_cold_damage = 0 @@ -214,5 +213,34 @@ projectile_sound = 'sound/items/weapons/emitter.ogg',\ cooldown_time = 0.5 SECONDS, \ ) + RegisterSignal(src, COMSIG_ATOM_AFTER_ATTACKEDBY, PROC_REF(check_tail_sever)) + +/// Cut off his tail! It's the only way! +/mob/living/basic/gorilla/saiyan/proc/check_tail_sever(mob/living/target, obj/item/weapon, mob/attacker, proximity_flag, click_parameters) + SIGNAL_HANDLER + if (!proximity_flag || weapon.force < 5 || weapon.get_sharpness() != SHARP_EDGED) + return + to_chat(world, "trying it") + if (!prob(3)) + return + target.visible_message(span_warning("[src]'s tail falls to the ground, severed completely!")) + INVOKE_ASYNC(target, TYPE_PROC_REF(/mob, emote), "scream") + + var/datum/status_effect/shapechange_mob/shapechange_status = has_status_effect(/datum/status_effect/shapechange_mob) + var/mob/living/carbon/saiyan + if (isnull(shapechange_status)) + saiyan = new /mob/living/carbon/human/species/saiyan(loc) + saiyan.name = name + saiyan.real_name = name + else + saiyan = shapechange_status.caster_mob + + if (istype(saiyan)) + var/obj/item/organ/external/tail/saiyan_tail = saiyan.get_organ_slot(ORGAN_SLOT_EXTERNAL_TAIL) + saiyan_tail.Remove(saiyan) + saiyan_tail.forceMove(saiyan.loc) + + remove_status_effect(/datum/status_effect/shapechange_mob) + qdel(src) #undef GORILLA_HANDS_LAYER diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index ac34dbf994b..b8296f2cffa 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1179,6 +1179,9 @@ /mob/living/carbon/human/species/pod race = /datum/species/pod +/mob/living/carbon/human/species/saiyan + race = /datum/species/saiyan + /mob/living/carbon/human/species/shadow race = /datum/species/shadow diff --git a/code/modules/mob/living/carbon/human/species_types/saiyan.dm b/code/modules/mob/living/carbon/human/species_types/saiyan.dm index a7ba148025e..49331555307 100644 --- a/code/modules/mob/living/carbon/human/species_types/saiyan.dm +++ b/code/modules/mob/living/carbon/human/species_types/saiyan.dm @@ -1,3 +1,10 @@ +#define DAMAGE_BOOST 2 +#define DAMAGE_MULT 0.1 +#define DEFENCE_BOOST 0.05 +#define SPEED_BOOST 0.1 +#define HEALTH_BOOST 5 +#define SAIYAN_TAIL_MOOD "saiyan_humiliated" + /datum/species/saiyan name = "\improper Saiyan" id = SPECIES_SAIYAN @@ -25,6 +32,8 @@ external_organs = list( /obj/item/organ/external/tail/monkey/saiyan = "Monkey", ) + /// How much fasterer are we? + var/applied_movespeed = 0 /datum/species/saiyan/prepare_human_for_preview(mob/living/carbon/human/human) human.set_haircolor("#292929", update = FALSE) @@ -36,6 +45,83 @@ // return TRUE // return ..() +/datum/species/saiyan/on_species_gain(mob/living/carbon/human/human_who_gained_species, datum/species/old_species, pref_load) + . = ..() + RegisterSignal(human_who_gained_species, COMSIG_SAIYAN_SURVIVOR, PROC_REF(on_survived_boost)) + RegisterSignal(human_who_gained_species, COMSIG_CARBON_GAIN_ORGAN, PROC_REF(on_tail_gained)) + RegisterSignal(human_who_gained_species, COMSIG_CARBON_LOSE_ORGAN, PROC_REF(on_tail_removed)) + RegisterSignal(human_who_gained_species, COMSIG_ATOM_AFTER_ATTACKEDBY, PROC_REF(check_tail_sever)) + +/datum/species/saiyan/on_species_loss(mob/living/carbon/human/C, datum/species/new_species, pref_load) + . = ..() + UnregisterSignal(C, list(COMSIG_SAIYAN_SURVIVOR, COMSIG_CARBON_GAIN_ORGAN, COMSIG_CARBON_LOSE_ORGAN, COMSIG_ATOM_AFTER_ATTACKEDBY)) + +/// If you take sharp damage someone might sever your tail +/datum/species/saiyan/proc/check_tail_sever(mob/living/carbon/target, obj/item/weapon, mob/attacker, proximity_flag, click_parameters) + SIGNAL_HANDLER + if (!proximity_flag || weapon.force < 5 || weapon.get_sharpness() != SHARP_EDGED) + return + if (attacker.zone_selected != BODY_ZONE_PRECISE_GROIN && attacker.zone_selected != BODY_ZONE_CHEST) + return + var/obj/item/organ/external/tail/saiyan_tail = target.get_organ_slot(ORGAN_SLOT_EXTERNAL_TAIL) + if (isnull(saiyan_tail) || !prob(3)) + return + target.visible_message(span_warning("[target]'s tail falls to the ground, severed completely!")) + INVOKE_ASYNC(target, TYPE_PROC_REF(/mob, emote), "scream") + saiyan_tail.Remove(target) + saiyan_tail.forceMove(target.loc) + +/// Called when we survive near-death +/datum/species/saiyan/proc/on_survived_boost(mob/living/saiyan) + SIGNAL_HANDLER + to_chat(saiyan, span_notice("Your near-death experience grants you more strength!")) + power_up(saiyan) + +/// Increase our strength, wow +/datum/species/saiyan/proc/power_up(mob/living/carbon/saiyan, var/multiplier = 1) + if (isnull(saiyan)) + return + + var/added_damage = DAMAGE_BOOST * multiplier + var/added_defence = DEFENCE_BOOST * multiplier + for (var/obj/item/bodypart/part as anything in saiyan.bodyparts) + if (!HAS_TRAIT(part, TRAIT_SAIYAN_STRENGTH)) + continue + part.unarmed_damage_high += added_damage + part.unarmed_damage_low += added_damage + part.unarmed_effectiveness += added_damage // This is maybe stronger than increasing the damage tbqh + part.brute_modifier = max(0, part.brute_modifier - added_defence) + part.burn_modifier = max(0, part.burn_modifier - added_defence) + + saiyan.maxHealth += HEALTH_BOOST * multiplier // Fuck knows if this actually does anything + var/datum/action/cooldown/mob_cooldown/ki_blast/blast = locate() in saiyan.actions + if (!isnull(blast)) + blast.damage_modifier += DAMAGE_MULT * multiplier + applied_movespeed -= SPEED_BOOST * multiplier + saiyan.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/saiyan_speed, TRUE, applied_movespeed) + +/// When your tail is cut you get weaker +/datum/species/saiyan/proc/on_tail_gained(mob/living/vegeta, obj/item/organ/tail) + SIGNAL_HANDLER + if (!istype(tail, /obj/item/organ/external/tail/monkey/saiyan)) + return + if (!vegeta.mob_mood.has_mood_of_category(SAIYAN_TAIL_MOOD)) + return + to_chat(vegeta, span_notice("As your tail returns, your strength returns too.")) + power_up(vegeta, multiplier = 5) + vegeta.clear_mood_event(SAIYAN_TAIL_MOOD) + +/// If your tail is restored you return to original strength +/datum/species/saiyan/proc/on_tail_removed(mob/living/vegeta, obj/item/organ/tail) + SIGNAL_HANDLER + if (!istype(tail, /obj/item/organ/external/tail/monkey/saiyan)) + return + to_chat(vegeta, span_boldwarning("No! Your tail!!")) + power_up(vegeta, multiplier = -5) + vegeta.add_mood_event(SAIYAN_TAIL_MOOD, /datum/mood_event/saiyan_humiliated) + vegeta.Paralyze(10 SECONDS) + vegeta.adjust_confusion(1 MINUTES) + /datum/species/saiyan/get_physical_attributes() return "While they appear superficially similar to humans, Saiyans are universally specimens of toned and perfect health with \ the honed physique of warriors. They can be distinguished from inferior Human stock by their simian tails, and expressive haircuts." @@ -69,7 +155,7 @@ list( SPECIES_PERK_TYPE = SPECIES_POSITIVE_PERK, SPECIES_PERK_ICON = "first-aid", - SPECIES_PERK_NAME = "Full Throttle", + SPECIES_PERK_NAME = "Fighting Spirit", SPECIES_PERK_DESC = "A Saiyan who recovers from grievous injury (but not death) often becomes more powerful.", ), list( @@ -99,3 +185,17 @@ ) return to_add + +/datum/movespeed_modifier/saiyan_speed + variable = TRUE + +/datum/mood_event/saiyan_humiliated + description = "Someone removed your Saiyan birthright... such an insult must not be tolerated." + mood_change = -4 + +#undef DAMAGE_BOOST +#undef DAMAGE_MULT +#undef DEFENCE_BOOST +#undef SPEED_BOOST +#undef HEALTH_BOOST +#undef SAIYAN_TAIL_MOOD diff --git a/code/modules/surgery/organs/internal/heart/heart_saiyan.dm b/code/modules/surgery/organs/internal/heart/heart_saiyan.dm index c716c077b2f..647bdb7bbd6 100644 --- a/code/modules/surgery/organs/internal/heart/heart_saiyan.dm +++ b/code/modules/surgery/organs/internal/heart/heart_saiyan.dm @@ -15,14 +15,14 @@ SIGNAL_HANDLER if (new_stat != UNCONSCIOUS) return - source.apply_status_effect(/datum/status_effect/full_throttle_boost) + source.apply_status_effect(/datum/status_effect/saiyan_survivor_tracker) /// Removes itself if you die, buffs your saiyan limbs if you do not -/datum/status_effect/full_throttle_boost - id = "full_throttle_boost" +/datum/status_effect/saiyan_survivor_tracker + id = "saiyan_survivor_tracker" alert_type = null -/datum/status_effect/full_throttle_boost/on_apply() +/datum/status_effect/saiyan_survivor_tracker/on_apply() . = ..() if (!.) return FALSE @@ -31,37 +31,18 @@ RegisterSignal(owner, COMSIG_LIVING_DEATH, PROC_REF(on_died)) return TRUE -/datum/status_effect/full_throttle_boost/on_remove() +/datum/status_effect/saiyan_survivor_tracker/on_remove() . = ..() UnregisterSignal(owner, list(COMSIG_MOB_STATCHANGE, COMSIG_LIVING_DEATH)) /// Upgrade all of your limb stats if you recovered, wow -/datum/status_effect/full_throttle_boost/proc/on_stat_changed(mob/living/source, new_stat) +/datum/status_effect/saiyan_survivor_tracker/proc/on_stat_changed(mob/living/source, new_stat) SIGNAL_HANDLER if (new_stat != CONSCIOUS || !iscarbon(source)) return - - var/mob/living/carbon/limb_haver = owner - var/upgraded = 0 - for (var/obj/item/bodypart/part as anything in limb_haver.bodyparts) - if (!HAS_TRAIT(part, TRAIT_SAIYAN_STRENGTH)) - continue - part.unarmed_damage_high += 2 - part.unarmed_damage_low += 2 - part.unarmed_effectiveness += 2 // This is maybe stronger than increasing the damage tbqh - part.brute_modifier = max(0, part.brute_modifier - 0.05) - part.burn_modifier = max(0, part.burn_modifier - 0.05) - upgraded++ - - if (upgraded > 0) - to_chat(owner, span_notice("Your near-death experience grants you more strength!")) - owner.maxHealth += 5 // Fuck knows if this actually does anything - var/datum/action/cooldown/mob_cooldown/ki_blast/blast = locate() in owner.actions - if (!isnull(blast)) - blast.damage_modifier += 0.1 - + SEND_SIGNAL(source, COMSIG_SAIYAN_SURVIVOR) qdel(src) -/datum/status_effect/full_throttle_boost/proc/on_died(mob/living/source) +/datum/status_effect/saiyan_survivor_tracker/proc/on_died(mob/living/source) SIGNAL_HANDLER qdel(src) From 241b32125a5ce47813601947eb84bfebe1b8e53d Mon Sep 17 00:00:00 2001 From: Jacquerel Date: Sat, 16 Mar 2024 21:01:19 +0000 Subject: [PATCH 10/33] solar flare --- .../basic/lavaland/watcher/watcher_gaze.dm | 8 ++++++-- code/modules/mob/living/brain/brain_saiyan.dm | 19 +++++++++++++++++-- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/code/modules/mob/living/basic/lavaland/watcher/watcher_gaze.dm b/code/modules/mob/living/basic/lavaland/watcher/watcher_gaze.dm index 7d0ad8f191a..df17ab3ba5f 100644 --- a/code/modules/mob/living/basic/lavaland/watcher/watcher_gaze.dm +++ b/code/modules/mob/living/basic/lavaland/watcher/watcher_gaze.dm @@ -21,12 +21,16 @@ var/image/current_overlay /// Timer until we go to the next stage var/stage_timer + /// Text to print upon use + var/report_started = "'s eye glows ominously!" + /// What do we report blinded people? + var/blinded_source = "piercing gaze" /datum/action/cooldown/mob_cooldown/watcher_gaze/Activate(mob/living/target) show_indicator_overlay("eye_open") stage_timer = addtimer(CALLBACK(src, PROC_REF(show_indicator_overlay), "eye_pulse"), animation_time, TIMER_STOPPABLE) StartCooldown(360 SECONDS, 360 SECONDS) - owner.visible_message(span_warning("[owner]'s eye glows ominously!")) + owner.visible_message(span_warning("[owner] [report_started]")) if (do_after(owner, delay = wait_delay, target = owner)) trigger_effect() else @@ -72,7 +76,7 @@ if (!viewer.flash_act(intensity = 4, affect_silicon = TRUE, visual = TRUE, length = 3 SECONDS)) return FALSE viewer.set_confusion_if_lower(12 SECONDS) - to_chat(viewer, span_warning("You are blinded by [owner]'s piercing gaze!")) + to_chat(viewer, span_warning("You are blinded by [owner]'s [blinded_source]!")) return TRUE /// Animate our effect out diff --git a/code/modules/mob/living/brain/brain_saiyan.dm b/code/modules/mob/living/brain/brain_saiyan.dm index 525f3630e37..b5324e5646d 100644 --- a/code/modules/mob/living/brain/brain_saiyan.dm +++ b/code/modules/mob/living/brain/brain_saiyan.dm @@ -1,3 +1,5 @@ +#define GOKU_FILTER "goku_filter" + /// The Saiyan brain contains knowledge of powerful martial arts /obj/item/organ/internal/brain/saiyan name = "saiyan brain" @@ -30,6 +32,7 @@ click_to_activate = FALSE check_flags = AB_CHECK_CONSCIOUS|AB_CHECK_INCAPACITATED|AB_CHECK_HANDS_BLOCKED shared_cooldown = NONE + melee_cooldown_time = 0 SECONDS /// Extra damage to do var/damage_modifier = 1 @@ -97,6 +100,7 @@ click_to_activate = FALSE cooldown_time = 3 SECONDS shared_cooldown = NONE + melee_cooldown_time = 0 SECONDS /datum/action/cooldown/mob_cooldown/saiyan_flight/Activate(atom/target) var/mob/living/mob_caster = target @@ -116,8 +120,6 @@ return TRUE -#define GOKU_FILTER "goku_filter" - /// Charge up a big beam /datum/action/cooldown/mob_cooldown/brimbeam/kamehameha name = "Kamehameha" @@ -129,6 +131,7 @@ beam_duration = 12 SECONDS cooldown_time = 90 SECONDS shared_cooldown = NONE + melee_cooldown_time = 0 SECONDS /// Things we still need to say, before it's too late var/speech_timers = list() @@ -174,5 +177,17 @@ icon = 'icons/effects/saiyan_effects.dmi' icon_state = "kamehameha" base_icon_state = "kamehameha" + report_started = "holds their hands to their forehead!" + blinded_source = "flash of light!" + +/// Blinds people +/datum/action/cooldown/mob_cooldown/watcher_gaze/solar_flare + name = "Solar Flare" + desc = "A surprising move of the Crane school, creating a blinding flash that can overpower even shaded glasses. Useful on opponents regardless of power level." + wait_delay = 1 SECONDS + +/datum/action/cooldown/mob_cooldown/watcher_gaze/solar_flare/trigger_effect() + . = ..() + owner.say("Solar flare!!") #undef GOKU_FILTER From b0a155504238016739985709076d1512c86a91bb Mon Sep 17 00:00:00 2001 From: Jacquerel Date: Sun, 17 Mar 2024 00:23:27 +0000 Subject: [PATCH 11/33] Another powerful technique --- .../signals/signals_mob/signals_mob_carbon.dm | 5 ++ code/modules/mob/living/brain/brain_saiyan.dm | 73 ++++++++++++++++++- code/modules/mob/living/carbon/carbon.dm | 20 +++++ .../carbon/human/species_types/saiyan.dm | 48 +++--------- code/modules/mob/living/living.dm | 23 ++++++ code/modules/mob/living/living_defines.dm | 3 + 6 files changed, 131 insertions(+), 41 deletions(-) diff --git a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_carbon.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_carbon.dm index e1665a8e7fb..9cd8f80af18 100644 --- a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_carbon.dm +++ b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_carbon.dm @@ -157,6 +157,11 @@ /// Saiyan just lost their tail #define COMSIG_SAIYAN_TAIL_REMOVED "saiyan_tail_removed" +/// Signal sent when you use the kaioken technique (power_multiplier) +#define COMSIG_KAIKOEN_APPLIED "kaioken_applied" +/// Signal sent when you lose the kaioken power (power_multiplier) +#define COMSIG_KAIOKEN_REMOVED "kaioken_removed" + /// Sent from /mob/living/carbon/human/handle_blood(): (seconds_per_tick, times_fired) #define COMSIG_HUMAN_ON_HANDLE_BLOOD "human_on_handle_blood" /// Return to prevent all default blood handling diff --git a/code/modules/mob/living/brain/brain_saiyan.dm b/code/modules/mob/living/brain/brain_saiyan.dm index b5324e5646d..53d4192f25d 100644 --- a/code/modules/mob/living/brain/brain_saiyan.dm +++ b/code/modules/mob/living/brain/brain_saiyan.dm @@ -177,17 +177,86 @@ icon = 'icons/effects/saiyan_effects.dmi' icon_state = "kamehameha" base_icon_state = "kamehameha" - report_started = "holds their hands to their forehead!" - blinded_source = "flash of light!" /// Blinds people /datum/action/cooldown/mob_cooldown/watcher_gaze/solar_flare name = "Solar Flare" desc = "A surprising move of the Crane school, creating a blinding flash that can overpower even shaded glasses. Useful on opponents regardless of power level." wait_delay = 1 SECONDS + report_started = "holds their hands to their forehead!" + blinded_source = "flash of light!" /datum/action/cooldown/mob_cooldown/watcher_gaze/solar_flare/trigger_effect() . = ..() owner.say("Solar flare!!") +/// Makes you stronger and stacks too. But watch out! +/datum/action/cooldown/mob_cooldown/kaioken + name = "Kaio-ken Technique" + desc = "A technique taught by the powerful Kais of Otherworld, allows the user to multiply their ki at great personal risk. The effects can be stacked multiplicatively to greatly increase fighting strength, however overuse may cause immediate disintegration." + cooldown_time = 3 SECONDS + shared_cooldown = NONE + melee_cooldown_time = NONE + click_to_activate = FALSE + background_icon_state = "bg_demon" + +// This is basically handled entirely by the status effect +/datum/action/cooldown/mob_cooldown/kaioken/Activate(mob/living/target) + target.apply_status_effect(/datum/status_effect/stacking/kaioken, 1) + StartCooldown() + return TRUE + +/datum/status_effect/stacking/kaioken + id = "kaioken" + stacks = 0 + max_stacks = INFINITY // but good luck + consumed_on_threshold = FALSE + alert_type = null + status_type = STATUS_EFFECT_REFRESH // Allows us to add one stack at a time by just applying the effect + duration = 10 SECONDS + stack_decay = 0 + /// How much strength to add every time? + var/power_multiplier = 3 + /// Percentage chance to die instantly, will be multiplied by current stacks + var/death_chance = 5 + +/datum/status_effect/stacking/kaioken/on_apply() + . = ..() + owner.add_filter(GOKU_FILTER, 2, list("type" = "outline", "color" = COLOR_RED, "alpha" = 0, "size" = 1)) + var/filter = owner.get_filter(GOKU_FILTER) + animate(filter, alpha = 200, time = 0.5 SECONDS, loop = -1) + animate(alpha = 0, time = 0.5 SECONDS) + +/datum/status_effect/stacking/kaioken/on_remove() + var/filter = owner.get_filter(GOKU_FILTER) + animate(filter) + owner.remove_filter(GOKU_FILTER) + owner.saiyan_boost(-power_multiplier * stacks) + return ..() + +/datum/status_effect/stacking/kaioken/refresh(effect, stacks_to_add) + . = ..() + add_stacks(stacks_to_add) + +/datum/status_effect/stacking/kaioken/add_stacks(stacks_added) + if (stacks_added == 0) + return + . = ..() + if (stacks == 0) + return + if (prob((stacks - 1) * death_chance)) + owner.say("Kaio-AARGH!!") + owner.visible_message(span_boldwarning("[owner] vanishes in an intense flash of light!")) + owner.ghostize(can_reenter_corpse = FALSE) + owner.dust() + return + owner.saiyan_boost(power_multiplier) + if (stacks == 1) + owner.say("Kaio-ken!") + return + var/exclamations = "" + for (var/i in 1 to stacks) + exclamations += "!" + owner.say("Kaio-ken... times [convert_integer_to_words(stacks)][exclamations]") + #undef GOKU_FILTER diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 5ad609a3286..a0d66859ced 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -1483,6 +1483,26 @@ var/damage = ((min_damage / part_count) + (max_damage / part_count)) / 2 return maxHealth * max(damage, 0.1) +#define DAMAGE_BOOST 2 +#define DEFENCE_BOOST 0.05 + +/mob/living/carbon/saiyan_boost(multiplier) + . = ..() + var/added_damage = DAMAGE_BOOST * multiplier + var/added_defence = DEFENCE_BOOST * multiplier + + for (var/obj/item/bodypart/part as anything in bodyparts) + if (!HAS_TRAIT(part, TRAIT_SAIYAN_STRENGTH)) + continue + part.unarmed_damage_high += added_damage + part.unarmed_damage_low += added_damage + part.unarmed_effectiveness += added_damage // This is maybe stronger than increasing the damage tbqh + part.brute_modifier = max(0, part.brute_modifier - added_defence) + part.burn_modifier = max(0, part.burn_modifier - added_defence) + +#undef DAMAGE_BOOST +#undef DEFENCE_BOOST + /mob/living/carbon/itch(obj/item/bodypart/target_part = null, damage = 0.5, can_scratch = TRUE, silent = FALSE) if (isnull(target_part)) target_part = get_bodypart(get_random_valid_zone(even_weights = TRUE)) diff --git a/code/modules/mob/living/carbon/human/species_types/saiyan.dm b/code/modules/mob/living/carbon/human/species_types/saiyan.dm index 49331555307..d13ee4b30a7 100644 --- a/code/modules/mob/living/carbon/human/species_types/saiyan.dm +++ b/code/modules/mob/living/carbon/human/species_types/saiyan.dm @@ -1,8 +1,3 @@ -#define DAMAGE_BOOST 2 -#define DAMAGE_MULT 0.1 -#define DEFENCE_BOOST 0.05 -#define SPEED_BOOST 0.1 -#define HEALTH_BOOST 5 #define SAIYAN_TAIL_MOOD "saiyan_humiliated" /datum/species/saiyan @@ -32,8 +27,6 @@ external_organs = list( /obj/item/organ/external/tail/monkey/saiyan = "Monkey", ) - /// How much fasterer are we? - var/applied_movespeed = 0 /datum/species/saiyan/prepare_human_for_preview(mob/living/carbon/human/human) human.set_haircolor("#292929", update = FALSE) @@ -54,7 +47,12 @@ /datum/species/saiyan/on_species_loss(mob/living/carbon/human/C, datum/species/new_species, pref_load) . = ..() - UnregisterSignal(C, list(COMSIG_SAIYAN_SURVIVOR, COMSIG_CARBON_GAIN_ORGAN, COMSIG_CARBON_LOSE_ORGAN, COMSIG_ATOM_AFTER_ATTACKEDBY)) + UnregisterSignal(C, list( + COMSIG_ATOM_AFTER_ATTACKEDBY, + COMSIG_CARBON_GAIN_ORGAN, + COMSIG_CARBON_LOSE_ORGAN, + COMSIG_SAIYAN_SURVIVOR, + )) /// If you take sharp damage someone might sever your tail /datum/species/saiyan/proc/check_tail_sever(mob/living/carbon/target, obj/item/weapon, mob/attacker, proximity_flag, click_parameters) @@ -75,30 +73,7 @@ /datum/species/saiyan/proc/on_survived_boost(mob/living/saiyan) SIGNAL_HANDLER to_chat(saiyan, span_notice("Your near-death experience grants you more strength!")) - power_up(saiyan) - -/// Increase our strength, wow -/datum/species/saiyan/proc/power_up(mob/living/carbon/saiyan, var/multiplier = 1) - if (isnull(saiyan)) - return - - var/added_damage = DAMAGE_BOOST * multiplier - var/added_defence = DEFENCE_BOOST * multiplier - for (var/obj/item/bodypart/part as anything in saiyan.bodyparts) - if (!HAS_TRAIT(part, TRAIT_SAIYAN_STRENGTH)) - continue - part.unarmed_damage_high += added_damage - part.unarmed_damage_low += added_damage - part.unarmed_effectiveness += added_damage // This is maybe stronger than increasing the damage tbqh - part.brute_modifier = max(0, part.brute_modifier - added_defence) - part.burn_modifier = max(0, part.burn_modifier - added_defence) - - saiyan.maxHealth += HEALTH_BOOST * multiplier // Fuck knows if this actually does anything - var/datum/action/cooldown/mob_cooldown/ki_blast/blast = locate() in saiyan.actions - if (!isnull(blast)) - blast.damage_modifier += DAMAGE_MULT * multiplier - applied_movespeed -= SPEED_BOOST * multiplier - saiyan.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/saiyan_speed, TRUE, applied_movespeed) + saiyan.saiyan_boost() /// When your tail is cut you get weaker /datum/species/saiyan/proc/on_tail_gained(mob/living/vegeta, obj/item/organ/tail) @@ -108,7 +83,7 @@ if (!vegeta.mob_mood.has_mood_of_category(SAIYAN_TAIL_MOOD)) return to_chat(vegeta, span_notice("As your tail returns, your strength returns too.")) - power_up(vegeta, multiplier = 5) + vegeta.saiyan_boost(multiplier = 5) vegeta.clear_mood_event(SAIYAN_TAIL_MOOD) /// If your tail is restored you return to original strength @@ -117,7 +92,7 @@ if (!istype(tail, /obj/item/organ/external/tail/monkey/saiyan)) return to_chat(vegeta, span_boldwarning("No! Your tail!!")) - power_up(vegeta, multiplier = -5) + vegeta.saiyan_boost(multiplier = -5) vegeta.add_mood_event(SAIYAN_TAIL_MOOD, /datum/mood_event/saiyan_humiliated) vegeta.Paralyze(10 SECONDS) vegeta.adjust_confusion(1 MINUTES) @@ -193,9 +168,4 @@ description = "Someone removed your Saiyan birthright... such an insult must not be tolerated." mood_change = -4 -#undef DAMAGE_BOOST -#undef DAMAGE_MULT -#undef DEFENCE_BOOST -#undef SPEED_BOOST -#undef HEALTH_BOOST #undef SAIYAN_TAIL_MOOD diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 3938af7c696..585925fc3e5 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -2982,6 +2982,29 @@ GLOBAL_LIST_EMPTY(fire_appearances) return span_boldwarning("[p_Their()] power level is... What?! [power_level]?!?!") return span_notice("[p_Their()] power level is [power_level].") +#define DAMAGE_BOOST 2 +#define DAMAGE_MULT 0.1 +#define SPEED_BOOST 0.1 +#define HEALTH_BOOST 5 + +/// Generally get stronger, as a saiyan would (or weaker if we pass a negative multiplier) +/mob/living/proc/saiyan_boost(multiplier = 1) + maxHealth += HEALTH_BOOST * multiplier // Fuck knows if this actually does anything + var/datum/action/cooldown/mob_cooldown/ki_blast/blast = locate() in actions + if (!isnull(blast)) + blast.damage_modifier += DAMAGE_MULT * multiplier + boost_movespeed -= SPEED_BOOST * multiplier + add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/saiyan_speed, TRUE, boost_movespeed) + + var/added_damage = DAMAGE_BOOST * multiplier + melee_damage_lower += added_damage + melee_damage_upper += added_damage + +#undef DAMAGE_BOOST +#undef DAMAGE_MULT +#undef SPEED_BOOST +#undef HEALTH_BOOST + /// Returns an arbitrary number which very roughly correlates with how buff you look /mob/living/proc/calculate_fitness() var/athletics_level = mind?.get_skill_level(/datum/skill/athletics) || 1 diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index 53d8b1fae9c..31b28a4b1a3 100644 --- a/code/modules/mob/living/living_defines.dm +++ b/code/modules/mob/living/living_defines.dm @@ -233,5 +233,8 @@ /// What our current gravity state is. Used to avoid duplicate animates and such var/gravity_state = null + /// How much fasterer are we as a result of martial arts superpowers? + var/boost_movespeed = 0 + /// How long it takes to return to 0 stam var/stamina_regen_time = 10 SECONDS From 0976e57afb829615bde2df3a25adc28fb011516f Mon Sep 17 00:00:00 2001 From: Jacquerel Date: Sun, 17 Mar 2024 00:32:41 +0000 Subject: [PATCH 12/33] Forgot the icon --- code/modules/mob/living/brain/brain_saiyan.dm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/code/modules/mob/living/brain/brain_saiyan.dm b/code/modules/mob/living/brain/brain_saiyan.dm index 53d4192f25d..324d7847526 100644 --- a/code/modules/mob/living/brain/brain_saiyan.dm +++ b/code/modules/mob/living/brain/brain_saiyan.dm @@ -194,11 +194,13 @@ /datum/action/cooldown/mob_cooldown/kaioken name = "Kaio-ken Technique" desc = "A technique taught by the powerful Kais of Otherworld, allows the user to multiply their ki at great personal risk. The effects can be stacked multiplicatively to greatly increase fighting strength, however overuse may cause immediate disintegration." + button_icon = 'icons/mob/actions/actions_cult.dmi' + button_icon_state = "tele" + background_icon_state = "bg_demon" cooldown_time = 3 SECONDS shared_cooldown = NONE melee_cooldown_time = NONE click_to_activate = FALSE - background_icon_state = "bg_demon" // This is basically handled entirely by the status effect /datum/action/cooldown/mob_cooldown/kaioken/Activate(mob/living/target) From 1e697aa0aa174178006e689c194cd5a4d108a655 Mon Sep 17 00:00:00 2001 From: Jacquerel Date: Sun, 17 Mar 2024 02:15:56 +0000 Subject: [PATCH 13/33] super saiyan --- code/modules/mob/living/brain/brain_saiyan.dm | 88 +++++++++++++++++++ .../carbon/human/species_types/saiyan.dm | 21 +++++ 2 files changed, 109 insertions(+) diff --git a/code/modules/mob/living/brain/brain_saiyan.dm b/code/modules/mob/living/brain/brain_saiyan.dm index 324d7847526..e9d8c558533 100644 --- a/code/modules/mob/living/brain/brain_saiyan.dm +++ b/code/modules/mob/living/brain/brain_saiyan.dm @@ -261,4 +261,92 @@ exclamations += "!" owner.say("Kaio-ken... times [convert_integer_to_words(stacks)][exclamations]") +/datum/action/cooldown/mob_cooldown/super_saiyan + name = "Power Up" + desc = "Concentrate your energy, surpass your limits, and go even further beyond!" + button_icon = 'icons/mob/actions/actions_spells.dmi' + button_icon_state = "sacredflame" + background_icon_state = "bg_demon" + cooldown_time = 4 MINUTES + cooldown_rounding = 0 + shared_cooldown = NONE + melee_cooldown_time = NONE + click_to_activate = FALSE + /// How long does it take to assume your next form? + var/charge_time = 30 SECONDS + /// Storage for our scream timer + var/yell_timer + +/datum/action/cooldown/mob_cooldown/super_saiyan/Activate(mob/living/target) + StartCooldown(360 SECONDS) + + target.add_filter(GOKU_FILTER, 2, list("type" = "outline", "color" = COLOR_VIVID_YELLOW, "alpha" = 0, "size" = 1)) + var/filter = target.get_filter(GOKU_FILTER) + animate(filter, alpha = 200, time = 0.5 SECONDS, loop = -1) + animate(alpha = 0, time = 0.5 SECONDS) + yell() + + owner.balloon_alert(owner, "charging...") + var/succeeded = do_after(target, delay = charge_time, target = target) + + deltimer(yell_timer) + animate(filter) + target.remove_filter(GOKU_FILTER) + + if (succeeded) + charge_time = max(6 SECONDS, charge_time - 2 SECONDS) + target.apply_status_effect(/datum/status_effect/super_saiyan) + StartCooldown() + return TRUE + StartCooldown(10 SECONDS) + return TRUE + +/// Aaaaaaa Aaaaaaaa aaaaaa AAAAAAAa a AaAAAAAA aAAAAAAAAAAAAAAAAAAAAAAA!!!! +/datum/action/cooldown/mob_cooldown/super_saiyan/proc/yell() + owner.emote("scream") + yell_timer = addtimer(CALLBACK(src, PROC_REF(yell)), rand(1 SECONDS, 3 SECONDS), TIMER_DELETE_ME | TIMER_STOPPABLE) + +/datum/status_effect/super_saiyan + id = "super_saiyan" + alert_type = null + duration = 45 SECONDS + /// How much strength do we gain? + var/power_multiplier = 8 + +/datum/status_effect/super_saiyan/on_apply() + . = ..() + to_chat(owner, span_notice("Your power surges!")) + + + new /obj/effect/temp_visual/explosion/fast(get_turf(owner)) + + owner.add_filter(GOKU_FILTER, 2, list("type" = "outline", "color" = COLOR_VIVID_YELLOW, "alpha" = 0, "size" = 2.5)) + var/filter = owner.get_filter(GOKU_FILTER) + animate(filter, alpha = 200, time = 0.25 SECONDS, loop = -1) + animate(alpha = 0, time = 0.25 SECONDS) + owner.saiyan_boost(multiplier = power_multiplier) + + playsound(owner, 'sound/magic/charge.ogg', vol = 80) + + var/list/destroy_turfs = circle_range_turfs(center = owner, radius = 2) + for (var/turf/check_turf as anything in destroy_turfs) + if (!isfloorturf(check_turf) || isindestructiblefloor(check_turf)) + continue + if (prob(75)) + continue + check_turf.break_tile() + + var/transform_area = get_area(owner) + for(var/mob/living/player as anything in GLOB.alive_player_list) + if (player == owner || !HAS_TRAIT(player, TRAIT_MARTIAL_VISION)) + continue + to_chat(player, span_warning("You sense an incredible power level coming from the direction of the [transform_area]!")) + +/datum/status_effect/super_saiyan/on_remove() + . = ..() + var/filter = owner.get_filter(GOKU_FILTER) + animate(filter) + owner.remove_filter(GOKU_FILTER) + owner.saiyan_boost(multiplier = -power_multiplier) + #undef GOKU_FILTER diff --git a/code/modules/mob/living/carbon/human/species_types/saiyan.dm b/code/modules/mob/living/carbon/human/species_types/saiyan.dm index d13ee4b30a7..25abb8a4070 100644 --- a/code/modules/mob/living/carbon/human/species_types/saiyan.dm +++ b/code/modules/mob/living/carbon/human/species_types/saiyan.dm @@ -38,6 +38,27 @@ // return TRUE // return ..() +/datum/species/saiyan/get_scream_sound(mob/living/carbon/human/human) + if(human.physique == MALE) + if(prob(1)) + return 'sound/voice/human/wilhelm_scream.ogg' + return pick( + 'sound/voice/human/malescream_1.ogg', + 'sound/voice/human/malescream_2.ogg', + 'sound/voice/human/malescream_3.ogg', + 'sound/voice/human/malescream_4.ogg', + 'sound/voice/human/malescream_5.ogg', + 'sound/voice/human/malescream_6.ogg', + ) + + return pick( + 'sound/voice/human/femalescream_1.ogg', + 'sound/voice/human/femalescream_2.ogg', + 'sound/voice/human/femalescream_3.ogg', + 'sound/voice/human/femalescream_4.ogg', + 'sound/voice/human/femalescream_5.ogg', + ) + /datum/species/saiyan/on_species_gain(mob/living/carbon/human/human_who_gained_species, datum/species/old_species, pref_load) . = ..() RegisterSignal(human_who_gained_species, COMSIG_SAIYAN_SURVIVOR, PROC_REF(on_survived_boost)) From a4516231da2932941a8e25a75ffb18a2563b655e Mon Sep 17 00:00:00 2001 From: Jacquerel Date: Sun, 17 Mar 2024 03:11:56 +0000 Subject: [PATCH 14/33] cool ape! --- .../basic/farm_animals/gorilla/gorilla.dm | 27 ++++++++++++++++-- code/modules/mob/living/brain/brain_saiyan.dm | 2 +- code/modules/surgery/organs/external/tails.dm | 2 +- icons/mob/simple/gorilla.dmi | Bin 7240 -> 10480 bytes 4 files changed, 26 insertions(+), 5 deletions(-) diff --git a/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm b/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm index b706e10b816..93889d68263 100644 --- a/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm +++ b/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm @@ -203,6 +203,7 @@ desc = "A large and destructive ape-like creature, capable of surviving the depths of space and discharging energy beams." unsuitable_atmos_damage = 0 unsuitable_cold_damage = 0 + basic_mob_flags = DEL_ON_DEATH /mob/living/basic/gorilla/saiyan/Initialize(mapload) . = ..() @@ -214,6 +215,21 @@ cooldown_time = 0.5 SECONDS, \ ) RegisterSignal(src, COMSIG_ATOM_AFTER_ATTACKEDBY, PROC_REF(check_tail_sever)) + update_appearance(UPDATE_ICON) + +/mob/living/basic/gorilla/saiyan/update_icon_state() + . = ..() + if (stat == DEAD) + return + icon_state = "great_ape" + +/mob/living/basic/gorilla/saiyan/death(gibbed) + if (has_status_effect(/datum/status_effect/shapechange_mob)) + return ..() + var/mob/living/corpse = spawn_fake_saiyan() + corpse.death() + corpse.setBruteLoss(maxHealth, TRUE, TRUE) + return ..() /// Cut off his tail! It's the only way! /mob/living/basic/gorilla/saiyan/proc/check_tail_sever(mob/living/target, obj/item/weapon, mob/attacker, proximity_flag, click_parameters) @@ -229,9 +245,7 @@ var/datum/status_effect/shapechange_mob/shapechange_status = has_status_effect(/datum/status_effect/shapechange_mob) var/mob/living/carbon/saiyan if (isnull(shapechange_status)) - saiyan = new /mob/living/carbon/human/species/saiyan(loc) - saiyan.name = name - saiyan.real_name = name + saiyan = spawn_fake_saiyan() else saiyan = shapechange_status.caster_mob @@ -243,4 +257,11 @@ remove_status_effect(/datum/status_effect/shapechange_mob) qdel(src) +/// Create a fake saiyan +/mob/living/basic/gorilla/saiyan/proc/spawn_fake_saiyan() + var/mob/saiyan = new /mob/living/carbon/human/species/saiyan(loc) + saiyan.name = name + saiyan.real_name = name + return saiyan + #undef GORILLA_HANDS_LAYER diff --git a/code/modules/mob/living/brain/brain_saiyan.dm b/code/modules/mob/living/brain/brain_saiyan.dm index e9d8c558533..da1e199ee9f 100644 --- a/code/modules/mob/living/brain/brain_saiyan.dm +++ b/code/modules/mob/living/brain/brain_saiyan.dm @@ -261,6 +261,7 @@ exclamations += "!" owner.say("Kaio-ken... times [convert_integer_to_words(stacks)][exclamations]") +/// Achieve the legend /datum/action/cooldown/mob_cooldown/super_saiyan name = "Power Up" desc = "Concentrate your energy, surpass your limits, and go even further beyond!" @@ -317,7 +318,6 @@ . = ..() to_chat(owner, span_notice("Your power surges!")) - new /obj/effect/temp_visual/explosion/fast(get_turf(owner)) owner.add_filter(GOKU_FILTER, 2, list("type" = "outline", "color" = COLOR_VIVID_YELLOW, "alpha" = 0, "size" = 2.5)) diff --git a/code/modules/surgery/organs/external/tails.dm b/code/modules/surgery/organs/external/tails.dm index ca866d9d8cc..c7e6085783b 100644 --- a/code/modules/surgery/organs/external/tails.dm +++ b/code/modules/surgery/organs/external/tails.dm @@ -210,7 +210,7 @@ /// When we move check if we are exposed to space /obj/item/organ/external/tail/monkey/saiyan/proc/on_moved() SIGNAL_HANDLER - if (isnull(owner)) + if (isnull(owner) || owner.stat == DEAD) return if (is_space_exposed_turf(get_turf(src))) go_ape(owner) diff --git a/icons/mob/simple/gorilla.dmi b/icons/mob/simple/gorilla.dmi index 77d03fa606d2596f054018eef7fa4c48009d502c..aa43c01fb5def77156865141b32a070459b5930a 100644 GIT binary patch literal 10480 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 D==}ga From c0eeed6008e7be0382e055fbbbe2931b8b007f98 Mon Sep 17 00:00:00 2001 From: Jacquerel Date: Sun, 17 Mar 2024 04:13:51 +0000 Subject: [PATCH 15/33] Dead men use no tails plus some other visuals --- .../basic/farm_animals/gorilla/gorilla.dm | 22 +++---- .../basic/lavaland/watcher/watcher_gaze.dm | 4 ++ code/modules/mob/living/brain/brain_saiyan.dm | 62 +++++++++++++++---- code/modules/surgery/organs/external/tails.dm | 9 ++- 4 files changed, 70 insertions(+), 27 deletions(-) diff --git a/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm b/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm index 93889d68263..bad263067a0 100644 --- a/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm +++ b/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm @@ -224,11 +224,9 @@ icon_state = "great_ape" /mob/living/basic/gorilla/saiyan/death(gibbed) - if (has_status_effect(/datum/status_effect/shapechange_mob)) - return ..() - var/mob/living/corpse = spawn_fake_saiyan() + var/mob/living/corpse = get_internal_saiyan() corpse.death() - corpse.setBruteLoss(maxHealth, TRUE, TRUE) + corpse.setBruteLoss(corpse.maxHealth, TRUE, TRUE) return ..() /// Cut off his tail! It's the only way! @@ -242,13 +240,7 @@ target.visible_message(span_warning("[src]'s tail falls to the ground, severed completely!")) INVOKE_ASYNC(target, TYPE_PROC_REF(/mob, emote), "scream") - var/datum/status_effect/shapechange_mob/shapechange_status = has_status_effect(/datum/status_effect/shapechange_mob) - var/mob/living/carbon/saiyan - if (isnull(shapechange_status)) - saiyan = spawn_fake_saiyan() - else - saiyan = shapechange_status.caster_mob - + var/mob/living/carbon/saiyan = get_internal_saiyan() if (istype(saiyan)) var/obj/item/organ/external/tail/saiyan_tail = saiyan.get_organ_slot(ORGAN_SLOT_EXTERNAL_TAIL) saiyan_tail.Remove(saiyan) @@ -257,8 +249,12 @@ remove_status_effect(/datum/status_effect/shapechange_mob) qdel(src) -/// Create a fake saiyan -/mob/living/basic/gorilla/saiyan/proc/spawn_fake_saiyan() +/// Find our normal body or return a fake saiyan +/mob/living/basic/gorilla/saiyan/proc/get_internal_saiyan() + var/datum/status_effect/shapechange_mob/shapechange_status = has_status_effect(/datum/status_effect/shapechange_mob) + if (!isnull(shapechange_status)) + return shapechange_status.caster_mob + var/mob/saiyan = new /mob/living/carbon/human/species/saiyan(loc) saiyan.name = name saiyan.real_name = name diff --git a/code/modules/mob/living/basic/lavaland/watcher/watcher_gaze.dm b/code/modules/mob/living/basic/lavaland/watcher/watcher_gaze.dm index df17ab3ba5f..4df6ebbc3bd 100644 --- a/code/modules/mob/living/basic/lavaland/watcher/watcher_gaze.dm +++ b/code/modules/mob/living/basic/lavaland/watcher/watcher_gaze.dm @@ -25,6 +25,8 @@ var/report_started = "'s eye glows ominously!" /// What do we report blinded people? var/blinded_source = "piercing gaze" + /// Should we stun ourselves after? + var/stop_self = TRUE /datum/action/cooldown/mob_cooldown/watcher_gaze/Activate(mob/living/target) show_indicator_overlay("eye_open") @@ -68,6 +70,8 @@ ) flick_overlay_global(flashed_overlay, show_to = GLOB.clients, duration = animation_time) stage_timer = addtimer(CALLBACK(src, PROC_REF(hide_eye)), animation_time, TIMER_STOPPABLE) + if (!stop_self) + return var/mob/living/living_owner = owner living_owner.Stun(1.5 SECONDS, ignore_canstun = TRUE) diff --git a/code/modules/mob/living/brain/brain_saiyan.dm b/code/modules/mob/living/brain/brain_saiyan.dm index da1e199ee9f..6b396843abd 100644 --- a/code/modules/mob/living/brain/brain_saiyan.dm +++ b/code/modules/mob/living/brain/brain_saiyan.dm @@ -7,6 +7,13 @@ brain_size = 0.5 /// What buttons did we give out var/list/granted_abilities = list() + /// Saiyans gain one of these cool karate moves at random + var/static/list/saiyan_skills = list( + /datum/action/cooldown/mob_cooldown/brimbeam/kamehameha, + /datum/action/cooldown/mob_cooldown/kaioken, + /datum/action/cooldown/mob_cooldown/super_saiyan, + /datum/action/cooldown/mob_cooldown/watcher_gaze/solar_flare, + ) /obj/item/organ/internal/brain/saiyan/on_mob_insert(mob/living/carbon/organ_owner, special, movement_flags) . = ..() @@ -18,6 +25,11 @@ flight.Grant(organ_owner) granted_abilities += flight + var/random_skill_path = pick(saiyan_skills) + var/datum/action/random_skill = new random_skill_path(organ_owner) + random_skill.Grant(organ_owner) + granted_abilities += random_skill + /obj/item/organ/internal/brain/saiyan/on_mob_remove(mob/living/carbon/organ_owner, special) . = ..() QDEL_LIST(granted_abilities) @@ -135,7 +147,7 @@ /// Things we still need to say, before it's too late var/speech_timers = list() -/datum/action/cooldown/mob_cooldown/brimbeam/kamehameha/Activate(atom/target) +/datum/action/cooldown/mob_cooldown/brimbeam/kamehameha/Activate(mob/living/target) owner.add_filter(GOKU_FILTER, 2, list("type" = "outline", "color" = COLOR_CYAN, "alpha" = 0, "size" = 1)) var/filter = owner.get_filter(GOKU_FILTER) animate(filter, alpha = 200, time = 0.5 SECONDS, loop = -1) @@ -149,24 +161,24 @@ current_interval += speech_interval speech_timers += timer playsound(owner, 'sound/items/modsuit/loader_charge.ogg', 75, TRUE) - return ..() -/datum/action/cooldown/mob_cooldown/brimbeam/kamehameha/fire_laser() - . = ..() - if (.) - owner.say("...HA!!!!!") + var/mob/living/living_owner = owner + var/lightbulb = istype(living_owner) ? living_owner.mob_light(2, 1, LIGHT_COLOR_CYAN) : null -/datum/action/cooldown/mob_cooldown/brimbeam/kamehameha/StartCooldown(override_cooldown_time, override_melee_cooldown_time) . = ..() - if (override_cooldown_time == 360 SECONDS) // Ignore the one we set while the ability is processing - return + + QDEL_NULL(lightbulb) for (var/timer as anything in speech_timers) deltimer(timer) speech_timers = list() - var/filter = owner.get_filter(GOKU_FILTER) animate(filter) owner.remove_filter(GOKU_FILTER) +/datum/action/cooldown/mob_cooldown/brimbeam/kamehameha/fire_laser() + . = ..() + if (.) + owner.say("...HA!!!!!") + /datum/action/cooldown/mob_cooldown/brimbeam/kamehameha/on_fail() owner.visible_message(span_notice("...and launches it straight into a wall, wasting their energy.")) @@ -185,6 +197,7 @@ wait_delay = 1 SECONDS report_started = "holds their hands to their forehead!" blinded_source = "flash of light!" + stop_self = FALSE /datum/action/cooldown/mob_cooldown/watcher_gaze/solar_flare/trigger_effect() . = ..() @@ -221,6 +234,8 @@ var/power_multiplier = 3 /// Percentage chance to die instantly, will be multiplied by current stacks var/death_chance = 5 + /// Light holder + var/lightbulb /datum/status_effect/stacking/kaioken/on_apply() . = ..() @@ -228,8 +243,10 @@ var/filter = owner.get_filter(GOKU_FILTER) animate(filter, alpha = 200, time = 0.5 SECONDS, loop = -1) animate(alpha = 0, time = 0.5 SECONDS) + lightbulb = owner.mob_light(2, 1, LIGHT_COLOR_INTENSE_RED) /datum/status_effect/stacking/kaioken/on_remove() + QDEL_NULL(lightbulb) var/filter = owner.get_filter(GOKU_FILTER) animate(filter) owner.remove_filter(GOKU_FILTER) @@ -281,24 +298,28 @@ /datum/action/cooldown/mob_cooldown/super_saiyan/Activate(mob/living/target) StartCooldown(360 SECONDS) - target.add_filter(GOKU_FILTER, 2, list("type" = "outline", "color" = COLOR_VIVID_YELLOW, "alpha" = 0, "size" = 1)) + target.add_filter(GOKU_FILTER, 2, list("type" = "outline", "color" = COLOR_GOLD, "alpha" = 0, "size" = 1)) var/filter = target.get_filter(GOKU_FILTER) animate(filter, alpha = 200, time = 0.5 SECONDS, loop = -1) animate(alpha = 0, time = 0.5 SECONDS) yell() + var/lightbulb = target.mob_light(3, 1, LIGHT_COLOR_BRIGHT_YELLOW) + owner.balloon_alert(owner, "charging...") var/succeeded = do_after(target, delay = charge_time, target = target) deltimer(yell_timer) animate(filter) target.remove_filter(GOKU_FILTER) + QDEL_NULL(lightbulb) if (succeeded) charge_time = max(6 SECONDS, charge_time - 2 SECONDS) target.apply_status_effect(/datum/status_effect/super_saiyan) StartCooldown() return TRUE + StartCooldown(10 SECONDS) return TRUE @@ -313,6 +334,10 @@ duration = 45 SECONDS /// How much strength do we gain? var/power_multiplier = 8 + /// What colour was our hair? + var/previous_hair_colour + /// Light holder + var/atom/lightbulb /datum/status_effect/super_saiyan/on_apply() . = ..() @@ -320,12 +345,19 @@ new /obj/effect/temp_visual/explosion/fast(get_turf(owner)) - owner.add_filter(GOKU_FILTER, 2, list("type" = "outline", "color" = COLOR_VIVID_YELLOW, "alpha" = 0, "size" = 2.5)) + if (ishuman(owner)) + var/mob/living/carbon/human/human_owner = owner + previous_hair_colour = human_owner.hair_color + human_owner.set_haircolor(COLOR_GOLD, update = TRUE) + + owner.add_filter(GOKU_FILTER, 2, list("type" = "outline", "color" = COLOR_GOLD, "alpha" = 0, "size" = 2.5)) var/filter = owner.get_filter(GOKU_FILTER) animate(filter, alpha = 200, time = 0.25 SECONDS, loop = -1) animate(alpha = 0, time = 0.25 SECONDS) owner.saiyan_boost(multiplier = power_multiplier) + lightbulb = owner.mob_light(5, 1, COLOR_GOLD) + playsound(owner, 'sound/magic/charge.ogg', vol = 80) var/list/destroy_turfs = circle_range_turfs(center = owner, radius = 2) @@ -344,9 +376,15 @@ /datum/status_effect/super_saiyan/on_remove() . = ..() + QDEL_NULL(lightbulb) + var/filter = owner.get_filter(GOKU_FILTER) animate(filter) owner.remove_filter(GOKU_FILTER) owner.saiyan_boost(multiplier = -power_multiplier) + if (ishuman(owner)) + var/mob/living/carbon/human/human_owner = owner + human_owner.set_haircolor(previous_hair_colour, update = TRUE) + #undef GOKU_FILTER diff --git a/code/modules/surgery/organs/external/tails.dm b/code/modules/surgery/organs/external/tails.dm index c7e6085783b..0b898342abe 100644 --- a/code/modules/surgery/organs/external/tails.dm +++ b/code/modules/surgery/organs/external/tails.dm @@ -210,7 +210,7 @@ /// When we move check if we are exposed to space /obj/item/organ/external/tail/monkey/saiyan/proc/on_moved() SIGNAL_HANDLER - if (isnull(owner) || owner.stat == DEAD) + if (isnull(owner)) return if (is_space_exposed_turf(get_turf(src))) go_ape(owner) @@ -235,7 +235,7 @@ /// Start being an ape /obj/item/organ/external/tail/monkey/saiyan/proc/go_ape() - if (HAS_TRAIT(owner, TRAIT_SHAPESHIFTED)) + if (HAS_TRAIT(owner, TRAIT_SHAPESHIFTED) || owner.stat == DEAD) return owner.visible_message(span_warning("[owner] transforms into a huge, ape-like creature!")) var/mob/living/basic/gorilla/saiyan/monkie = new(owner.loc) @@ -244,6 +244,11 @@ monkie.name = owner.real_name monkie.real_name = owner.real_name monkie.apply_status_effect(/datum/status_effect/shapechange_mob, owner) + RegisterSignal(monkie, COMSIG_LIVING_DEATH, PROC_REF(ape_died)) + +/obj/item/organ/external/tail/monkey/saiyan/proc/ape_died() + SIGNAL_HANDLER + owner.death() /// Stop being an ape /obj/item/organ/external/tail/monkey/saiyan/proc/escape_ape() From 1dea380c325a1c96d3b1f3ff403a0e1fb94015f7 Mon Sep 17 00:00:00 2001 From: Jacquerel Date: Sun, 17 Mar 2024 04:47:28 +0000 Subject: [PATCH 16/33] Lore reasons --- code/__DEFINES/traits/declarations.dm | 2 ++ code/modules/mob/living/brain/brain_saiyan.dm | 7 +++++++ .../bodyparts/species_parts/saiyan_bodyparts.dm | 11 +++++++++++ 3 files changed, 20 insertions(+) diff --git a/code/__DEFINES/traits/declarations.dm b/code/__DEFINES/traits/declarations.dm index e752731d3e1..d39ecd4086c 100644 --- a/code/__DEFINES/traits/declarations.dm +++ b/code/__DEFINES/traits/declarations.dm @@ -868,6 +868,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_SAIYAN_STRENGTH "saiyan_strength" /// Allows you to detect power levels #define TRAIT_MARTIAL_VISION "martial_vision" +/// Are you the legendary super saiyan? If so, you are allowed to become blonde. +#define TRAIT_SUPER_SAIYAN "super_saiyan" //quirk traits #define TRAIT_ALCOHOL_TOLERANCE "alcohol_tolerance" diff --git a/code/modules/mob/living/brain/brain_saiyan.dm b/code/modules/mob/living/brain/brain_saiyan.dm index 6b396843abd..9455fed43bf 100644 --- a/code/modules/mob/living/brain/brain_saiyan.dm +++ b/code/modules/mob/living/brain/brain_saiyan.dm @@ -100,6 +100,10 @@ damage_type = BRUTE hitsound = 'sound/weapons/sear_disabler.ogg' hitsound_wall = 'sound/weapons/sear_disabler.ogg' + light_system = OVERLAY_LIGHT + light_range = 1 + light_power = 1.4 + light_color = LIGHT_COLOR_CYAN /// Saiyans can fly /datum/action/cooldown/mob_cooldown/saiyan_flight @@ -344,6 +348,7 @@ to_chat(owner, span_notice("Your power surges!")) new /obj/effect/temp_visual/explosion/fast(get_turf(owner)) + ADD_TRAIT(owner, TRAIT_SUPER_SAIYAN, "[STATUS_EFFECT_TRAIT]_[id]") if (ishuman(owner)) var/mob/living/carbon/human/human_owner = owner @@ -378,6 +383,8 @@ . = ..() QDEL_NULL(lightbulb) + REMOVE_TRAIT(owner, TRAIT_SUPER_SAIYAN, "[STATUS_EFFECT_TRAIT]_[id]") + var/filter = owner.get_filter(GOKU_FILTER) animate(filter) owner.remove_filter(GOKU_FILTER) diff --git a/code/modules/surgery/bodyparts/species_parts/saiyan_bodyparts.dm b/code/modules/surgery/bodyparts/species_parts/saiyan_bodyparts.dm index ae02905d070..79d1fcdb8be 100644 --- a/code/modules/surgery/bodyparts/species_parts/saiyan_bodyparts.dm +++ b/code/modules/surgery/bodyparts/species_parts/saiyan_bodyparts.dm @@ -2,11 +2,22 @@ unarmed_damage_low = 5 unarmed_damage_high = 7 unarmed_effectiveness = 15 + /// All TRUE saiyans have this colour hair + var/saiyan_hair_colour = "#292929" /obj/item/bodypart/head/saiyan/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_SAIYAN_STRENGTH, INNATE_TRAIT) +/obj/item/bodypart/head/saiyan/update_hair_and_lips(dropping_limb, is_creating) + . = ..() + if (HAS_TRAIT(owner, TRAIT_SUPER_SAIYAN)) + return + // Sorry, you are not legendary enough to dye your hair + var/mob/living/carbon/human/human_head_owner = owner + human_head_owner?.hair_color = saiyan_hair_colour + hair_color = saiyan_hair_colour + /obj/item/bodypart/chest/saiyan unarmed_damage_low = 5 // Good luck actually dealing damage with your chest unarmed_damage_high = 7 From 499fc04e4c52bea07601f6d08038aac4c5c4b7e6 Mon Sep 17 00:00:00 2001 From: Jacquerel Date: Sat, 30 Mar 2024 18:58:43 +0000 Subject: [PATCH 17/33] Ultra Instinct --- code/__DEFINES/traits/declarations.dm | 2 +- code/modules/mob/living/brain/brain_saiyan.dm | 106 +++++++++++++++++- .../species_parts/saiyan_bodyparts.dm | 2 +- 3 files changed, 104 insertions(+), 6 deletions(-) diff --git a/code/__DEFINES/traits/declarations.dm b/code/__DEFINES/traits/declarations.dm index d39ecd4086c..829bdf0d6b4 100644 --- a/code/__DEFINES/traits/declarations.dm +++ b/code/__DEFINES/traits/declarations.dm @@ -869,7 +869,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai /// Allows you to detect power levels #define TRAIT_MARTIAL_VISION "martial_vision" /// Are you the legendary super saiyan? If so, you are allowed to become blonde. -#define TRAIT_SUPER_SAIYAN "super_saiyan" +#define TRAIT_POWER_HAIR "thirty_dollar_haircut" //quirk traits #define TRAIT_ALCOHOL_TOLERANCE "alcohol_tolerance" diff --git a/code/modules/mob/living/brain/brain_saiyan.dm b/code/modules/mob/living/brain/brain_saiyan.dm index 9455fed43bf..ef34a9048de 100644 --- a/code/modules/mob/living/brain/brain_saiyan.dm +++ b/code/modules/mob/living/brain/brain_saiyan.dm @@ -240,14 +240,22 @@ var/death_chance = 5 /// Light holder var/lightbulb + /// What colour was our hair? + var/previous_hair_colour /datum/status_effect/stacking/kaioken/on_apply() . = ..() - owner.add_filter(GOKU_FILTER, 2, list("type" = "outline", "color" = COLOR_RED, "alpha" = 0, "size" = 1)) + owner.add_filter(GOKU_FILTER, 2, list("type" = "outline", "color" = COLOR_SOFT_RED, "alpha" = 0, "size" = 1)) var/filter = owner.get_filter(GOKU_FILTER) animate(filter, alpha = 200, time = 0.5 SECONDS, loop = -1) animate(alpha = 0, time = 0.5 SECONDS) - lightbulb = owner.mob_light(2, 1, LIGHT_COLOR_INTENSE_RED) + lightbulb = owner.mob_light(2, 1, LIGHT_COLOR_BUBBLEGUM) + + ADD_TRAIT(owner, TRAIT_POWER_HAIR, "[STATUS_EFFECT_TRAIT]_[id]") + if (ishuman(owner)) + var/mob/living/carbon/human/human_owner = owner + previous_hair_colour = human_owner.hair_color + human_owner.set_haircolor(COLOR_SOFT_RED, update = TRUE) /datum/status_effect/stacking/kaioken/on_remove() QDEL_NULL(lightbulb) @@ -255,6 +263,11 @@ animate(filter) owner.remove_filter(GOKU_FILTER) owner.saiyan_boost(-power_multiplier * stacks) + + REMOVE_TRAIT(owner, TRAIT_POWER_HAIR, "[STATUS_EFFECT_TRAIT]_[id]") + if (ishuman(owner)) + var/mob/living/carbon/human/human_owner = owner + human_owner.set_haircolor(previous_hair_colour, update = TRUE) return ..() /datum/status_effect/stacking/kaioken/refresh(effect, stacks_to_add) @@ -348,7 +361,7 @@ to_chat(owner, span_notice("Your power surges!")) new /obj/effect/temp_visual/explosion/fast(get_turf(owner)) - ADD_TRAIT(owner, TRAIT_SUPER_SAIYAN, "[STATUS_EFFECT_TRAIT]_[id]") + ADD_TRAIT(owner, TRAIT_POWER_HAIR, "[STATUS_EFFECT_TRAIT]_[id]") if (ishuman(owner)) var/mob/living/carbon/human/human_owner = owner @@ -383,7 +396,7 @@ . = ..() QDEL_NULL(lightbulb) - REMOVE_TRAIT(owner, TRAIT_SUPER_SAIYAN, "[STATUS_EFFECT_TRAIT]_[id]") + REMOVE_TRAIT(owner, TRAIT_POWER_HAIR, "[STATUS_EFFECT_TRAIT]_[id]") var/filter = owner.get_filter(GOKU_FILTER) animate(filter) @@ -394,4 +407,89 @@ var/mob/living/carbon/human/human_owner = owner human_owner.set_haircolor(previous_hair_colour, update = TRUE) +/// Dodge without thinking +/datum/action/cooldown/mob_cooldown/ultra_instinct + name = "Ultra Instinct" + desc = "Clear your mind and instinctually avoid incoming blows, until you take action yourself." + button_icon = 'icons/mob/actions/actions_spells.dmi' + button_icon_state = "chuuni" + background_icon_state = "bg_demon" + cooldown_time = 90 SECONDS + shared_cooldown = NONE + melee_cooldown_time = NONE + click_to_activate = FALSE + +// This is basically handled entirely by the status effect +/datum/action/cooldown/mob_cooldown/ultra_instinct/Activate(mob/living/target) + target.apply_status_effect(/datum/status_effect/ultra_instinct) + StartCooldown() + return TRUE + +/datum/status_effect/ultra_instinct + id = "ultra_instinct" + alert_type = null + duration = 90 SECONDS + /// Light holder + var/atom/lightbulb + /// What colour was our hair? + var/previous_hair_colour + +/datum/status_effect/ultra_instinct/on_apply() + . = ..() + owner.add_filter(GOKU_FILTER, 2, list("type" = "outline", "color" = COLOR_CYAN, "alpha" = 0, "size" = 2)) + var/filter = owner.get_filter(GOKU_FILTER) + animate(filter, alpha = 200, time = 0.5 SECONDS, loop = -1) + animate(alpha = 0, time = 0.5 SECONDS) + lightbulb = owner.mob_light(2, 1, LIGHT_COLOR_CYAN) + + ADD_TRAIT(owner, TRAIT_POWER_HAIR, "[STATUS_EFFECT_TRAIT]_[id]") + if (ishuman(owner)) + var/mob/living/carbon/human/human_owner = owner + previous_hair_colour = human_owner.hair_color + human_owner.set_haircolor(COLOR_CYAN, update = TRUE) + + RegisterSignals(owner, list(COMSIG_MOB_ATTACK_HAND, COMSIG_LIVING_GRAB, COMSIG_MOB_ITEM_ATTACK, COMSIG_MOB_THROW), PROC_REF(took_action)) + RegisterSignal(owner, COMSIG_LIVING_CHECK_BLOCK, PROC_REF(on_hit)) + +/datum/status_effect/ultra_instinct/on_remove() + QDEL_NULL(lightbulb) + var/filter = owner.get_filter(GOKU_FILTER) + animate(filter) + owner.remove_filter(GOKU_FILTER) + + REMOVE_TRAIT(owner, TRAIT_POWER_HAIR, "[STATUS_EFFECT_TRAIT]_[id]") + if (ishuman(owner)) + var/mob/living/carbon/human/human_owner = owner + human_owner.set_haircolor(previous_hair_colour, update = TRUE) + + UnregisterSignal(owner, list( + COMSIG_LIVING_CHECK_BLOCK, + COMSIG_LIVING_GRAB, + COMSIG_MOB_ATTACK_HAND, + COMSIG_MOB_ITEM_ATTACK, + COMSIG_MOB_THROW + )) + return ..() + +/// Called when we do something +/datum/status_effect/ultra_instinct/proc/took_action() + SIGNAL_HANDLER + qdel(src) + +/// Called when something hits us +/datum/status_effect/ultra_instinct/proc/on_hit(mob/living/source) + SIGNAL_HANDLER + source.balloon_alert_to_viewers("dodged") + var/turf/current = get_turf(source) + var/list/valid_turfs = list() + for (var/turf/open/check_turf in orange(source, 1)) + if (check_turf.is_blocked_turf(exclude_mobs = FALSE, source_atom = source)) + continue + valid_turfs += check_turf + if (length(valid_turfs)) + var/turf/land_turf = pick(valid_turfs) + source.Move(land_turf, get_dir(current, land_turf)) + new /obj/effect/temp_visual/jet_plume(current) + return SUCCESSFUL_BLOCK + #undef GOKU_FILTER diff --git a/code/modules/surgery/bodyparts/species_parts/saiyan_bodyparts.dm b/code/modules/surgery/bodyparts/species_parts/saiyan_bodyparts.dm index 79d1fcdb8be..de6b9be37a9 100644 --- a/code/modules/surgery/bodyparts/species_parts/saiyan_bodyparts.dm +++ b/code/modules/surgery/bodyparts/species_parts/saiyan_bodyparts.dm @@ -11,7 +11,7 @@ /obj/item/bodypart/head/saiyan/update_hair_and_lips(dropping_limb, is_creating) . = ..() - if (HAS_TRAIT(owner, TRAIT_SUPER_SAIYAN)) + if (HAS_TRAIT(owner, TRAIT_POWER_HAIR)) return // Sorry, you are not legendary enough to dye your hair var/mob/living/carbon/human/human_head_owner = owner From ae462d78809e059bb41988f7d34029565a0cce05 Mon Sep 17 00:00:00 2001 From: Jacquerel Date: Sun, 31 Mar 2024 17:51:13 +0100 Subject: [PATCH 18/33] add it to the list --- code/modules/mob/living/brain/brain_saiyan.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/modules/mob/living/brain/brain_saiyan.dm b/code/modules/mob/living/brain/brain_saiyan.dm index ef34a9048de..b7b9e65609b 100644 --- a/code/modules/mob/living/brain/brain_saiyan.dm +++ b/code/modules/mob/living/brain/brain_saiyan.dm @@ -13,6 +13,7 @@ /datum/action/cooldown/mob_cooldown/kaioken, /datum/action/cooldown/mob_cooldown/super_saiyan, /datum/action/cooldown/mob_cooldown/watcher_gaze/solar_flare, + /datum/action/cooldown/mob_cooldown/ultra_instinct, ) /obj/item/organ/internal/brain/saiyan/on_mob_insert(mob/living/carbon/organ_owner, special, movement_flags) From 3decdbe34d7eadbe06a7fd5ad7eb37740d374bbf Mon Sep 17 00:00:00 2001 From: Jacquerel Date: Sun, 31 Mar 2024 18:36:28 +0100 Subject: [PATCH 19/33] Remove commented out code --- code/modules/mob/living/carbon/human/species_types/saiyan.dm | 3 --- 1 file changed, 3 deletions(-) diff --git a/code/modules/mob/living/carbon/human/species_types/saiyan.dm b/code/modules/mob/living/carbon/human/species_types/saiyan.dm index 25abb8a4070..4cc4fb0406a 100644 --- a/code/modules/mob/living/carbon/human/species_types/saiyan.dm +++ b/code/modules/mob/living/carbon/human/species_types/saiyan.dm @@ -34,9 +34,6 @@ /datum/species/saiyan/check_roundstart_eligible() return TRUE - // if(check_holidays(APRIL_FOOLS)) - // return TRUE - // return ..() /datum/species/saiyan/get_scream_sound(mob/living/carbon/human/human) if(human.physique == MALE) From a6f23790c6aa9fae8f9538779d742c9ffac34561 Mon Sep 17 00:00:00 2001 From: Jacquerel Date: Sun, 31 Mar 2024 18:42:00 +0100 Subject: [PATCH 20/33] Lint and remove debug log --- code/_globalvars/traits/_traits.dm | 3 +++ code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm | 1 - 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/code/_globalvars/traits/_traits.dm b/code/_globalvars/traits/_traits.dm index 304198cece3..82029b82033 100644 --- a/code/_globalvars/traits/_traits.dm +++ b/code/_globalvars/traits/_traits.dm @@ -431,6 +431,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_PLANT_SAFE" = TRAIT_PLANT_SAFE, "TRAIT_PLASMA_LOVER_METABOLISM" = TRAIT_PLASMA_LOVER_METABOLISM, "TRAIT_POSTERBOY" = TRAIT_POSTERBOY, + "TRAIT_POWER_HAIR" = TRAIT_POWER_HAIR, "TRAIT_PRESENT_VISION" = TRAIT_PRESENT_VISION, "TRAIT_PRESERVE_UI_WITHOUT_CLIENT" = TRAIT_PRESERVE_UI_WITHOUT_CLIENT, "TRAIT_PREVENT_IMPLANT_AUTO_EXPLOSION" = TRAIT_PREVENT_IMPLANT_AUTO_EXPLOSION, @@ -466,10 +467,12 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_ROD_SUPLEX" = TRAIT_ROD_SUPLEX, "TRAIT_ROUGHRIDER" = TRAIT_ROUGHRIDER, "TRAIT_SABRAGE_PRO" = TRAIT_SABRAGE_PRO, + "TRAIT_SAIYAN_STRENGTH" = TRAIT_SAIYAN_STRENGTH, "TRAIT_SECURITY_HUD" = TRAIT_SECURITY_HUD, "TRAIT_SEE_WORN_COLOURS" = TRAIT_SEE_WORN_COLOURS, "TRAIT_SELF_AWARE" = TRAIT_SELF_AWARE, "TRAIT_SETTLER" = TRAIT_SETTLER, + "TRAIT_SHAPESHIFTED" = TRAIT_SHAPESHIFTED, "TRAIT_SHAVED" = TRAIT_SHAVED, "TRAIT_SHIFTY_EYES" = TRAIT_SHIFTY_EYES, "TRAIT_SHOCKIMMUNE" = TRAIT_SHOCKIMMUNE, diff --git a/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm b/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm index bad263067a0..35fa7d7c954 100644 --- a/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm +++ b/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm @@ -234,7 +234,6 @@ SIGNAL_HANDLER if (!proximity_flag || weapon.force < 5 || weapon.get_sharpness() != SHARP_EDGED) return - to_chat(world, "trying it") if (!prob(3)) return target.visible_message(span_warning("[src]'s tail falls to the ground, severed completely!")) From 4c70ed131ee71c5a130e1b0d00650edff4aaf7ab Mon Sep 17 00:00:00 2001 From: Jacquerel Date: Sun, 31 Mar 2024 23:57:00 +0100 Subject: [PATCH 21/33] Superstition + screenshot --- code/datums/sprite_accessories.dm | 2 +- .../living/carbon/human/species_types/saiyan.dm | 2 +- ...creenshot_humanoids__datum_species_saiyan.png | Bin 0 -> 1037 bytes 3 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_saiyan.png diff --git a/code/datums/sprite_accessories.dm b/code/datums/sprite_accessories.dm index 132f35a06f9..73e84ade292 100644 --- a/code/datums/sprite_accessories.dm +++ b/code/datums/sprite_accessories.dm @@ -1816,7 +1816,7 @@ color_src = FALSE /datum/sprite_accessory/tails/saiyan/standard - name = "Monkey" + name = "Saiyan" icon_state = "monkey" /datum/sprite_accessory/pod_hair diff --git a/code/modules/mob/living/carbon/human/species_types/saiyan.dm b/code/modules/mob/living/carbon/human/species_types/saiyan.dm index 4cc4fb0406a..f89aa1ee4c7 100644 --- a/code/modules/mob/living/carbon/human/species_types/saiyan.dm +++ b/code/modules/mob/living/carbon/human/species_types/saiyan.dm @@ -25,7 +25,7 @@ BODY_ZONE_R_LEG = /obj/item/bodypart/leg/right/saiyan, ) external_organs = list( - /obj/item/organ/external/tail/monkey/saiyan = "Monkey", + /obj/item/organ/external/tail/monkey/saiyan = "Saiyan", ) /datum/species/saiyan/prepare_human_for_preview(mob/living/carbon/human/human) diff --git a/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_saiyan.png b/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_saiyan.png new file mode 100644 index 0000000000000000000000000000000000000000..73570bb23b68c49b2356d4a6037daf602b98a36c GIT binary patch literal 1037 zcmV+o1oHcdP)c6yeHp*WZbYq9i0LEiE(4&C%}e?j0T^rKz@bae^uiP}~3j z00DGTPE!Ct=GbNc003orR9JLGWpiV4X>fFDZ*Bkpc$`yKaB_9`^iy#0_2eo`Eh^5; z&r`5fFwryM;w;ZhDainGjE%TBGg33tGfE(w;*!LYR3KAHiHkEOv#1!Po{KZBC^0t` z#5UwoR&e!m0hvG#55QPB|2g7nH@g=F^$bSEq z>{%qcNd&l){^?|j$F`EQ`?11^Jwkl9A*K8~T@9)iA%|h;>RKtK+YwR&(9s{H+6)^d zRYQk@3YC0l0UnLQ49c{okVf$^j}3h*tWkK`W{H*w(6?;@0^0c?D6QK0!Vwu`h+ISW z&*Em;e-B!A+Q5wUH}<;)_ejOrTOl|F7QgQUee}#eoJj^PDGg~WouTCoYYqG z3hs8hCoip*bJ_yH%Nis1hvW0h&*Nb)&FXkmoiIyfms|lw?*g)@ZIT-R)#u6{_=f;@0`3Ab#{BU$eH>q3 zN5LQCm-N%y+i9G{H1b7NpT?q(Q&kt|)9HM^h|8HTzMy}bA@3M~ySnNd0QLtx15xsa zc6YS1-Z2ov1N#4_86Y>RU!s+d1BWz9umh{Qa$Maawo>cP3|IoKalAGGLTmvUe2%`mV=mMwuZk z04L8uVdYY|Z9&TkQ*;32Q|3mG@O1^H?bE#qXm$##3S0pY7tjTu1S){fi@?pF&r7-o zAdU(jog8<1ZvL5VDhIW;a?uc!*(2Qi!D0}wEEy(2a_?*GwONCA$O!)J55%?A`#ns6 zJsh52S{1xJ9}XO|_u{=jxOV$pPFD8YH>=X7ysP^IZd<+lg|ISU9|+z2Lg?lH2QUCf z($oV?IFNdP()>GwY4!-c05%7gmV8+}M0?E5zYSPC!u#lbHw~j&;00000NkvXX Hu0mjf_0i?( literal 0 HcmV?d00001 From 5124f8736b56f44a62f21ae1aa0d1f0f6d109326 Mon Sep 17 00:00:00 2001 From: Jacquerel Date: Mon, 1 Apr 2024 15:13:57 +0100 Subject: [PATCH 22/33] Great Ape now benefits from any increase you had to your power level (even if it was temporary lol) --- code/modules/surgery/organs/external/tails.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/modules/surgery/organs/external/tails.dm b/code/modules/surgery/organs/external/tails.dm index 0b898342abe..2c4106655b8 100644 --- a/code/modules/surgery/organs/external/tails.dm +++ b/code/modules/surgery/organs/external/tails.dm @@ -244,6 +244,7 @@ monkie.name = owner.real_name monkie.real_name = owner.real_name monkie.apply_status_effect(/datum/status_effect/shapechange_mob, owner) + monkie.saiyan_boost(owner.boost_movespeed / -0.1) RegisterSignal(monkie, COMSIG_LIVING_DEATH, PROC_REF(ape_died)) /obj/item/organ/external/tail/monkey/saiyan/proc/ape_died() From d9119f973c9849d75afbecf8c39c01e7557d5918 Mon Sep 17 00:00:00 2001 From: Jacquerel Date: Mon, 1 Apr 2024 16:28:06 +0100 Subject: [PATCH 23/33] Nerf Saiyan sleeping before it hits Manuel or Sybil --- code/modules/surgery/organs/internal/heart/heart_saiyan.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/surgery/organs/internal/heart/heart_saiyan.dm b/code/modules/surgery/organs/internal/heart/heart_saiyan.dm index 647bdb7bbd6..292f50d5e86 100644 --- a/code/modules/surgery/organs/internal/heart/heart_saiyan.dm +++ b/code/modules/surgery/organs/internal/heart/heart_saiyan.dm @@ -13,7 +13,7 @@ /// When we enter crit, prepare for a zenkai boost /obj/item/organ/internal/heart/saiyan/proc/on_stat_changed(mob/living/source, new_stat) SIGNAL_HANDLER - if (new_stat != UNCONSCIOUS) + if (new_stat != HARD_CRIT) return source.apply_status_effect(/datum/status_effect/saiyan_survivor_tracker) From f6a7d64c9eca6bdd95341d0910b0780229985cc5 Mon Sep 17 00:00:00 2001 From: Jacquerel Date: Mon, 1 Apr 2024 23:03:07 +0100 Subject: [PATCH 24/33] Firing your ki ends ultra instinct --- code/modules/mob/living/brain/brain_saiyan.dm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/modules/mob/living/brain/brain_saiyan.dm b/code/modules/mob/living/brain/brain_saiyan.dm index b7b9e65609b..49915b6fe3a 100644 --- a/code/modules/mob/living/brain/brain_saiyan.dm +++ b/code/modules/mob/living/brain/brain_saiyan.dm @@ -449,7 +449,7 @@ previous_hair_colour = human_owner.hair_color human_owner.set_haircolor(COLOR_CYAN, update = TRUE) - RegisterSignals(owner, list(COMSIG_MOB_ATTACK_HAND, COMSIG_LIVING_GRAB, COMSIG_MOB_ITEM_ATTACK, COMSIG_MOB_THROW), PROC_REF(took_action)) + RegisterSignals(owner, list(COMSIG_MOB_ATTACK_HAND, COMSIG_MOB_FIRED_GUN, COMSIG_LIVING_GRAB, COMSIG_MOB_ITEM_ATTACK, COMSIG_MOB_THROW), PROC_REF(took_action)) RegisterSignal(owner, COMSIG_LIVING_CHECK_BLOCK, PROC_REF(on_hit)) /datum/status_effect/ultra_instinct/on_remove() @@ -467,6 +467,7 @@ COMSIG_LIVING_CHECK_BLOCK, COMSIG_LIVING_GRAB, COMSIG_MOB_ATTACK_HAND, + COMSIG_MOB_FIRED_GUN, COMSIG_MOB_ITEM_ATTACK, COMSIG_MOB_THROW )) From 92b390d5a76d907db036d05d76bc74fe63cf7051 Mon Sep 17 00:00:00 2001 From: ZealousZeke <85478781+ZealousZeke@users.noreply.github.com> Date: Wed, 10 Jun 2026 19:19:59 -0500 Subject: [PATCH 25/33] it compiles --- .../subsystem/sprite_accessories.dm | 6 +++ .../basic/farm_animals/gorilla/gorilla.dm | 2 +- code/modules/mob/living/brain/brain_saiyan.dm | 14 +++---- .../carbon/human/species_types/saiyan.dm | 42 +++++++++---------- code/modules/surgery/organs/external/tails.dm | 20 ++++----- .../organs/internal/heart/heart_saiyan.dm | 8 ++-- .../organs/internal/stomach/_stomach.dm | 2 +- 7 files changed, 50 insertions(+), 44 deletions(-) diff --git a/code/controllers/subsystem/sprite_accessories.dm b/code/controllers/subsystem/sprite_accessories.dm index 2d121daa7a0..e3900cd7080 100644 --- a/code/controllers/subsystem/sprite_accessories.dm +++ b/code/controllers/subsystem/sprite_accessories.dm @@ -56,6 +56,8 @@ SUBSYSTEM_DEF(accessories) // just 'accessories' for brevity var/list/caps_list var/list/pod_hair_list + var/list/tails_list_saiyan + /datum/controller/subsystem/accessories/PreInit() // this stuff NEEDS to be set up before GLOB for preferences and stuff to work so this must go here. sorry setup_lists() init_hair_gradients() @@ -107,6 +109,10 @@ SUBSYSTEM_DEF(accessories) // just 'accessories' for brevity moth_markings_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/moth_markings, add_blank = TRUE)[DEFAULT_SPRITE_LIST] pod_hair_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/pod_hair)[DEFAULT_SPRITE_LIST] + tails_list_saiyan = init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/saiyan, add_blank = FALSE)[DEFAULT_SPRITE_LIST] + + + /// This proc just initializes all /datum/sprite_accessory/hair_gradient into an list indexed by gradient-style name /datum/controller/subsystem/accessories/proc/init_hair_gradients() hair_gradients_list = list() diff --git a/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm b/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm index 35fa7d7c954..d20ed9464b5 100644 --- a/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm +++ b/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm @@ -241,7 +241,7 @@ var/mob/living/carbon/saiyan = get_internal_saiyan() if (istype(saiyan)) - var/obj/item/organ/external/tail/saiyan_tail = saiyan.get_organ_slot(ORGAN_SLOT_EXTERNAL_TAIL) + var/obj/item/organ/tail/saiyan_tail = saiyan.get_organ_slot(ORGAN_SLOT_EXTERNAL_TAIL) saiyan_tail.Remove(saiyan) saiyan_tail.forceMove(saiyan.loc) diff --git a/code/modules/mob/living/brain/brain_saiyan.dm b/code/modules/mob/living/brain/brain_saiyan.dm index 49915b6fe3a..76d7b21b28f 100644 --- a/code/modules/mob/living/brain/brain_saiyan.dm +++ b/code/modules/mob/living/brain/brain_saiyan.dm @@ -1,7 +1,7 @@ #define GOKU_FILTER "goku_filter" /// The Saiyan brain contains knowledge of powerful martial arts -/obj/item/organ/internal/brain/saiyan +/obj/item/organ/brain/saiyan name = "saiyan brain" desc = "The brain of a mighty saiyan warrior. Guess they don't work out at the library..." brain_size = 0.5 @@ -16,7 +16,7 @@ /datum/action/cooldown/mob_cooldown/ultra_instinct, ) -/obj/item/organ/internal/brain/saiyan/on_mob_insert(mob/living/carbon/organ_owner, special, movement_flags) +/obj/item/organ/brain/saiyan/on_mob_insert(mob/living/carbon/organ_owner, special, movement_flags) . = ..() var/datum/action/cooldown/mob_cooldown/ki_blast/blast = new(organ_owner) blast.Grant(organ_owner) @@ -31,7 +31,7 @@ random_skill.Grant(organ_owner) granted_abilities += random_skill -/obj/item/organ/internal/brain/saiyan/on_mob_remove(mob/living/carbon/organ_owner, special) +/obj/item/organ/brain/saiyan/on_mob_remove(mob/living/carbon/organ_owner, special) . = ..() QDEL_LIST(granted_abilities) @@ -62,7 +62,7 @@ /obj/item/gun/ki_blast name = "concentrated ki" desc = "The power of your lifeforce converted into a deadly weapon. Fire it at someone." - fire_sound = 'sound/magic/wand_teleport.ogg' + fire_sound = 'sound/effects/magic/wand_teleport.ogg' icon = 'icons/obj/weapons/guns/projectiles.dmi' icon_state = "pulse1" inhand_icon_state = "arcane_barrage" @@ -99,8 +99,8 @@ icon_state = "pulse1_bl" damage = 3 damage_type = BRUTE - hitsound = 'sound/weapons/sear_disabler.ogg' - hitsound_wall = 'sound/weapons/sear_disabler.ogg' + hitsound = 'sound/items/weapons/sear_disabler.ogg' + hitsound_wall = 'sound/items/weapons/sear_disabler.ogg' light_system = OVERLAY_LIGHT light_range = 1 light_power = 1.4 @@ -377,7 +377,7 @@ lightbulb = owner.mob_light(5, 1, COLOR_GOLD) - playsound(owner, 'sound/magic/charge.ogg', vol = 80) + playsound(owner, 'sound/effects/magic/charge.ogg', vol = 80) var/list/destroy_turfs = circle_range_turfs(center = owner, radius = 2) for (var/turf/check_turf as anything in destroy_turfs) diff --git a/code/modules/mob/living/carbon/human/species_types/saiyan.dm b/code/modules/mob/living/carbon/human/species_types/saiyan.dm index f89aa1ee4c7..04cc0ec43f9 100644 --- a/code/modules/mob/living/carbon/human/species_types/saiyan.dm +++ b/code/modules/mob/living/carbon/human/species_types/saiyan.dm @@ -3,10 +3,10 @@ /datum/species/saiyan name = "\improper Saiyan" id = SPECIES_SAIYAN - mutanteyes = /obj/item/organ/internal/eyes/saiyan - mutantbrain = /obj/item/organ/internal/brain/saiyan - mutantheart = /obj/item/organ/internal/heart/saiyan - mutantstomach = /obj/item/organ/internal/stomach/saiyan + mutanteyes = /obj/item/organ/eyes/saiyan + mutantbrain = /obj/item/organ/brain/saiyan + mutantheart = /obj/item/organ/heart/saiyan + mutantstomach = /obj/item/organ/stomach/saiyan payday_modifier = 2.0 inherent_traits = list( TRAIT_CATLIKE_GRACE, @@ -24,8 +24,8 @@ BODY_ZONE_L_LEG = /obj/item/bodypart/leg/left/saiyan, BODY_ZONE_R_LEG = /obj/item/bodypart/leg/right/saiyan, ) - external_organs = list( - /obj/item/organ/external/tail/monkey/saiyan = "Saiyan", + mutant_organs = list( + /obj/item/organ/tail/monkey/saiyan = "Saiyan", ) /datum/species/saiyan/prepare_human_for_preview(mob/living/carbon/human/human) @@ -38,22 +38,22 @@ /datum/species/saiyan/get_scream_sound(mob/living/carbon/human/human) if(human.physique == MALE) if(prob(1)) - return 'sound/voice/human/wilhelm_scream.ogg' + return 'sound/mobs/humanoids/human/scream/wilhelm_scream.ogg' return pick( - 'sound/voice/human/malescream_1.ogg', - 'sound/voice/human/malescream_2.ogg', - 'sound/voice/human/malescream_3.ogg', - 'sound/voice/human/malescream_4.ogg', - 'sound/voice/human/malescream_5.ogg', - 'sound/voice/human/malescream_6.ogg', + 'sound/mobs/humanoids/human/scream/malescream_1.ogg', + 'sound/mobs/humanoids/human/scream/malescream_2.ogg', + 'sound/mobs/humanoids/human/scream/malescream_3.ogg', + 'sound/mobs/humanoids/human/scream/malescream_4.ogg', + 'sound/mobs/humanoids/human/scream/malescream_5.ogg', + 'sound/mobs/humanoids/human/scream/malescream_6.ogg', ) return pick( - 'sound/voice/human/femalescream_1.ogg', - 'sound/voice/human/femalescream_2.ogg', - 'sound/voice/human/femalescream_3.ogg', - 'sound/voice/human/femalescream_4.ogg', - 'sound/voice/human/femalescream_5.ogg', + 'sound/mobs/humanoids/human/scream/femalescream_1.ogg', + 'sound/mobs/humanoids/human/scream/femalescream_2.ogg', + 'sound/mobs/humanoids/human/scream/femalescream_3.ogg', + 'sound/mobs/humanoids/human/scream/femalescream_4.ogg', + 'sound/mobs/humanoids/human/scream/femalescream_5.ogg', ) /datum/species/saiyan/on_species_gain(mob/living/carbon/human/human_who_gained_species, datum/species/old_species, pref_load) @@ -79,7 +79,7 @@ return if (attacker.zone_selected != BODY_ZONE_PRECISE_GROIN && attacker.zone_selected != BODY_ZONE_CHEST) return - var/obj/item/organ/external/tail/saiyan_tail = target.get_organ_slot(ORGAN_SLOT_EXTERNAL_TAIL) + var/obj/item/organ/tail/saiyan_tail = target.get_organ_slot(ORGAN_SLOT_EXTERNAL_TAIL) if (isnull(saiyan_tail) || !prob(3)) return target.visible_message(span_warning("[target]'s tail falls to the ground, severed completely!")) @@ -96,7 +96,7 @@ /// When your tail is cut you get weaker /datum/species/saiyan/proc/on_tail_gained(mob/living/vegeta, obj/item/organ/tail) SIGNAL_HANDLER - if (!istype(tail, /obj/item/organ/external/tail/monkey/saiyan)) + if (!istype(tail, /obj/item/organ/tail/monkey/saiyan)) return if (!vegeta.mob_mood.has_mood_of_category(SAIYAN_TAIL_MOOD)) return @@ -107,7 +107,7 @@ /// If your tail is restored you return to original strength /datum/species/saiyan/proc/on_tail_removed(mob/living/vegeta, obj/item/organ/tail) SIGNAL_HANDLER - if (!istype(tail, /obj/item/organ/external/tail/monkey/saiyan)) + if (!istype(tail, /obj/item/organ/tail/monkey/saiyan)) return to_chat(vegeta, span_boldwarning("No! Your tail!!")) vegeta.saiyan_boost(multiplier = -5) diff --git a/code/modules/surgery/organs/external/tails.dm b/code/modules/surgery/organs/external/tails.dm index 2c4106655b8..f9d5a8dcb40 100644 --- a/code/modules/surgery/organs/external/tails.dm +++ b/code/modules/surgery/organs/external/tails.dm @@ -193,22 +193,22 @@ desc = "The severed tail of a mighty Saiyan warrior, the ultimate humiliation." bodypart_overlay = /datum/bodypart_overlay/mutant/tail/monkey/saiyan -/obj/item/organ/external/tail/monkey/saiyan/on_mob_insert(mob/living/carbon/organ_owner, special, movement_flags) +/obj/item/organ/tail/monkey/saiyan/on_mob_insert(mob/living/carbon/organ_owner, special, movement_flags) . = ..() var/static/list/loc_connections = list( COMSIG_MOVABLE_MOVED = PROC_REF(on_moved), ) AddComponent(/datum/component/connect_containers, src, loc_connections) -/obj/item/organ/external/tail/monkey/saiyan/on_mob_remove(mob/living/carbon/organ_owner, special) +/obj/item/organ/tail/monkey/saiyan/on_mob_remove(mob/living/carbon/organ_owner, special) . = ..() qdel(GetComponent(/datum/component/connect_containers)) -/obj/item/organ/external/tail/monkey/saiyan/get_butt_sprite() +/obj/item/organ/tail/monkey/saiyan/get_butt_sprite() return BUTT_SPRITE_CAT // how don't we have a monkey one... /// When we move check if we are exposed to space -/obj/item/organ/external/tail/monkey/saiyan/proc/on_moved() +/obj/item/organ/tail/monkey/saiyan/proc/on_moved() SIGNAL_HANDLER if (isnull(owner)) return @@ -218,7 +218,7 @@ escape_ape(owner) /// Check if the passed turf can see space -/obj/item/organ/external/tail/monkey/saiyan/proc/is_space_exposed_turf(turf/turf_to_check) +/obj/item/organ/tail/monkey/saiyan/proc/is_space_exposed_turf(turf/turf_to_check) if (isnull(turf_to_check)) return FALSE var/area/area_to_check = get_area(turf_to_check) @@ -234,7 +234,7 @@ return isnull(turf_to_check) || isspaceturf(turf_to_check) /// Start being an ape -/obj/item/organ/external/tail/monkey/saiyan/proc/go_ape() +/obj/item/organ/tail/monkey/saiyan/proc/go_ape() if (HAS_TRAIT(owner, TRAIT_SHAPESHIFTED) || owner.stat == DEAD) return owner.visible_message(span_warning("[owner] transforms into a huge, ape-like creature!")) @@ -247,12 +247,12 @@ monkie.saiyan_boost(owner.boost_movespeed / -0.1) RegisterSignal(monkie, COMSIG_LIVING_DEATH, PROC_REF(ape_died)) -/obj/item/organ/external/tail/monkey/saiyan/proc/ape_died() +/obj/item/organ/tail/monkey/saiyan/proc/ape_died() SIGNAL_HANDLER owner.death() /// Stop being an ape -/obj/item/organ/external/tail/monkey/saiyan/proc/escape_ape() +/obj/item/organ/tail/monkey/saiyan/proc/escape_ape() if (!HAS_TRAIT(owner, TRAIT_SHAPESHIFTED)) return var/mob/living/ape_form = owner.loc @@ -264,8 +264,8 @@ /datum/bodypart_overlay/mutant/tail/monkey/saiyan feature_key = "tail_saiyan" -/datum/bodypart_overlay/mutant/tail/monkey/saiyan/get_global_feature_list() - return GLOB.tails_list_saiyan +/datum/bodypart_overlay/mutant/tail/saiyan/get_global_feature_list() + return SSaccessories.tails_list_saiyan /obj/item/organ/tail/lizard name = "lizard tail" diff --git a/code/modules/surgery/organs/internal/heart/heart_saiyan.dm b/code/modules/surgery/organs/internal/heart/heart_saiyan.dm index 292f50d5e86..3b30a24b2f1 100644 --- a/code/modules/surgery/organs/internal/heart/heart_saiyan.dm +++ b/code/modules/surgery/organs/internal/heart/heart_saiyan.dm @@ -1,17 +1,17 @@ /// A warrior's heart which gains experience from fighting (and losing) -/obj/item/organ/internal/heart/saiyan +/obj/item/organ/heart/saiyan maxHealth = STANDARD_ORGAN_THRESHOLD*0.5 // Vulnerable to heart disease -/obj/item/organ/internal/heart/saiyan/on_mob_insert(mob/living/carbon/organ_owner, special, movement_flags) +/obj/item/organ/heart/saiyan/on_mob_insert(mob/living/carbon/organ_owner, special, movement_flags) . = ..() RegisterSignal(organ_owner, COMSIG_MOB_STATCHANGE, PROC_REF(on_stat_changed)) -/obj/item/organ/internal/heart/saiyan/on_mob_remove(mob/living/carbon/organ_owner, special) +/obj/item/organ/heart/saiyan/on_mob_remove(mob/living/carbon/organ_owner, special) . = ..() UnregisterSignal(organ_owner, COMSIG_MOB_STATCHANGE) /// When we enter crit, prepare for a zenkai boost -/obj/item/organ/internal/heart/saiyan/proc/on_stat_changed(mob/living/source, new_stat) +/obj/item/organ/heart/saiyan/proc/on_stat_changed(mob/living/source, new_stat) SIGNAL_HANDLER if (new_stat != HARD_CRIT) return diff --git a/code/modules/surgery/organs/internal/stomach/_stomach.dm b/code/modules/surgery/organs/internal/stomach/_stomach.dm index 49704688316..ab7d50b5c8b 100644 --- a/code/modules/surgery/organs/internal/stomach/_stomach.dm +++ b/code/modules/surgery/organs/internal/stomach/_stomach.dm @@ -325,7 +325,7 @@ . = ..() AddElement(/datum/element/dangerous_organ_removal, /*surgical = */ TRUE) -/obj/item/organ/internal/stomach/saiyan +/obj/item/organ/stomach/saiyan disgust_metabolism = 2 hunger_modifier = 3 desc = "The Saiyan stomach can handle a wide range of foods, but burns it fast to power their energetic lifestyle." From 350275df955b59ecf8ba329a9ac5b486ddff6fde Mon Sep 17 00:00:00 2001 From: ZealousZeke <85478781+ZealousZeke@users.noreply.github.com> Date: Thu, 11 Jun 2026 10:27:44 -0500 Subject: [PATCH 26/33] fixes one of the linter issues --- code/modules/mob/living/carbon/human/species_types/saiyan.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/carbon/human/species_types/saiyan.dm b/code/modules/mob/living/carbon/human/species_types/saiyan.dm index 04cc0ec43f9..5bb6df2b92a 100644 --- a/code/modules/mob/living/carbon/human/species_types/saiyan.dm +++ b/code/modules/mob/living/carbon/human/species_types/saiyan.dm @@ -56,7 +56,7 @@ 'sound/mobs/humanoids/human/scream/femalescream_5.ogg', ) -/datum/species/saiyan/on_species_gain(mob/living/carbon/human/human_who_gained_species, datum/species/old_species, pref_load) +/datum/species/saiyan/on_species_gain(mob/living/carbon/human/human_who_gained_species, datum/species/old_species, pref_load, regenerate_icons) . = ..() RegisterSignal(human_who_gained_species, COMSIG_SAIYAN_SURVIVOR, PROC_REF(on_survived_boost)) RegisterSignal(human_who_gained_species, COMSIG_CARBON_GAIN_ORGAN, PROC_REF(on_tail_gained)) From 0f76cd88e976ebb5a44ac854a1ac9a2b2115ff82 Mon Sep 17 00:00:00 2001 From: ZealousZeke <85478781+ZealousZeke@users.noreply.github.com> Date: Sat, 13 Jun 2026 00:04:02 -0500 Subject: [PATCH 27/33] test --- code/modules/mob/living/carbon/human/species_types/saiyan.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/carbon/human/species_types/saiyan.dm b/code/modules/mob/living/carbon/human/species_types/saiyan.dm index 5bb6df2b92a..bfd1c87872a 100644 --- a/code/modules/mob/living/carbon/human/species_types/saiyan.dm +++ b/code/modules/mob/living/carbon/human/species_types/saiyan.dm @@ -14,7 +14,7 @@ TRAIT_USES_SKINTONES, ) changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_PRIDE | MIRROR_MAGIC | RACE_SWAP | ERT_SPAWN | SLIME_EXTRACT - species_language_holder = /datum/language_holder/clown + species_language_holder = /datum/language_holder/universal bodypart_overrides = list( BODY_ZONE_HEAD = /obj/item/bodypart/head/saiyan, From 86ca001a75017e2d699fe2f73a905ee28e42fb33 Mon Sep 17 00:00:00 2001 From: ZealousZeke <85478781+ZealousZeke@users.noreply.github.com> Date: Sat, 13 Jun 2026 01:19:43 -0500 Subject: [PATCH 28/33] anotha one --- code/modules/mob/living/carbon/human/species_types/saiyan.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/carbon/human/species_types/saiyan.dm b/code/modules/mob/living/carbon/human/species_types/saiyan.dm index bfd1c87872a..8b6f09aa2ec 100644 --- a/code/modules/mob/living/carbon/human/species_types/saiyan.dm +++ b/code/modules/mob/living/carbon/human/species_types/saiyan.dm @@ -14,7 +14,7 @@ TRAIT_USES_SKINTONES, ) changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_PRIDE | MIRROR_MAGIC | RACE_SWAP | ERT_SPAWN | SLIME_EXTRACT - species_language_holder = /datum/language_holder/universal + species_language_holder = /datum/language/common bodypart_overrides = list( BODY_ZONE_HEAD = /obj/item/bodypart/head/saiyan, From 0acae0ce5e30d114a776336dce4ecf230e902230 Mon Sep 17 00:00:00 2001 From: ZealousZeke <85478781+ZealousZeke@users.noreply.github.com> Date: Sat, 13 Jun 2026 08:03:03 -0500 Subject: [PATCH 29/33] test 3 --- code/modules/mob/living/carbon/human/species_types/saiyan.dm | 1 - 1 file changed, 1 deletion(-) diff --git a/code/modules/mob/living/carbon/human/species_types/saiyan.dm b/code/modules/mob/living/carbon/human/species_types/saiyan.dm index 8b6f09aa2ec..d624c344d7a 100644 --- a/code/modules/mob/living/carbon/human/species_types/saiyan.dm +++ b/code/modules/mob/living/carbon/human/species_types/saiyan.dm @@ -14,7 +14,6 @@ TRAIT_USES_SKINTONES, ) changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_PRIDE | MIRROR_MAGIC | RACE_SWAP | ERT_SPAWN | SLIME_EXTRACT - species_language_holder = /datum/language/common bodypart_overrides = list( BODY_ZONE_HEAD = /obj/item/bodypart/head/saiyan, From c4f681358d66b04e7c5bfa854799deb8b2c63194 Mon Sep 17 00:00:00 2001 From: ZealousZeke <85478781+ZealousZeke@users.noreply.github.com> Date: Sun, 14 Jun 2026 12:33:51 -0500 Subject: [PATCH 30/33] fixed the tail --- code/controllers/subsystem/sprite_accessories.dm | 5 ++--- code/modules/mob/living/carbon/human/species_types/saiyan.dm | 2 ++ code/modules/surgery/organs/external/tails.dm | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/code/controllers/subsystem/sprite_accessories.dm b/code/controllers/subsystem/sprite_accessories.dm index e3900cd7080..5dcd6057908 100644 --- a/code/controllers/subsystem/sprite_accessories.dm +++ b/code/controllers/subsystem/sprite_accessories.dm @@ -46,6 +46,7 @@ SUBSYSTEM_DEF(accessories) // just 'accessories' for brevity var/list/tails_list_felinid var/list/tails_list_lizard var/list/tails_list_monkey + var/list/tails_list_saiyan var/list/tails_list_fish var/list/ears_list var/list/wings_list @@ -56,7 +57,6 @@ SUBSYSTEM_DEF(accessories) // just 'accessories' for brevity var/list/caps_list var/list/pod_hair_list - var/list/tails_list_saiyan /datum/controller/subsystem/accessories/PreInit() // this stuff NEEDS to be set up before GLOB for preferences and stuff to work so this must go here. sorry setup_lists() @@ -93,6 +93,7 @@ SUBSYSTEM_DEF(accessories) // just 'accessories' for brevity tails_list_felinid = init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/felinid, add_blank = TRUE)[DEFAULT_SPRITE_LIST] tails_list_lizard = init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/lizard)[DEFAULT_SPRITE_LIST] tails_list_monkey = init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/monkey)[DEFAULT_SPRITE_LIST] + tails_list_saiyan = init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/saiyan, add_blank = FALSE)[DEFAULT_SPRITE_LIST] //tails fo fish organ infusions, not for prefs. tails_list_fish = init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/fish)[DEFAULT_SPRITE_LIST] snouts_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/snouts)[DEFAULT_SPRITE_LIST] @@ -109,8 +110,6 @@ SUBSYSTEM_DEF(accessories) // just 'accessories' for brevity moth_markings_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/moth_markings, add_blank = TRUE)[DEFAULT_SPRITE_LIST] pod_hair_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/pod_hair)[DEFAULT_SPRITE_LIST] - tails_list_saiyan = init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/saiyan, add_blank = FALSE)[DEFAULT_SPRITE_LIST] - /// This proc just initializes all /datum/sprite_accessory/hair_gradient into an list indexed by gradient-style name diff --git a/code/modules/mob/living/carbon/human/species_types/saiyan.dm b/code/modules/mob/living/carbon/human/species_types/saiyan.dm index d624c344d7a..83c4020c812 100644 --- a/code/modules/mob/living/carbon/human/species_types/saiyan.dm +++ b/code/modules/mob/living/carbon/human/species_types/saiyan.dm @@ -15,6 +15,8 @@ ) changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_PRIDE | MIRROR_MAGIC | RACE_SWAP | ERT_SPAWN | SLIME_EXTRACT + species_language_holder = /datum/language_holder/clown + bodypart_overrides = list( BODY_ZONE_HEAD = /obj/item/bodypart/head/saiyan, BODY_ZONE_CHEST = /obj/item/bodypart/chest/saiyan, diff --git a/code/modules/surgery/organs/external/tails.dm b/code/modules/surgery/organs/external/tails.dm index f9d5a8dcb40..e49e92082e5 100644 --- a/code/modules/surgery/organs/external/tails.dm +++ b/code/modules/surgery/organs/external/tails.dm @@ -264,7 +264,7 @@ /datum/bodypart_overlay/mutant/tail/monkey/saiyan feature_key = "tail_saiyan" -/datum/bodypart_overlay/mutant/tail/saiyan/get_global_feature_list() +/datum/bodypart_overlay/mutant/tail/monkey/saiyan/get_global_feature_list() return SSaccessories.tails_list_saiyan /obj/item/organ/tail/lizard From 1bf3a7f1a13b12271da1137a70f48b84a8b08c5b Mon Sep 17 00:00:00 2001 From: ZealousZeke <85478781+ZealousZeke@users.noreply.github.com> Date: Sun, 14 Jun 2026 12:58:56 -0500 Subject: [PATCH 31/33] fixed a runtime --- .../surgery/bodyparts/species_parts/saiyan_bodyparts.dm | 4 ++++ code/modules/surgery/organs/external/tails.dm | 1 - 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/code/modules/surgery/bodyparts/species_parts/saiyan_bodyparts.dm b/code/modules/surgery/bodyparts/species_parts/saiyan_bodyparts.dm index de6b9be37a9..56186d46788 100644 --- a/code/modules/surgery/bodyparts/species_parts/saiyan_bodyparts.dm +++ b/code/modules/surgery/bodyparts/species_parts/saiyan_bodyparts.dm @@ -11,6 +11,10 @@ /obj/item/bodypart/head/saiyan/update_hair_and_lips(dropping_limb, is_creating) . = ..() + + if(!owner) + return + if (HAS_TRAIT(owner, TRAIT_POWER_HAIR)) return // Sorry, you are not legendary enough to dye your hair diff --git a/code/modules/surgery/organs/external/tails.dm b/code/modules/surgery/organs/external/tails.dm index e49e92082e5..2b053abc07c 100644 --- a/code/modules/surgery/organs/external/tails.dm +++ b/code/modules/surgery/organs/external/tails.dm @@ -187,7 +187,6 @@ /datum/bodypart_overlay/mutant/tail/monkey/get_global_feature_list() return SSaccessories.tails_list_monkey - /obj/item/organ/tail/monkey/saiyan name = "saiyan tail" desc = "The severed tail of a mighty Saiyan warrior, the ultimate humiliation." From 046e0b7ff79a983175c25d1ec9e2c6f73df03472 Mon Sep 17 00:00:00 2001 From: ZealousZeke <85478781+ZealousZeke@users.noreply.github.com> Date: Sun, 14 Jun 2026 17:47:02 -0500 Subject: [PATCH 32/33] human basic --- code/modules/mob/living/carbon/human/species_types/saiyan.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/carbon/human/species_types/saiyan.dm b/code/modules/mob/living/carbon/human/species_types/saiyan.dm index 83c4020c812..1d81758fafa 100644 --- a/code/modules/mob/living/carbon/human/species_types/saiyan.dm +++ b/code/modules/mob/living/carbon/human/species_types/saiyan.dm @@ -15,7 +15,7 @@ ) changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_PRIDE | MIRROR_MAGIC | RACE_SWAP | ERT_SPAWN | SLIME_EXTRACT - species_language_holder = /datum/language_holder/clown + species_language_holder = /datum/language_holder/human_basic bodypart_overrides = list( BODY_ZONE_HEAD = /obj/item/bodypart/head/saiyan, From fc0ad913b565c70bf04258acaa7d64b1c8c006fa Mon Sep 17 00:00:00 2001 From: ZealousZeke <85478781+ZealousZeke@users.noreply.github.com> Date: Mon, 15 Jun 2026 12:08:15 -0500 Subject: [PATCH 33/33] anotha runtime down --- code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm b/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm index d20ed9464b5..9d27c22b3a9 100644 --- a/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm +++ b/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm @@ -204,6 +204,7 @@ unsuitable_atmos_damage = 0 unsuitable_cold_damage = 0 basic_mob_flags = DEL_ON_DEATH + ai_controller = null /mob/living/basic/gorilla/saiyan/Initialize(mapload) . = ..()