Adds snailpeople as a rare genetic meltdown effect (#42889)

Meant to be part of #42864 , but got a little big so I'll add it to wichever gets merged last.
[Snailcrawl demonstration](https://youtu.be/IL7WFpfRo4c)

PROS

- Gets snailcrawl, wich makes them greatly faster and gives them a lube trail

- Their blood is spacelube

- They get a cool armored nodrop snail shell

- They don't slip

CONS

- Very slow

- Punch is pathetic

- Tttaaalllkkk llliiikkkeee ttthhhiiisss

- Extremely vulnerable to salt

- Can't wear glasses

Adds gastrolisis, wich is pretty much [this](https://www.youtube.com/watch?v=lFbPi8o0OEU) spongebob episode where they slowly turn into snails

You can also get gastrolisis by random_reagent_id, so maintpills and botany

🆑
add: Adds snailpeople as a rare genetics accident.
sprite: Snailshell sprites by nickvr628
/🆑
Snailshell sprites by @nickvr628

Why: It's a silly gimmicky race and it's a rare occurence. Also extremely highly requested for some reason
This commit is contained in:
Time-Green
2019-03-01 21:40:56 +01:00
committed by yogstation13-bot
parent 1d1617fdf8
commit c0e0ef18e4
24 changed files with 281 additions and 30 deletions

View File

@@ -53,6 +53,7 @@
#define MOVESPEED_ID_SANITY "MOOD_SANITY"
#define MOVESPEED_ID_SPECIES "SPECIES_SPEED_MOD"
#define MOVESPEED_ID_SNAIL_CRAWL "SNAIL_CRAWL_SPEED_MOD"
#define MOVESPEED_ID_CYBER_THRUSTER "CYBER_IMPLANT_THRUSTER"
#define MOVESPEED_ID_JETPACK "JETPACK"

View File

@@ -0,0 +1,19 @@
/datum/component/snailcrawl
var/mob/living/carbon/snail
/datum/component/snailcrawl/Initialize()
RegisterSignal(parent, list(COMSIG_MOVABLE_MOVED), .proc/lubricate)
snail = parent
/datum/component/snailcrawl/proc/lubricate()
if(snail.resting) //s l i d e
var/turf/open/OT = get_turf(snail)
if(isopenturf(OT))
OT.MakeSlippery(TURF_WET_LUBE, 20)
snail.add_movespeed_modifier(MOVESPEED_ID_SNAIL_CRAWL, update=TRUE, priority=100, multiplicative_slowdown=-7, movetypes=GROUND)
else
snail.remove_movespeed_modifier(MOVESPEED_ID_SNAIL_CRAWL)
/datum/component/snailcrawl/_RemoveFromParent()
snail.remove_movespeed_modifier(MOVESPEED_ID_SNAIL_CRAWL)
return ..()

View File

@@ -0,0 +1,85 @@
/datum/disease/gastrolosis
name = "Invasive Gastrolosis"
max_stages = 4
spread_text = "Degenerative Virus"
spread_flags = DISEASE_SPREAD_SPECIAL
cure_text = "Salt and mutadone"
agent = "Agent S and DNA restructuring"
viable_mobtypes = list(/mob/living/carbon/human)
stage_prob = 1
disease_flags = CURABLE
cures = list("sodiumchloride")
/datum/disease/gastrolosis/stage_act()
..()
if(is_species(affected_mob, /datum/species/snail))
cure()
switch(stage)
if(2)
if(prob(2))
affected_mob.emote("gag")
if(prob(1))
var/turf/open/OT = get_turf(affected_mob)
if(isopenturf(OT))
OT.MakeSlippery(TURF_WET_LUBE, 40)
if(3)
if(prob(5))
affected_mob.emote("gag")
if(prob(5))
var/turf/open/OT = get_turf(affected_mob)
if(isopenturf(OT))
OT.MakeSlippery(TURF_WET_LUBE, 100)
if(4)
var/obj/item/organ/eyes/eyes = locate(/obj/item/organ/eyes/snail) in affected_mob.internal_organs
if(!eyes && prob(5))
var/obj/item/organ/eyes/snail/new_eyes = new()
new_eyes.Insert(affected_mob, drop_if_replaced = TRUE)
affected_mob.visible_message("<span class='warning'>[affected_mob]'s eyes fall out, with snail eyes taking its place!</span>", \
"<span class='userdanger'>You scream in pain as your eyes are pushed out by your new snail eyes!</span>")
affected_mob.emote("scream")
return
var/obj/item/shell = affected_mob.get_item_by_slot(SLOT_BACK)
if(!istype(shell, /obj/item/storage/backpack/snail))
shell = null
if(!shell && prob(5))
if(affected_mob.dropItemToGround(affected_mob.get_item_by_slot(SLOT_BACK)))
affected_mob.equip_to_slot_or_del(new /obj/item/storage/backpack/snail(affected_mob), SLOT_BACK)
affected_mob.visible_message("<span class='warning'>[affected_mob] grows a grotesque shell on their back!</span>", \
"<span class='userdanger'>You scream in pain as a shell pushes itself out from under your skin!</span>")
affected_mob.emote("scream")
return
var/obj/item/organ/tongue/tongue = locate(/obj/item/organ/tongue/snail) in affected_mob.internal_organs
if(!tongue && prob(5))
var/obj/item/organ/tongue/snail/new_tongue = new()
new_tongue.Insert(affected_mob)
to_chat(affected_mob, "<span class='userdanger'>You feel your speech slow down</span>")
return
if(shell && eyes && tongue && prob(5))
affected_mob.set_species(/datum/species/snail)
affected_mob.visible_message("<span class='warning'>[affected_mob] turns into a snail!</span>", \
"<span class='boldnotice'>You turned into a snail person! You feel an urge to cccrrraaawwwlll...</span>")
cure()
if(prob(10))
affected_mob.emote("gag")
if(prob(10))
var/turf/open/OT = get_turf(affected_mob)
if(isopenturf(OT))
OT.MakeSlippery(TURF_WET_LUBE, 100)
/datum/disease/gastrolosis/cure()
. = ..()
if(!is_species(affected_mob, /datum/species/snail)) //undo all the snail fuckening
var/mob/living/carbon/human/H = affected_mob
var/obj/item/organ/tongue/tongue = locate(/obj/item/organ/tongue/snail) in H.internal_organs
if(tongue)
var/obj/item/organ/tongue/new_tongue = new H.dna.species.mutanttongue ()
new_tongue.Insert(H)
var/obj/item/organ/eyes/eyes = locate(/obj/item/organ/eyes/snail) in H.internal_organs
if(eyes)
var/obj/item/organ/eyes/new_eyes = new H.dna.species.mutanteyes ()
new_eyes.Insert(H)
var/obj/item/storage/backpack/bag = H.get_item_by_slot(SLOT_BACK)
if(istype(bag, /obj/item/storage/backpack/snail))
bag.emptyStorage()
H.doUnEquip(bag, TRUE, no_move = TRUE)
qdel(bag)

View File

@@ -566,7 +566,7 @@
dna.remove_all_mutations()
dna.stability = 100
if(prob(max(70-instability,0)))
switch(rand(0,7)) //not complete and utter death
switch(rand(0,10)) //not complete and utter death
if(0)
monkeyize()
if(1)
@@ -600,6 +600,9 @@
O.forceMove(drop_location())
if(prob(20))
O.animate_atom_living()
if(9 to 10)
ForceContractDisease(new/datum/disease/gastrolosis())
to_chat(src, "<span class='notice'>Oh, I actually feel quite alright!</span>")
else
switch(rand(0,5))
if(0)

View File

@@ -30,6 +30,12 @@
desc = "A sizable pile of table salt. Someone must be upset."
icon_state = "salt_pile"
/obj/effect/decal/cleanable/food/salt/CanPass(atom/movable/AM, turf/target)
if(is_species(AM, /datum/species/snail))
to_chat(AM, "<span class='danger'>Your path is obstructed by <span class='phobia'>salt</span>.</span>")
return FALSE
return TRUE
/obj/effect/decal/cleanable/food/flour
name = "flour"
desc = "It's still good. Four second rule!"

View File

@@ -793,3 +793,10 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
if(has_trait(TRAIT_NODROP))
return
return ..()
/obj/item/proc/canStrip(mob/stripper, mob/owner)
return !has_trait(TRAIT_NODROP)
/obj/item/proc/doStrip(mob/stripper, mob/owner)
return owner.dropItemToGround(src)

View File

@@ -1,8 +1,8 @@
/obj/item/storage
name = "storage"
icon = 'icons/obj/storage.dmi'
w_class = WEIGHT_CLASS_NORMAL
var/rummage_if_nodrop = TRUE
var/component_type = /datum/component/storage/concrete
/obj/item/storage/get_dumping_location(obj/item/storage/source,mob/user)
@@ -23,6 +23,23 @@
A.ex_act(severity, target)
CHECK_TICK
/obj/item/storage/canStrip(mob/who)
. = ..()
if(!. && rummage_if_nodrop)
return TRUE
/obj/item/storage/doStrip(mob/who)
if(has_trait(TRAIT_NODROP) && rummage_if_nodrop)
GET_COMPONENT(CP, /datum/component/storage)
CP.do_quick_empty()
return TRUE
return ..()
/obj/item/storage/contents_explosion(severity, target)
//Cyberboss says: "USE THIS TO FILL IT, NOT INITIALIZE OR NEW"
/obj/item/storage/proc/PopulateContents()
/obj/item/storage/proc/emptyStorage()
GET_COMPONENT(ST, /datum/component/storage)
ST.do_quick_empty()

View File

@@ -901,7 +901,6 @@
if(SANITY_NEUTRAL to SANITY_GREAT)
. *= 0.90
/mob/living/carbon/proc/create_internal_organs()
for(var/X in internal_organs)
var/obj/item/organ/I = X

View File

@@ -479,13 +479,13 @@ GLOBAL_LIST_EMPTY(roundstart_races)
// eyes
if(!(NOEYES in species_traits))
var/has_eyes = H.getorganslot(ORGAN_SLOT_EYES)
var/obj/item/organ/eyes/E = H.getorganslot(ORGAN_SLOT_EYES)
var/mutable_appearance/eye_overlay
if(!has_eyes)
if(!E)
eye_overlay = mutable_appearance('icons/mob/human_face.dmi', "eyes_missing", -BODY_LAYER)
else
eye_overlay = mutable_appearance('icons/mob/human_face.dmi', "eyes", -BODY_LAYER)
if((EYECOLOR in species_traits) && has_eyes)
eye_overlay = mutable_appearance('icons/mob/human_face.dmi', E.eye_icon_state, -BODY_LAYER)
if((EYECOLOR in species_traits) && E)
eye_overlay.color = "#" + H.eye_color
if(OFFSET_FACE in H.dna.species.offset_features)
eye_overlay.pixel_x += H.dna.species.offset_features[OFFSET_FACE][1]
@@ -823,6 +823,9 @@ GLOBAL_LIST_EMPTY(roundstart_races)
return FALSE
if(!H.get_bodypart(BODY_ZONE_HEAD))
return FALSE
var/obj/item/organ/eyes/E = H.getorganslot(ORGAN_SLOT_EYES)
if(E?.no_glasses)
return FALSE
return equip_delay_self_check(I, H, bypass_equip_delay_self)
if(SLOT_HEAD)
if(H.head)
@@ -1130,10 +1133,6 @@ GLOBAL_LIST_EMPTY(roundstart_races)
// ATTACK PROCS //
//////////////////
//////////////////
// ATTACK PROCS //
//////////////////
/datum/species/proc/spec_updatehealth(mob/living/carbon/human/H)
return
@@ -1176,10 +1175,6 @@ GLOBAL_LIST_EMPTY(roundstart_races)
target.grabbedby(user)
return 1
/datum/species/proc/harm(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style)
if(user.has_trait(TRAIT_PACIFISM))
to_chat(user, "<span class='warning'>You don't want to harm [target]!</span>")

View File

@@ -0,0 +1,62 @@
/datum/species/snail
name = "Snailperson"
id = "snail"
default_color = "336600" //vomit green
species_traits = list(MUTCOLORS, NO_UNDERWEAR)
inherent_traits = list(TRAIT_ALWAYS_CLEAN)
attack_verb = "slap"
say_mod = "slurs"
coldmod = 0.5 //snails only come out when its cold and wet
burnmod = 2
speedmod = 6
punchdamagehigh = 0.5 //snails are soft and squishy
siemens_coeff = 2 //snails are mostly water
changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_MAGIC | MIRROR_PRIDE | RACE_SWAP
sexes = FALSE //snails are hermaphrodites
var/shell_type = /obj/item/storage/backpack/snail
mutanteyes = /obj/item/organ/eyes/snail
mutanttongue = /obj/item/organ/tongue/snail
exotic_blood = "spacelube"
/datum/species/snail/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H)
if(chem.id == "sodiumchloride")
H.adjustFireLoss(2)
playsound(H, 'sound/weapons/sear.ogg', 30, 1)
H.reagents.remove_reagent(chem.id, REAGENTS_METABOLISM)
return 1
/datum/species/snail/on_species_gain(mob/living/carbon/C, datum/species/old_species, pref_load)
. = ..()
var/obj/item/storage/backpack/bag = C.get_item_by_slot(SLOT_BACK)
if(!istype(bag, /obj/item/storage/backpack/snail))
if(C.dropItemToGround(bag)) //returns TRUE even if its null
C.equip_to_slot_or_del(new /obj/item/storage/backpack/snail(C), SLOT_BACK)
C.AddComponent(/datum/component/snailcrawl)
C.add_trait(TRAIT_NOSLIPALL, SPECIES_TRAIT)
/datum/species/snail/on_species_loss(mob/living/carbon/C)
. = ..()
var/datum/component/CP = C.GetComponent(/datum/component/snailcrawl)
CP.RemoveComponent()
C.remove_trait(TRAIT_NOSLIPALL, SPECIES_TRAIT)
var/obj/item/storage/backpack/bag = C.get_item_by_slot(SLOT_BACK)
if(istype(bag, /obj/item/storage/backpack/snail))
bag.emptyStorage()
C.doUnEquip(bag, TRUE, no_move = TRUE)
qdel(bag)
/obj/item/storage/backpack/snail
name = "snail shell"
desc = "Worn by snails as armor and storage compartment."
icon_state = "snail_green"
item_state = "snail_green"
lefthand_file = 'icons/mob/inhands/equipment/backpack_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/backpack_righthand.dmi'
armor = list("melee" = 40, "bullet" = 30, "laser" = 30, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 50)
max_integrity = 200
resistance_flags = FIRE_PROOF | ACID_PROOF
/obj/item/storage/backpack/snail/Initialize()
. = ..()
add_trait(TRAIT_NODROP)

View File

@@ -657,13 +657,13 @@ generate/load female uniform sprites matching all previously decided variables
// eyes
if(!(NOEYES in dna.species.species_traits))
var/has_eyes = getorganslot(ORGAN_SLOT_EYES)
var/obj/item/organ/eyes/E = getorganslot(ORGAN_SLOT_EYES)
var/mutable_appearance/eye_overlay
if(!has_eyes)
if(!E)
eye_overlay = mutable_appearance('icons/mob/human_face.dmi', "eyes_missing", -BODY_LAYER)
else
eye_overlay = mutable_appearance('icons/mob/human_face.dmi', "eyes", -BODY_LAYER)
if((EYECOLOR in dna.species.species_traits) && has_eyes)
eye_overlay = mutable_appearance('icons/mob/human_face.dmi', E.eye_icon_state, -BODY_LAYER)
if((EYECOLOR in dna.species.species_traits) && E)
eye_overlay.color = "#" + eye_color
if(OFFSET_FACE in dna.species.offset_features)
eye_overlay.pixel_x += dna.species.offset_features[OFFSET_FACE][1]

View File

@@ -504,6 +504,20 @@
var/obj/effect/proc_holder/spell/spell = S
spell.updateButtonIcon()
<<<<<<< HEAD
=======
/mob/living/proc/remove_CC(should_update_mobility = TRUE)
SetStun(0, FALSE)
SetKnockdown(0, FALSE)
SetImmobilized(0, FALSE)
SetParalyzed(0, FALSE)
SetSleeping(0, FALSE)
setStaminaLoss(0)
SetUnconscious(0, FALSE)
if(should_update_mobility)
update_mobility()
>>>>>>> ad1dd38655... Adds snailpeople as a rare genetic meltdown effect (#42889)
//proc used to completely heal a mob.
/mob/living/proc/fully_heal(admin_revive = 0)
restore_blood()
@@ -740,7 +754,7 @@
// The src mob is trying to strip an item from someone
// Override if a certain type of mob should be behave differently when stripping items (can't, for example)
/mob/living/stripPanelUnequip(obj/item/what, mob/who, where)
if(what.has_trait(TRAIT_NODROP))
if(!what.canStrip(who))
to_chat(src, "<span class='warning'>You can't remove \the [what.name], it appears to be stuck!</span>")
return
who.visible_message("<span class='danger'>[src] tries to remove [who]'s [what.name].</span>", \
@@ -751,10 +765,10 @@
if(islist(where))
var/list/L = where
if(what == who.get_item_for_held_index(L[2]))
if(who.dropItemToGround(what))
if(what.doStrip(src, who))
log_combat(src, who, "stripped [what] off")
if(what == who.get_item_by_slot(where))
if(who.dropItemToGround(what))
if(what.doStrip(src, who))
log_combat(src, who, "stripped [what] off")
if(Adjacent(who)) //update inventory window

View File

@@ -1138,6 +1138,18 @@
if(method==PATCH || method==INGEST || method==INJECT || (method == VAPOR && prob(min(reac_volume,100)*(1 - touch_protection))))
L.ForceContractDisease(new /datum/disease/tuberculosis(), FALSE, TRUE)
/datum/reagent/snail
name = "Agent-S"
id = "snailserum"
description = "Virological agent that infects the subject with Gastrolosis."
color = "#003300" // rgb(0, 51, 0)
taste_description = "goo"
can_synth = FALSE //special orange man request
/datum/reagent/snail/reaction_mob(mob/living/L, method=TOUCH, reac_volume, show_message = 1, touch_protection = 0)
if(method==PATCH || method==INGEST || method==INJECT || (method == VAPOR && prob(min(reac_volume,100)*(1 - touch_protection))))
L.ForceContractDisease(new /datum/disease/gastrolosis(), FALSE, TRUE)
/datum/reagent/fluorosurfactant//foam precursor
name = "Fluorosurfactant"
id = "fluorosurfactant"

View File

@@ -198,3 +198,9 @@
name = "atropine autoinjector"
desc = "A rapid way to save a person from a critical injury state!"
list_reagents = list("atropine" = 10)
/obj/item/reagent_containers/hypospray/medipen/snail
name = "snail shot"
desc = "All-purpose snail medicine! Do not use on non-snails!"
list_reagents = list("snailserum" = 10)
icon_state = "snail"

View File

@@ -234,10 +234,10 @@
. += lips_overlay
// eyes
var/image/eyes_overlay = image('icons/mob/human_face.dmi', "eyes", -BODY_LAYER, SOUTH)
var/image/eyes_overlay = image('icons/mob/human_face.dmi', "eyes_missing", -BODY_LAYER, SOUTH)
. += eyes_overlay
if(!eyes)
eyes_overlay.icon_state = "eyes_missing"
if(eyes)
eyes_overlay.icon_state = eyes.eye_icon_state
else if(eyes.eye_color)
eyes_overlay.color = "#" + eyes.eye_color

View File

@@ -11,13 +11,15 @@
var/eye_damage = 0
var/tint = 0
var/eye_color = "" //set to a hex code to override a mob's eye color
var/eye_icon_state = "eyes"
var/old_eye_color = "fff"
var/flash_protect = 0
var/see_invisible = SEE_INVISIBLE_LIVING
var/lighting_alpha
var/no_glasses
/obj/item/organ/eyes/Insert(mob/living/carbon/M, special = FALSE, drop_if_replaced = FALSE)
..()
/obj/item/organ/eyes/Insert(mob/living/carbon/M, special = FALSE, drop_if_replaced = FALSE, initialising)
. = ..()
if(ishuman(owner))
var/mob/living/carbon/human/HMN = owner
old_eye_color = HMN.eye_color
@@ -30,6 +32,8 @@
lighting_alpha = LIGHTING_PLANE_ALPHA_NV_TRAIT
M.update_tint()
owner.update_sight()
if(M.has_dna())
M.dna.species.handle_body(M) //updates eye icon
/obj/item/organ/eyes/Remove(mob/living/carbon/M, special = 0)
..()
@@ -338,3 +342,9 @@
name = "moth eyes"
desc = "These eyes seem to have increased sensitivity to bright light, with no improvement to low light vision."
flash_protect = -1
/obj/item/organ/eyes/snail
name = "snail eyes"
desc = "These eyes seem to have a large range, but might be cumbersome with glasses."
eye_icon_state = "snail_eyes"
icon_state = "snail_eyeballs"

View File

@@ -222,3 +222,15 @@
/obj/item/organ/tongue/robot/get_spans()
return ..() | SPAN_ROBOT
/obj/item/organ/tongue/snail
name = "snailtongue"
/obj/item/organ/tongue/snail/TongueSpeech(message)
var/new_message
for(var/i in 1 to length(message))
if(findtext("ABCDEFGHIJKLMNOPWRSTUVWXYZabcdefghijklmnopqrstuvwxyz", message[i])) //Im open to suggestions
new_message += message[i] + message[i] + message[i] //aaalllsssooo ooopppeeennn tttooo sssuuuggggggeeessstttiiiooonsss
else
new_message += message[i]
return new_message

Binary file not shown.

Before

Width:  |  Height:  |  Size: 98 KiB

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

@@ -368,6 +368,7 @@
#include "code\datums\components\rotation.dm"
#include "code\datums\components\signal_redirect.dm"
#include "code\datums\components\slippery.dm"
#include "code\datums\components\snail_crawl.dm"
#include "code\datums\components\spawner.dm"
#include "code\datums\components\spill.dm"
#include "code\datums\components\spooky.dm"
@@ -401,6 +402,7 @@
#include "code\datums\diseases\fake_gbs.dm"
#include "code\datums\diseases\flu.dm"
#include "code\datums\diseases\fluspanish.dm"
#include "code\datums\diseases\gastrolisis.dm"
#include "code\datums\diseases\gbs.dm"
#include "code\datums\diseases\heart_failure.dm"
#include "code\datums\diseases\magnitis.dm"
@@ -2007,6 +2009,7 @@
#include "code\modules\mob\living\carbon\human\species_types\podpeople.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"
#include "code\modules\mob\living\carbon\human\species_types\synths.dm"
#include "code\modules\mob\living\carbon\human\species_types\vampire.dm"
#include "code\modules\mob\living\carbon\human\species_types\zombies.dm"