Skip to content

Commit

Permalink
Merge pull request #79 from Nerev4r/snailsfordinneragain
Browse files Browse the repository at this point in the history
Snails, Except Twice
  • Loading branch information
carpotoxin authored Sep 23, 2024
2 parents 2e45e5b + f1b2eba commit ba8b8ea
Show file tree
Hide file tree
Showing 19 changed files with 340 additions and 6 deletions.
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
2 changes: 2 additions & 0 deletions modular_doppler/modular_customization/organs/internal/eyes.dm
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.
190 changes: 190 additions & 0 deletions modular_doppler/modular_species/species_types/snails/modular_snail.dm
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

0 comments on commit ba8b8ea

Please sign in to comment.