Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Snails, Except Twice #79

Merged
merged 4 commits into from
Sep 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions code/__DEFINES/~doppler_defines/is_helpers.dm
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@
//Customization bases
#define isfeline(A) (isfelinid(A) || HAS_TRAIT(A, TRAIT_FELINE))
#define isinsectoid(A) (is_species(A, /datum/species/insectoid))
#define issnail(A) (is_species(A, /datum/species/snail))
//Species with green blood
#define hasgreenblood(A) (isinsectoid(A) || HAS_TRAIT(A, TRAIT_GREEN_BLOOD))
1 change: 1 addition & 0 deletions code/__DEFINES/~doppler_defines/mobs.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#define BODYPART_ICON_SNAIL 'modular_doppler/modular_species/species_types/snails/icons/bodyparts/snail_bodyparts.dmi'
13 changes: 12 additions & 1 deletion code/datums/elements/lube_walking.dm
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,26 @@
if(new_resting && lubricate(snail))
snail.add_movespeed_modifier(/datum/movespeed_modifier/snail_crawl)
RegisterSignal(snail, COMSIG_MOVABLE_MOVED, PROC_REF(lubricate))
//DOPPLER EDIT ADDITION BEGIN - This is to prevent snails from achieving FTL speeds without gravity, think of it like snails affixing to walls irl.
ADD_TRAIT(snail, TRAIT_NEGATES_GRAVITY, TRAIT_GENERIC)
snail.AddElement(/datum/element/forced_gravity, 0)
if(HAS_TRAIT(snail, TRAIT_SETTLER)) //This is to keep settlers from reaching FTL speeds too.
snail.remove_movespeed_modifier(/datum/movespeed_modifier/snail_crawl)
//DOPPLER EDIT ADDITION END
else
snail.remove_movespeed_modifier(/datum/movespeed_modifier/snail_crawl)
UnregisterSignal(snail, COMSIG_MOVABLE_MOVED)
//DOPPLER EDIT ADDITION BEGIN - This clears the forced gravity so they're affected by it while standing.
REMOVE_TRAIT(snail, TRAIT_NEGATES_GRAVITY, TRAIT_GENERIC)
snail.RemoveElement(/datum/element/forced_gravity, 0)
//DOPPLER EDIT ADDITION END

/datum/element/lube_walking/proc/lubricate(atom/movable/snail)
SIGNAL_HANDLER

var/turf/open/turf_standing_on = get_turf(snail)
if(!istype(turf_standing_on))
return FALSE
turf_standing_on.MakeSlippery(wet_flags, min_wet_time = min_time_wet_for)
turf_standing_on.MakeSlippery(TURF_WET_WATER, min_wet_time = 1 SECONDS) //DOPPLER EDIT CHANGE: Roundstart Snails - No more lube - ORIGINAL: turf_standing_on.MakeSlippery(wet_flags, min_wet_time = min_time_wet_for)
turf_standing_on.wash(CLEAN_WASH) //DOPPLER EDIT ADDITION: Roundstart Snails - Snails Keep Clean
return TRUE
9 changes: 5 additions & 4 deletions code/modules/surgery/organs/internal/eyes/_eyes.dm
Original file line number Diff line number Diff line change
Expand Up @@ -134,14 +134,14 @@
var/eye_icon = my_head?.eyes_icon || 'icons/mob/human/human_face.dmi'
/// DOPPLER SHIFT ADDITION END

var/mutable_appearance/eye_left = mutable_appearance(eye_icon, "[eye_icon_state]_l", -BODY_LAYER) /// DOPPLER SHIFT EDIT: using eye_icon instead of human_face.dmi
var/mutable_appearance/eye_right = mutable_appearance(eye_icon, "[eye_icon_state]_r", -BODY_LAYER) /// DOPPLER SHIFT EDIT: using eye_icon instead of human_face.dmi
var/mutable_appearance/eye_left = mutable_appearance(eye_icon, "[eye_icon_state]_l", -eyes_layer) /// DOPPLER SHIFT EDIT: using eye_icon instead of human_face.dmi, eyes_layer instead of BODY_LAYER
var/mutable_appearance/eye_right = mutable_appearance(eye_icon, "[eye_icon_state]_r", -eyes_layer) /// DOPPLER SHIFT EDIT: using eye_icon instead of human_face.dmi, eyes_layer instead of BODY_LAYER
var/list/overlays = list(eye_left, eye_right)

var/obscured = parent.check_obscured_slots(TRUE)
if(overlay_ignore_lighting && !(obscured & ITEM_SLOT_EYES))
overlays += emissive_appearance(eye_left.icon, eye_left.icon_state, parent, -BODY_LAYER, alpha = eye_left.alpha)
overlays += emissive_appearance(eye_right.icon, eye_right.icon_state, parent, -BODY_LAYER, alpha = eye_right.alpha)
overlays += emissive_appearance(eye_left.icon, eye_left.icon_state, parent, -eyes_layer, alpha = eye_left.alpha) //DOPPLER SHIFT EDIT : using eyes_layer instead of BODY_LAYER
overlays += emissive_appearance(eye_right.icon, eye_right.icon_state, parent, -eyes_layer, alpha = eye_right.alpha) //DOPPLER SHIFT EDIT : using eyes_layer instead of BODY_LAYER
//var/obj/item/bodypart/head/my_head = parent.get_bodypart(BODY_ZONE_HEAD) /// DOPPLER SHIFT REMOVAL
if(my_head)
if(my_head.head_flags & HEAD_EYECOLOR)
Expand Down Expand Up @@ -719,6 +719,7 @@
desc = "These eyes seem to have a large range, but might be cumbersome with glasses."
eye_icon_state = "snail_eyes"
icon_state = "snail_eyeballs"
eyes_layer = ABOVE_BODY_FRONT_HEAD_LAYER // DOPPLER EDIT - Roundstart Snails

/obj/item/organ/internal/eyes/jelly
name = "jelly eyes"
Expand Down
4 changes: 4 additions & 0 deletions code/modules/surgery/organs/internal/tongue/_tongue.dm
Original file line number Diff line number Diff line change
Expand Up @@ -562,7 +562,10 @@ GLOBAL_LIST_INIT(english_to_zombie, list())
color = "#96DB00" // TODO proper sprite, rather than recoloured pink tongue
modifies_speech = TRUE
voice_filter = "atempo=0.5" // makes them talk really slow
liked_foodtypes = VEGETABLES | FRUIT | GROSS | RAW //DOPPLER EDIT - Roundstart Snails - Food Prefs
disliked_foodtypes = DAIRY | ORANGES | SUGAR //DOPPLER EDIT: Roundstart Snails - As it turns out, you can't give a snail processed sugar or citrus.

/* DOPPLER EDIT START - Roundstart Snails: Less annoying speech.
/obj/item/organ/internal/tongue/snail/modify_speech(datum/source, list/speech_args)
var/new_message
var/message = speech_args[SPEECH_MESSAGE]
Expand All @@ -572,6 +575,7 @@ GLOBAL_LIST_INIT(english_to_zombie, list())
else
new_message += message[i]
speech_args[SPEECH_MESSAGE] = new_message
*/ // DOPPLER EDIT END

/obj/item/organ/internal/tongue/ethereal
name = "electric discharger"
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion config/game_options.txt
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ ROUNDSTART_RACES primitive_felinid
ROUNDSTART_RACES ethereal
#ROUNDSTART_RACES jelly
#ROUNDSTART_RACES abductor
#ROUNDSTART_RACES snail
ROUNDSTART_RACES snail

## Races that are straight upgrades. If these are on expect powergamers to always pick them
#ROUNDSTART_RACES skeleton
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/obj/item/organ/internal/eyes
var/eyes_layer = BODY_LAYER
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
#define SHELL_TRANSPARENCY_ALPHA 90

/datum/species/snail
mutantliver = /obj/item/organ/internal/liver/snail //This is just a better liver to deal with toxins, it's a thematic thing.
mutantheart = /obj/item/organ/internal/heart/snail //This gives them the shell buff where they take less damage from behind, and their heart's more durable.
exotic_blood = null

/datum/species/snail/on_species_gain(mob/living/carbon/new_snailperson, datum/species/old_species, pref_load)
. = ..()
new_snailperson.update_icons()

/obj/item/storage/backpack/snail
/// Whether or not a bluespace anomaly core has been inserted
var/storage_core = FALSE
slowdown = 6 // The snail's shell is what's making them slow.
obj_flags = IMMUTABLE_SLOW //This should hopefully solve other issues involing it as well.
alternate_worn_layer = ABOVE_BODY_FRONT_LAYER //This makes them layer over tails like the cult backpack; some tails really shouldn't appear over them!
uses_advanced_reskins = TRUE
unique_reskin = list(
"Conical Shell" = list(
RESKIN_ICON = 'modular_doppler/modular_species/species_types/snails/icons/shell/shell_obj.dmi',
RESKIN_ICON_STATE = "coneshell",
RESKIN_WORN_ICON = 'modular_doppler/modular_species/species_types/snails/icons/shell/shell_mob.dmi',
RESKIN_WORN_ICON_STATE = "coneshell"
),
"Round Shell" = list(
RESKIN_ICON = 'icons/obj/storage/backpack.dmi',
RESKIN_ICON_STATE = "snailshell",
RESKIN_WORN_ICON = 'icons/mob/clothing/back/backpack.dmi',
RESKIN_WORN_ICON_STATE = "snailshell"
),
"Cinnamon Shell" = list(
RESKIN_ICON = 'modular_doppler/modular_species/species_types/snails/icons/shell/shell_obj.dmi',
RESKIN_ICON_STATE = "cinnamonshell",
RESKIN_WORN_ICON = 'modular_doppler/modular_species/species_types/snails/icons/shell/shell_mob.dmi',
RESKIN_WORN_ICON_STATE = "cinnamonshell"
),
"Caramel Shell" = list(
RESKIN_ICON = 'modular_doppler/modular_species/species_types/snails/icons/shell/shell_obj.dmi',
RESKIN_ICON_STATE = "caramelshell",
RESKIN_WORN_ICON = 'modular_doppler/modular_species/species_types/snails/icons/shell/shell_mob.dmi',
RESKIN_WORN_ICON_STATE = "caramelshell"
),
"Metal Shell" = list(
RESKIN_ICON = 'modular_doppler/modular_species/species_types/snails/icons/shell/shell_obj.dmi',
RESKIN_ICON_STATE = "mechashell",
RESKIN_WORN_ICON = 'modular_doppler/modular_species/species_types/snails/icons/shell/shell_mob.dmi',
RESKIN_WORN_ICON_STATE = "mechashell"
),
"Pyramid Shell" = list(
RESKIN_ICON = 'modular_doppler/modular_species/species_types/snails/icons/shell/shell_obj.dmi',
RESKIN_ICON_STATE = "pyramidshell",
RESKIN_WORN_ICON = 'modular_doppler/modular_species/species_types/snails/icons/shell/shell_mob.dmi',
RESKIN_WORN_ICON_STATE = "pyramidshell"
),
"Ivory Pyramid Shell" = list(
RESKIN_ICON = 'modular_doppler/modular_species/species_types/snails/icons/shell/shell_obj.dmi',
RESKIN_ICON_STATE = "pyramidshellwhite",
RESKIN_WORN_ICON = 'modular_doppler/modular_species/species_types/snails/icons/shell/shell_mob.dmi',
RESKIN_WORN_ICON_STATE = "pyramidshellwhite"
),
"Spiral Shell" = list(
RESKIN_ICON = 'modular_doppler/modular_species/species_types/snails/icons/shell/shell_obj.dmi',
RESKIN_ICON_STATE = "spiralshell",
RESKIN_WORN_ICON = 'modular_doppler/modular_species/species_types/snails/icons/shell/shell_mob.dmi',
RESKIN_WORN_ICON_STATE = "spiralshell"
),
"Ivory Spiral Shell" = list(
RESKIN_ICON = 'modular_doppler/modular_species/species_types/snails/icons/shell/shell_obj.dmi',
RESKIN_ICON_STATE = "spiralshellwhite",
RESKIN_WORN_ICON = 'modular_doppler/modular_species/species_types/snails/icons/shell/shell_mob.dmi',
RESKIN_WORN_ICON_STATE = "spiralshellwhite"
),
"Rocky Shell" = list(
RESKIN_ICON = 'modular_doppler/modular_species/species_types/snails/icons/shell/shell_obj.dmi',
RESKIN_ICON_STATE = "rockshell",
RESKIN_WORN_ICON = 'modular_doppler/modular_species/species_types/snails/icons/shell/shell_mob.dmi',
RESKIN_WORN_ICON_STATE = "rockshell"
),
"Ivory Rocky Shell" = list(
RESKIN_ICON = 'modular_doppler/modular_species/species_types/snails/icons/shell/shell_obj.dmi',
RESKIN_ICON_STATE = "rockshellwhite",
RESKIN_WORN_ICON = 'modular_doppler/modular_species/species_types/snails/icons/shell/shell_mob.dmi',
RESKIN_WORN_ICON_STATE = "rockshellwhite"
),
)

/obj/item/storage/backpack/snail/Initialize(mapload)
. = ..()
atom_storage.max_total_storage = 30

/obj/item/storage/backpack/snail/build_worn_icon(
default_layer = 0,
default_icon_file = null,
isinhands = FALSE,
female_uniform = NO_FEMALE_UNIFORM,
override_state = null,
override_file = null,
mutant_styles = NONE,
humie = null,
)

var/mutable_appearance/standing = ..()
if(storage_core == TRUE)
standing.add_filter("bluespace_shell", 2, list("type" = "outline", "color" = COLOR_BLUE_LIGHT, "alpha" = SHELL_TRANSPARENCY_ALPHA, "size" = 1))
return standing

/obj/item/storage/backpack/snail/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
if(storage_core || !istype(tool, /obj/item/assembly/signaler/anomaly/bluespace))
return NONE

qdel(tool)
upgrade_to_bluespace(user)
to_chat(user, span_notice("You insert [tool] into your shell, and it starts to glow blue with expanded storage potential!"))
return ITEM_INTERACT_SUCCESS

/// Upgrades the storage capacity of the snail shell and gives it a glowy blue outline
/obj/item/storage/backpack/snail/proc/upgrade_to_bluespace(mob/living/wearer)
add_filter("bluespace_shell", 2, list("type" = "outline", "color" = COLOR_BLUE_LIGHT, "size" = 1))
playsound(src, 'sound/machines/click.ogg', 50, TRUE)
storage_core = TRUE
var/old_inventory = atom_storage.return_inv(FALSE)
emptyStorage()
create_storage(max_specific_storage = WEIGHT_CLASS_GIGANTIC, max_total_storage = 35, max_slots = 30, storage_type = /datum/storage/bag_of_holding)
for(var/obj/item/stored_item in old_inventory)
atom_storage.attempt_insert(stored_item, override = TRUE, messages = FALSE, force = TRUE)
name = "snail shell of holding"
update_appearance()

// Update the worn sprite with the blue outline too if applicable
if(isnull(wearer))
wearer = loc
if(istype(wearer))
wearer.update_worn_back()

/datum/species/snail/prepare_human_for_preview(mob/living/carbon/human/snail)
snail.dna.features["mcolor"] = "#adaba7"
snail.update_body(TRUE)

/datum/species/snail/create_pref_unique_perks()
var/list/to_add = list()

to_add += list(
list(
SPECIES_PERK_TYPE = SPECIES_POSITIVE_PERK,
SPECIES_PERK_ICON = "home",
SPECIES_PERK_NAME = "Shellback",
SPECIES_PERK_DESC = "Snails have a shell fused to their back. It offers great storage and most importantly gives them 50% brute damage reduction from behind, or while resting. Alt click to change the sprite!",
),
list(
SPECIES_PERK_TYPE = SPECIES_POSITIVE_PERK,
SPECIES_PERK_ICON = "wine-glass",
SPECIES_PERK_NAME = "Poison Resistance",
SPECIES_PERK_DESC = "Snails have a higher tolerance for poison owing to their robust livers.",
),
list(
SPECIES_PERK_TYPE = SPECIES_POSITIVE_PERK,
SPECIES_PERK_ICON = "heart",
SPECIES_PERK_NAME = "Double Hearts",
SPECIES_PERK_DESC = "Snails have two hearts, meaning it'll take more to break theirs.",
),
list(
SPECIES_PERK_TYPE = SPECIES_POSITIVE_PERK,
SPECIES_PERK_ICON = "bone",
SPECIES_PERK_NAME = "Boneless",
SPECIES_PERK_DESC = "Snails are invertebrates, meaning they don't take bone wounds, but are easier to delimb.",
),
list(
SPECIES_PERK_TYPE = SPECIES_NEGATIVE_PERK,
SPECIES_PERK_ICON = "crutch",
SPECIES_PERK_NAME = "Sheer Mollusk Speed",
SPECIES_PERK_DESC = "Snails move incredibly slow while standing. They move much faster while crawling, and can stick to the floors when the gravity is out.",
),
list(
SPECIES_PERK_TYPE = SPECIES_NEGATIVE_PERK,
SPECIES_PERK_ICON = "frown",
SPECIES_PERK_NAME = "Weak Fighter",
SPECIES_PERK_DESC = "Snails punch half as hard as a human.",
),
list(
SPECIES_PERK_TYPE = SPECIES_NEGATIVE_PERK,
SPECIES_PERK_ICON = "skull",
SPECIES_PERK_NAME = "Salt Weakness",
SPECIES_PERK_DESC = "Salt burns snails, and salt piles will block their path.",
),
)

return to_add

#undef SHELL_TRANSPARENCY_ALPHA
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/obj/item/organ/internal/heart/snail
name = "twin gastropod hearts"
desc = "A primary heart normally nestled inside a gastropod's shell, and another in the owner's actual chest; necessary to maintain ample bloodflow through essentially two torsos."
icon = 'modular_doppler/modular_species/species_types/snails/icons/organs/snail_heart.dmi'
icon_state = "heart-snail-on"
base_icon_state = "heart-snail"
maxHealth = 2 * STANDARD_ORGAN_THRESHOLD // There's two of them. Also, due to the special interaction below, it's best we make sure these aren't easily lost.
now_fixed = span_info("Your hearts begin to beat again.") //For the sake of verisimilitude.

COOLDOWN_DECLARE(shell_effect_cd)

/obj/item/organ/internal/heart/snail/on_mob_insert(mob/living/carbon/organ_owner, special)
. = ..()
if(!ishuman(organ_owner))
return

if(!issnail(organ_owner)) //This is cleaner than checking for the shell, because there's not really going to be any non-horribly-bugged situation in which a snail will be lacking a shell.
return

var/mob/living/carbon/human/human_owner = organ_owner

RegisterSignal(human_owner, COMSIG_MOB_APPLY_DAMAGE_MODIFIERS, PROC_REF(modify_damage))
RegisterSignal(human_owner, COMSIG_MOB_AFTER_APPLY_DAMAGE, PROC_REF(do_block_effect))

/obj/item/organ/internal/heart/snail/on_mob_remove(mob/living/carbon/organ_owner, special)
. = ..()
if(!ishuman(organ_owner) || QDELETED(organ_owner))
return

var/mob/living/carbon/human/human_owner = organ_owner

UnregisterSignal(human_owner, list(COMSIG_MOB_APPLY_DAMAGE_MODIFIERS, COMSIG_MOB_AFTER_APPLY_DAMAGE))

/**
* Signal proc for [COMSIG_MOB_APPLY_DAMAGE_MODIFIERS]
*
* Adds a 0.5 modifier to attacks from the back, code borrowed (wholesale) from the roach heart.
*/
/obj/item/organ/internal/heart/snail/proc/modify_damage(mob/living/carbon/human/source, list/damage_mods, damage_amount, damagetype, def_zone, sharpness, attack_direction, obj/item/attacking_item)
SIGNAL_HANDLER

if(!is_blocking(source, damage_amount, damagetype, attack_direction))
return

damage_mods += 0.5

/**
* Signal proc for [COMSIG_MOB_AFTER_APPLY_DAMAGE]
*
* Does a special effect if we blocked damage with our shell.
*/
/obj/item/organ/internal/heart/snail/proc/do_block_effect(mob/living/carbon/human/source, damage_dealt, damagetype, def_zone, blocked, wound_bonus, bare_wound_bonus, sharpness, attack_direction, obj/item/attacking_item)
SIGNAL_HANDLER

if(!is_blocking(source, damage_dealt, damagetype, attack_direction))
return

if(COOLDOWN_FINISHED(src, shell_effect_cd))
source.visible_message(span_warning("[source]'s shell weathers the blow, absorbing most of the shock!"))
playsound(source, 'sound/weapons/parry.ogg', 50, extrarange = SHORT_RANGE_SOUND_EXTRARANGE)

COOLDOWN_START(src, shell_effect_cd, 3 SECONDS) // Cooldown resets EVERY time we get hit

/// Checks if the passed mob is in a valid state to be blocking damage with the snail shell
/obj/item/organ/internal/heart/snail/proc/is_blocking(mob/living/carbon/human/blocker, damage_amount, damagetype, attack_direction)
if(damage_amount < 5 || damagetype != BRUTE || !attack_direction)
return
if(!ishuman(blocker) || blocker.stat >= UNCONSCIOUS)
return FALSE
// No tactical spinning
if(HAS_TRAIT(blocker, TRAIT_SPINNING))
return FALSE
if(blocker.body_position == LYING_DOWN || (blocker.dir & attack_direction))
return TRUE
return FALSE

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/obj/item/organ/internal/liver/snail
name = "gastropod liver"
icon = 'modular_doppler/modular_species/species_types/snails/icons/organs/snail_liver.dmi'
icon_state = "liver-snail"
desc = "Due to snailfolk evolving in typically poisonous environments such as bogs, their liver has a higher tolerance for poisons compared to most."
maxHealth = 1.5 * STANDARD_ORGAN_THRESHOLD
toxTolerance = 5 //can shrug off up to 5u of toxins
Loading
Loading